当前位置: 首页 > 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;提供一个全局的访问点工厂方法模式-创建…...

(LeetCode 每日一题) 3442. 奇偶频次间的最大差值 I (哈希、字符串)

题目&#xff1a;3442. 奇偶频次间的最大差值 I 思路 &#xff1a;哈希&#xff0c;时间复杂度0(n)。 用哈希表来记录每个字符串中字符的分布情况&#xff0c;哈希表这里用数组即可实现。 C版本&#xff1a; class Solution { public:int maxDifference(string s) {int a[26]…...

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

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

C++:std::is_convertible

C++标志库中提供is_convertible,可以测试一种类型是否可以转换为另一只类型: template <class From, class To> struct is_convertible; 使用举例: #include <iostream> #include <string>using namespace std;struct A { }; struct B : A { };int main…...

JavaScript 中的 ES|QL:利用 Apache Arrow 工具

作者&#xff1a;来自 Elastic Jeffrey Rengifo 学习如何将 ES|QL 与 JavaScript 的 Apache Arrow 客户端工具一起使用。 想获得 Elastic 认证吗&#xff1f;了解下一期 Elasticsearch Engineer 培训的时间吧&#xff01; Elasticsearch 拥有众多新功能&#xff0c;助你为自己…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

【位运算】消失的两个数字(hard)

消失的两个数字&#xff08;hard&#xff09; 题⽬描述&#xff1a;解法&#xff08;位运算&#xff09;&#xff1a;Java 算法代码&#xff1a;更简便代码 题⽬链接&#xff1a;⾯试题 17.19. 消失的两个数字 题⽬描述&#xff1a; 给定⼀个数组&#xff0c;包含从 1 到 N 所有…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

CSS设置元素的宽度根据其内容自动调整

width: fit-content 是 CSS 中的一个属性值&#xff0c;用于设置元素的宽度根据其内容自动调整&#xff0c;确保宽度刚好容纳内容而不会超出。 效果对比 默认情况&#xff08;width: auto&#xff09;&#xff1a; 块级元素&#xff08;如 <div>&#xff09;会占满父容器…...

纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join

纯 Java 项目&#xff08;非 SpringBoot&#xff09;集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...