当前位置: 首页 > news >正文

【数据集标注制作】视频剪切标注1——类DarkLabel软件

视频标注

用于从视频中标注数据,用于YOLO网络的目标检测。旨在实现单次鼠标标注能生成多张被标注图像,实现数据集快速制作!

  1. 从视频中,通过鼠标框选指定区域,形成掩码box
  2. 鼠标选定区域后,根据设定的成像尺寸,在选定区域周围随机实施多个角度的剪切,制作数据集。(重在减少鼠标标注操作,丰富数据集图片数量)
  3. 剪切出的图片,每张都带掩码box、原图和效果图。
  4. 标注过程视频可暂停,生成图像文件自动命名。(鼠标单击过后,或者键盘按键,都可控制视频暂停和继续)
  5. 不足之处:不可控制视频帧移动

程序文件:https://download.csdn.net/download/tjb132/88514408?spm=1001.2014.3001.5503


import threading
import queueclass Mask_video:def __init__(self, urls, label, images_save_path):self.urls = urlsself.video_idx = 0self.lock = threading.Lock()self.drawing = Falseself.start_point = (-1, -1)self.end_point = (-1, -1)self.cropped_image = Noneself.paused = False  # 是否暂停视频播放self.expanded_cropped_image = Noneself.expanded_cropped_image_mask_pts = [0,0,0,0]self.images_save_root = images_save_pathself.images_data_save_path = os.path.join(self.images_save_root, 'images')self.images_label_save_path = os.path.join(self.images_save_root, 'labels')self.images_label_mask_path = os.path.join(self.images_save_root, 'mask')os.makedirs(self.images_data_save_path, exist_ok=True)os.makedirs(self.images_label_save_path, exist_ok=True)os.makedirs(self.images_label_mask_path, exist_ok=True)self.images_idx = 0self.label = label# 创建一个窗口并设置鼠标事件回调函数cv.namedWindow('Video')cv.setMouseCallback('Video', self.draw_rectangle)passdef draw_rectangle(self, event, x, y, flags, param):if event == cv.EVENT_LBUTTONDOWN:with self.lock:self.drawing = Trueself.start_point = (x, y)self.pause_video()elif event == cv.EVENT_MOUSEMOVE:if self.drawing:with self.lock:self.end_point = (x, y)if event == cv.EVENT_LBUTTONUP:with self.lock:self.drawing = Falseself.end_point = (x, y)# print('=== 1 ===',  self.start_point, self.end_point)# 归一化坐标,确保 start_point 包含左上角坐标,end_point 包含右下角坐标start_point = (min(self.start_point[0], self.end_point[0]), min(self.start_point[1], self.end_point[1]))end_point = (max(self.start_point[0], self.end_point[0]), max(self.start_point[1], self.end_point[1]))self.start_point, self.end_point = start_point, end_point# print('=== 2 ===', self.start_point, self.end_point)if (self.start_point[0]-self.end_point[0])==0 or (self.start_point[1]-self.end_point[1])==0:self.cropped_image = Nonereturnelse:# 裁剪图像并显示self.cropped_image = self.frame[self.start_point[1]:self.end_point[1],self.start_point[0]:self.end_point[0]]# cv.imshow('Cropped Image', self.cropped_image)for i in range(4): self.crop_and_random_expand()self.cropped_image = Noneself.resume_video()def pause_video(self):with self.lock:self.paused = Truedef resume_video(self):with self.lock:self.paused = Falsedef crop_and_random_expand(self):""" 在指定区域的附近,实施随机剪裁,生成图像 """# with self.lock:if self.cropped_image is not None:# 定义扩展的像素范围expand_range1 = np.random.randint(0, self.start_point[0])  # 您可以根据需要调整这个值expanded_x1 = max(self.start_point[0] - expand_range1, 0)expand_range2 = np.random.randint(0, self.frame.shape[1]-self.end_point[0])  # 您可以根据需要调整这个值expanded_x2 = min(self.end_point[0] + expand_range2, self.frame.shape[1])expand_range3 = np.random.randint(0, self.start_point[1])  # 您可以根据需要调整这个值expanded_y1 = max(self.start_point[1] - expand_range3, 0)expand_range4 = np.random.randint(0, self.frame.shape[0] - self.end_point[1])  # 您可以根据需要调整这个值expanded_y2 = min(self.end_point[1] + expand_range4, self.frame.shape[0])expanded_cropped_image = self.frame[expanded_y1:expanded_y2, expanded_x1:expanded_x2]yh1, xw1 = expanded_cropped_image.shape[:2]expanded_cropped_image = cv.resize(expanded_cropped_image, (640, 640))yh2, xw2 = expanded_cropped_image.shape[:2]self.expanded_cropped_image = expanded_cropped_image.copy()new_pts = [expand_range1, expand_range3, self.end_point[0]-self.start_point[0], self.end_point[1]-self.start_point[1]]new_pts = [new_pts[0]*xw2/xw1, new_pts[1]*yh2/yh1, new_pts[2]*xw2/xw1, new_pts[3]*yh2/yh1]new_pts = np.array(new_pts, dtype=np.int32)self.expanded_cropped_image_mask_pts = new_ptscv.rectangle(expanded_cropped_image, (new_pts[0],new_pts[1]), (new_pts[0]+new_pts[2], new_pts[1]+new_pts[3]), (0, 255, 0), 2)cv.imshow('expanded_cropped_image', expanded_cropped_image)self.save_image(self.expanded_cropped_image, expanded_cropped_image)return expanded_cropped_imageelse:return Nonedef run_video_crop(self):while True:if not self.paused:ret, self.frame = self.cap.read()if not ret:print("无法读取视频帧")breakimg = self.frame.copy()if self.start_point != (-1, -1) and self.end_point != (-1, -1):# 在帧上绘制方框with self.lock:cv.rectangle(img, self.start_point, self.end_point, (0, 255, 0), 2)cv.imshow('Video', img)key = cv.waitKey(20)if key & 0xFF == ord('q'):  # 退出剪裁软件breakelif key & 0xFF == ord('s'):   # 暂停视频self.pause_video()elif key & 0xFF == ord('d'):  # 继续播放视频self.resume_video()# cv.waitKey(20)self.cap.release()# cv.destroyAllWindows()def run(self):for i in range(len(self.urls)):url = self.urls[i]self.video_idx = itry:cap = cv.VideoCapture(url)ret, frame = cap.read()if ret:self.cap = cap# breakself.lock = threading.Lock()self.drawing = Falseself.start_point = (-1, -1)self.end_point = (-1, -1)self.cropped_image = Noneself.paused = False  # 是否暂停视频播放self.run_video_crop()except: passcv.destroyAllWindows()def save_image(self, imgdata, maskdata):self.images_idx += 1imgfile = os.path.join(self.images_data_save_path, f"{str(self.video_idx)}_{self.images_idx}.jpg")labelfile = os.path.join(self.images_label_save_path, f"{str(self.video_idx)}_{self.images_idx}.txt")maskfile = os.path.join(self.images_label_mask_path, f"{str(self.video_idx)}_{self.images_idx}.jpg")print('\timages data jpg save in:', imgfile)cv.imwrite(imgfile, imgdata)print('\timages label txt save in:', labelfile)hy, wx = imgdata.shape[:2]x,y,w,h = self.expanded_cropped_image_mask_ptswith open(labelfile, 'w') as f:data = f"{str(self.label)}\t{x / wx}\t{y / hy}\t{w / wx}\t{h / hy}" + "\n"f.write(data)print('\timages mask save in:', maskfile)cv.imwrite(maskfile, maskdata)def run():print('==========   start system  ==============')import pandas as pd# 读取Excel文件excel_file = r'I:\python\02-job\h03090 data-output\video.xlsx'  # 将文件名替换为实际的Excel文件名df = pd.read_excel(io=excel_file)# 提取某一行的数据,例如第3行(索引为2)row_index = 3selected_row = df.iloc[row_index]# 打印提取的行数据print("提取的行数据:")print(selected_row)videos = str(selected_row['topVideo']).split(',')print(videos)data = {'id': selected_row['goods_id'], 'videos': videos}images_save_path = r'I:\python\02-job\h03090 data-output\new_images-labeled'mask = Mask_video(urls=videos, label=row_index, images_save_path=images_save_path)mask.run()pass

相关文章:

【数据集标注制作】视频剪切标注1——类DarkLabel软件

视频标注 用于从视频中标注数据,用于YOLO网络的目标检测。旨在实现单次鼠标标注能生成多张被标注图像,实现数据集快速制作! 从视频中,通过鼠标框选指定区域,形成掩码box鼠标选定区域后,根据设定的成像尺寸…...

一体化HIS医疗信息管理系统源码:云HIS、云电子病历、云LIS

基于云计算技术的B/S架构的HIS系统,为医疗机构提供标准化的、信息化的、可共享的医疗信息管理系统,实现医患事务管理和临床诊疗管理等标准医疗管理信息系统的功能。系统利用云计算平台的技术优势,建立统一的云HIS、云病历、云LIS,…...

NSSCTF逆向题解

[SWPUCTF 2021 新生赛]简简单单的逻辑 直接把key打印出来,然后整理一下result,让key和result进行异或 key[242,168,247,147,87,203,51,248,17,69,162,120,196,150,193,154,145,8] data[0xbc,0xfb,0xa4,0xd0,0x03,0x8d,0x48,0xbd,0x4b,0x00,0xf8,0x27,0x…...

广域网加速的作用:企业为什么需要广域网加速?

由于局域网与广域网之间巨大的带宽鸿沟,通过增加带宽来满足膨胀的流量需求是不切实际的。 并且广域网带宽成本较高,增加广域网带宽对任何企业都意味着巨大的成本负担。这些使得控制 管理广域网带宽使用成为必需。 企业为什么要加速广域网? 对重要的企…...

SQL SERVER Inregration Services-OLE DB、Oracle和ODBC操作

OLE DB链接器 OLE DB插件下载:https://learn.microsoft.com/zh-cn/sql/connect/oledb/download-oledb-driver-for-sql-server?viewsql-server-ver16 配置OLE DB Connection Manager 在点击“新建”时,会弹出警告信息“不支持指定的提供程序&#xff0…...

尚硅谷大数据项目《在线教育之实时数仓》笔记006

视频地址:尚硅谷大数据项目《在线教育之实时数仓》_哔哩哔哩_bilibili 目录 第9章 数仓开发之DWD层 P041 P042 P043 P044 P045 P046 P047 P048 P049 P050 P051 P052 第9章 数仓开发之DWD层 P041 9.3 流量域用户跳出事务事实表 P042 DwdTrafficUserJum…...

Linux-源码安装go

使用go 1.14 版本 #wget https://golang.org/dl/go1.14.15.linux-amd64.tar.gz #tar zxvf go1.14.15.linux-amd64.tar.gz #mv go /usr/local/ #vim /etc/profile export GOROOT/usr/local/go export GOBIN$GOROOT/bin export GOPKG$GOROOT/pkg/tool/linux_amd64 export GO…...

如何检测小红书账号是否被限流?哪些原因会导致账号被限流?

hi,同学们,本期是第5期AI运营技巧篇,文章底部准备了粉丝福利,看完后可领取! 最近好多新手学员运营小红书账号,可能会遇到这样的问题:发布的内容小眼睛少得可怜?搜索不到自己的笔记&…...

[动态规划] (十三) 简单多状态 LeetCode 740.删除并获得点数

[动态规划] (十三) 简单多状态: LeetCode 740.删除并获得点数 文章目录 [动态规划] (十三) 简单多状态: LeetCode 740.删除并获得点数题目解析解题思路状态表示状态转移方程初始化和填表顺序返回值 代码实现总结 740. 删除并获得点数 题目解析 (1) 给定一个整数数组。 (2) 选…...

【K-means聚类算法】实现鸢尾花聚类

文章目录 前言一、数据集介绍二、使用步骤1.导包1.2加载数据集1.3绘制二维数据分布图1.4实例化K-means类,并且定义训练函数1.5训练1.6可视化展示2.聚类算法2.1.可视化生成3其他聚类算法进行鸢尾花分类 前言 例如:随着人工智能的不断发展,机器…...

什么是代理IP池?如何判断IP池优劣?

代理池充当多个代理服务器的存储库,提供在线安全和匿名层。代理池允许用户抓取数据、访问受限制的内容以及执行其他在线任务,而无需担心被检测或阻止的风险。代理池为各种在线活动(例如网页抓取、安全浏览等)提高后勤保障。 读完…...

【面经】讲一下线程池的参数和运行原理

线程池是Java中一种重要的并发工具,它可以帮助我们更好地管理线程,避免线程过多导致的系统开销和性能问题。线程池通过预先创建一定数量的线程,并将任务提交给这些线程执行,从而避免了频繁创建和销毁线程的开销。 线程池的参数主…...

针对图像分类的数据增强方法,离线增强,适合分类,无标签增强

针对图像分类的数据增强方法,离线增强,适合分类,无标签增强 代码: 改变路径即可使用 # 本代码主要提供一些针对图像分类的数据增强方法# 1、平移。在图像平面上对图像以一定方式进行平移。 # 2、翻转图像。沿着水平或者垂直方向…...

润色论文Prompt

你好,我现在开始写论文了,我希望你可以扮演帮我润色论文的角色我写的论文是关于xxxxx领域的xxxxx,我希望你能帮我检查段落中语句的逻辑、语法和拼写等问题我希望你能帮我检查以下段落中语句的逻辑、语法和拼写等问题同时提供润色版本以符合学…...

配置简单VLAN

1、 需求 : 1)创建VLAN 10、20、30 2)将端口加入VLAN 3)查看VLAN信息 2、方案 使用eNSP搭建实验环境,如图所示。 3、步骤 实现此案例需要按照如下步骤进行。 1)交换机创建VLAN 10、20、30 [sw1]vla…...

手机是否能登陆国际腾讯云服务器?

在当今社会,跟着互联网的开展,越来越多的用户开始运用云服务器来存储和处理数据。其间,腾讯云服务器作为国内知名的云服务器供给商,受到了广大用户的欢迎。可是,有一些用户可能还不清楚手机是否能登陆腾讯云服务器。本…...

5分钟Python安装实战(MAC版本)

最近在学习Chatgpt接口,官方提供三种方式调用Chatgpt接口,分别是curl、python、node.js:具体介绍我放在下方图片 因为熟悉Python,所以我选择了python这种方式,顺便记录下安装过程,整体并不复杂,…...

python自动化测试(十一):写入、读取、修改Excel表格的数据

目录 一、写入 1.1 安装 xlwt 1.2 增加sheet页 1.2.1 新建sheet页 1.2.2 sheet页写入数据 1.2.3 excel保存 1.2.4 完整代码 1.2.5 同一坐标,重复写入 二、读取 2.1 安装读取模块 2.2 读取sheet页 2.2.1 序号读取shee页 2.2.2 通过sheet页的名称读取she…...

【milkv】添加LCD屏GC9306

前言 本章介绍如何添加LCD屏GC9306驱动。 电路图 dts build\boards\cv180x\cv1800b_milkv_duo_sd\dts_riscv\cv1800b_milkv_duo_sd.dts &spi2 {status "okay";/delete-node/ spidev0;gc9306: gc93060{compatible "sitronix,gc9306";reg <0&g…...

设计模式--开篇

什么是设计模式 设计模式是软件开发过程中面临的通用问题的解决方案。 使用设计模式是为了可重用代码、让代码更容易被他人理解、保证代码可靠性 按使用目的分类 创建型–主要用于创建对象 单例模式-某个类只能有一个实例&#xff0c;提供一个全局的访问点工厂方法模式-创建…...

零门槛NAS搭建:WinNAS如何让普通电脑秒变私有云?

一、核心优势&#xff1a;专为Windows用户设计的极简NAS WinNAS由深圳耘想存储科技开发&#xff0c;是一款收费低廉但功能全面的Windows NAS工具&#xff0c;主打“无学习成本部署” 。与其他NAS软件相比&#xff0c;其优势在于&#xff1a; 无需硬件改造&#xff1a;将任意W…...

阿里云ACP云计算备考笔记 (5)——弹性伸缩

目录 第一章 概述 第二章 弹性伸缩简介 1、弹性伸缩 2、垂直伸缩 3、优势 4、应用场景 ① 无规律的业务量波动 ② 有规律的业务量波动 ③ 无明显业务量波动 ④ 混合型业务 ⑤ 消息通知 ⑥ 生命周期挂钩 ⑦ 自定义方式 ⑧ 滚的升级 5、使用限制 第三章 主要定义 …...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

【Go】3、Go语言进阶与依赖管理

前言 本系列文章参考自稀土掘金上的 【字节内部课】公开课&#xff0c;做自我学习总结整理。 Go语言并发编程 Go语言原生支持并发编程&#xff0c;它的核心机制是 Goroutine 协程、Channel 通道&#xff0c;并基于CSP&#xff08;Communicating Sequential Processes&#xff0…...

学习STC51单片机31(芯片为STC89C52RCRC)OLED显示屏1

每日一言 生活的美好&#xff0c;总是藏在那些你咬牙坚持的日子里。 硬件&#xff1a;OLED 以后要用到OLED的时候找到这个文件 OLED的设备地址 SSD1306"SSD" 是品牌缩写&#xff0c;"1306" 是产品编号。 驱动 OLED 屏幕的 IIC 总线数据传输格式 示意图 …...

python如何将word的doc另存为docx

将 DOCX 文件另存为 DOCX 格式&#xff08;Python 实现&#xff09; 在 Python 中&#xff0c;你可以使用 python-docx 库来操作 Word 文档。不过需要注意的是&#xff0c;.doc 是旧的 Word 格式&#xff0c;而 .docx 是新的基于 XML 的格式。python-docx 只能处理 .docx 格式…...

CMake控制VS2022项目文件分组

我们可以通过 CMake 控制源文件的组织结构,使它们在 VS 解决方案资源管理器中以“组”(Filter)的形式进行分类展示。 🎯 目标 通过 CMake 脚本将 .cpp、.h 等源文件分组显示在 Visual Studio 2022 的解决方案资源管理器中。 ✅ 支持的方法汇总(共4种) 方法描述是否推荐…...

是否存在路径(FIFOBB算法)

题目描述 一个具有 n 个顶点e条边的无向图&#xff0c;该图顶点的编号依次为0到n-1且不存在顶点与自身相连的边。请使用FIFOBB算法编写程序&#xff0c;确定是否存在从顶点 source到顶点 destination的路径。 输入 第一行两个整数&#xff0c;分别表示n 和 e 的值&#xff08;1…...

MySQL JOIN 表过多的优化思路

当 MySQL 查询涉及大量表 JOIN 时&#xff0c;性能会显著下降。以下是优化思路和简易实现方法&#xff1a; 一、核心优化思路 减少 JOIN 数量 数据冗余&#xff1a;添加必要的冗余字段&#xff08;如订单表直接存储用户名&#xff09;合并表&#xff1a;将频繁关联的小表合并成…...

NPOI Excel用OLE对象的形式插入文件附件以及插入图片

static void Main(string[] args) {XlsWithObjData();Console.WriteLine("输出完成"); }static void XlsWithObjData() {// 创建工作簿和单元格,只有HSSFWorkbook,XSSFWorkbook不可以HSSFWorkbook workbook new HSSFWorkbook();HSSFSheet sheet (HSSFSheet)workboo…...