视频演示

如何用labelimg标注yolo数据集,并利用工具自动划分数据集_哔哩哔哩_bilibili

1 labelimg标注数据集

1.1 labelimg工具介绍

LabelImg是一款开源的图像标注工具,专门用于为目标检测任务创建数据集。它支持矩形框标注,可导出PASCAL VOC、YOLO、CreateML等多种格式。

通过简单的点击和拖拽操作,用户即可快速为图像中的对象添加标注框和类别标签。

该工具界面简洁直观,支持快捷键操作,大幅提升标注效率,是计算机视觉领域数据准备的常用工具之一。

1.2 labelimg标注数据集

点击界面左侧的“Open Dir”按钮,选择数据集所存放的文件夹,选择后文件夹中存放的图片信息会展示到界面上

左下角的File List会显示读取进来的数据集列表

点击左侧的Create \nRectBox 按钮,长按鼠标左键可以对图像中的目标物体绘制矩形框

绘制完成之后,弹出来的命名对话框中,写上当前绘制的类别的名字,这里绘制的这个手势是剪刀,我们命名为“Scissors”

依次对剩下的图像数据集进行绘制标注。

查看存放图片的文件夹,会发现每一个图片的旁边,都生成了一个同名的txt文档,这个文档就是我们标注数据后产生的标注文件。

这里可以打开标注文件,查看下标注文件中的内容:

0 0.560937 0.768750 0.625000 0.425000

标注文件中的内容按照行排列,每一行有5个数字,第1个数字是一个整数,后面4个数字是0到1之间的小数,这里以上图举例,说明下数字的含义:

第1个数字“0”:表示当前目标物体的类别编号,0表示第0号目标物体,同理如果是2的话,表明第2号目标物体,具体的编号根据标注时编写目标物体的名称的先后顺序而来。

第2、3个数字“0.560937 0.768750”:表示的是标注物体的坐标信息,分别是x轴和y轴的坐标,坐标为目标检测物体的中心区域,坐标原点是图像的左上角,这里不一样的地方是,坐标轴长不是按照图像的实际尺寸来标注的,而是做了归一化处理,即左下角的y轴坐标是1,右上角的x轴坐标是1,所以x轴和y轴的坐标的阈值是0到1之间。

第4、5数字"0.625000 0.425000":表示的是标注物体的尺寸,分别表示宽度和高度,数值同样是归一化处理,例如0.625表示尺寸为宽度的62.5%

最后还有一个classes.txt文件,打开后是标注的名字信息

scissors
rock
paper

2 划分数据集

当标注完数据之后,yolo模型训练的时候,数据集需要区分训练集和验证集,最后为了检测模型的有效性,我们还需要测试集

所以这里又写了一个python脚本可以将我们标注好的数据集一次性随机性的按照设定的划分比例进行自动化数据集划分

# YOLO 数据集划分工具
# 功能:将包含图片和对应标注文件的数据集按比例随机划分为训练集、验证集和测试集
# 同时生成YOLO训练所需的dataset.yaml配置文件 import os
import shutil
import random
import yaml # ============ 配置参数 ============
SOURCE_DIR = "data" # 源数据目录,图片及其标注 .txt 文件应在此目录
OUTPUT_DIR = "data_split_output2" # 输出根目录,将生成 train/val/test 及其 images/labels TRAIN_RATIO = 0.7 # 训练集比例
VAL_RATIO = 0.2 # 验证集比例
TEST_RATIO = 0.1 # 测试集比例
SEED = 42 # 随机种子,确保每次划分结果一致
REQUIRE_LABEL = True # 仅包含存在对应 .txt 标注的图片 IMG_EXTS = {'.jpg', '.jpeg', '.png', '.bmp', '.gif', '.tiff'} # 支持的图片格式
# ========================================== def ensure_dir(path: str):
"""确保目录存在,不存在则创建"""
os.makedirs(path, exist_ok=True) def main():
# 检查源目录是否存在
if not os.path.isdir(SOURCE_DIR):
print(f"源目录不存在: {SOURCE_DIR}")
return # 收集图片及对应标注信息
candidates = []
for fname in os.listdir(SOURCE_DIR):
fpath = os.path.join(SOURCE_DIR, fname)
# 跳过非文件项
if not os.path.isfile(fpath):
continue # 检查文件是否为图片格式
ext = os.path.splitext(fname)[1].lower()
if ext in IMG_EXTS:
base = os.path.splitext(fname)[0] # 获取文件名(不含扩展名)
label_name = base + ".txt" # 对应的标注文件名
label_path = os.path.join(SOURCE_DIR, label_name) # 如果需要标注文件且不存在,则跳过此图片
if REQUIRE_LABEL and not os.path.exists(label_path):
continue # 记录图片文件名和对应的标注文件名(如果有)
has_label = os.path.exists(label_path)
candidates.append((fname, label_name if has_label else None)) n = len(candidates)
if n == 0:
print("未找到符合条件的图片及标注对。")
return # 检查比例设置是否有效
ratio_sum = TRAIN_RATIO + VAL_RATIO + TEST_RATIO
if ratio_sum <= 0:
print("train/val/test 比例之和必须大于0")
return # 设置随机种子并打乱数据顺序
random.seed(SEED)
random.shuffle(candidates) # 计算各数据集的数量
n_train = int(n * (TRAIN_RATIO / ratio_sum))
n_val = int(n * (VAL_RATIO / ratio_sum))
n_test = n - n_train - n_val # 定义输出目录路径
train_img_out = os.path.join(OUTPUT_DIR, "train", "images")
train_lab_out = os.path.join(OUTPUT_DIR, "train", "labels")
val_img_out = os.path.join(OUTPUT_DIR, "val", "images")
val_lab_out = os.path.join(OUTPUT_DIR, "val", "labels")
test_img_out = os.path.join(OUTPUT_DIR, "test", "images")
test_lab_out = os.path.join(OUTPUT_DIR, "test", "labels") # 创建所有输出目录
for d in [train_img_out, train_lab_out, val_img_out, val_lab_out, test_img_out, test_lab_out]:
ensure_dir(d) def copy_pair(item, dst_img_dir, dst_lab_dir):
"""复制图片和对应的标注文件到目标目录"""
img_name, label_name = item
src_img = os.path.join(SOURCE_DIR, img_name)
dst_img = os.path.join(dst_img_dir, img_name)
shutil.copy2(src_img, dst_img) # 复制图片文件 # 如果存在标注文件,则一并复制
if label_name:
src_lab = os.path.join(SOURCE_DIR, label_name)
if os.path.exists(src_lab):
dst_lab = os.path.join(dst_lab_dir, label_name)
shutil.copy2(src_lab, dst_lab) # 复制标注文件 # 按划分结果复制文件到对应目录
idx = 0
for _ in range(n_train):
copy_pair(candidates[idx], train_img_out, train_lab_out)
idx += 1
for _ in range(n_val):
copy_pair(candidates[idx], val_img_out, val_lab_out)
idx += 1
for _ in range(n_test):
copy_pair(candidates[idx], test_img_out, test_lab_out)
idx += 1 # 读取类别信息
classes_file = os.path.join(SOURCE_DIR, 'classes.txt')
class_names = []
if os.path.exists(classes_file):
with open(classes_file, 'r', encoding='utf-8') as f:
class_names = [line.strip() for line in f.readlines() if line.strip()]
else:
print(f"警告: 未找到 classes.txt 文件,使用默认类别")
class_names = ['class0', 'class1', 'class2'] # 默认类别名 # 生成 YAML 配置文件 (手动控制顺序)
yaml_path = os.path.join(OUTPUT_DIR, 'dataset.yaml')
with open(yaml_path, 'w', encoding='utf-8') as f:
# 写入数据集路径
f.write(f"train: ./train/images\n")
f.write(f"val: ./val/images\n")
f.write(f"test: ./test/images\n")
f.write(f"\n")
# 写入类别数量
f.write(f"nc: {len(class_names)}\n")
# 写入类别名称列表
f.write(f"names:\n")
for name in class_names:
f.write(f"- {name}\n") # 输出划分结果摘要
print("划分完成:")
print(f" 训练集: train/images={train_img_out}, train/labels={train_lab_out}, 张数={n_train}")
print(f" 验证集: val/images={val_img_out}, val/labels={val_lab_out}, 张数={n_val}")
print(f" 测试集: test/images={test_img_out}, test/labels={test_lab_out}, 张数={n_test}")
print(f" 配置文件: {yaml_path}") if __name__ == "__main__":
main() 代码中设置好对应的初始化参数: SOURCE_DIR = "data" # 源数据目录,图片及其标注 .txt 文件应在此目录
OUTPUT_DIR = "data_split_output2" # 输出根目录,将生成 train/val/test 及其 images/labels TRAIN_RATIO = 0.7 # 训练集比例
VAL_RATIO = 0.2 # 验证集比例
TEST_RATIO = 0.1 # 测试集比例

代码中都有相应的注释,这里不再赘述,主要是设置好数据集所在目录,输出的数据集的目录,各个数据集的比例

代码的核心思想就是读取文件夹下的所有图片,然后把图片存放到candidates的list中,然后使用random.shuffle方法打乱candidates中的数据。最后依次按照划分的比例读取数据集。

最终划分好的数据集如下(为了结构展现清楚,这里用macos下的目录展现形式)

同时还生成了yolo框架训练时需要用到的yaml数据集说明文件,这里名字命名为dataset.yaml,打开后内容如下

train: ./train/images
val: ./val/images
test: ./test/images nc: 3
names:
- scissors
- rock
- paper

上面有数据集所在的目录,nc数,还有对应类别的名字

3 封装好GUI的划分数据集工具

利用pyqt5制作了一个界面,将python脚本集成进去,并打包成exe,方便标注数据集的小伙伴不用特意从python环境中去处理

有了界面之后,各个参数的设置就比较清楚了

可以设置源数据集所在的目录,也可以直接把数据集的文件夹拖动到界面上,自动把目录填入

设置输出目录,最终划分数据集后所保存的位置

设置不同数据集的划分比例,这里需要注意划分的比例之和不能超过1

点击开始划分按钮后,会有数据集划分的进度和日志信息,方便用户随时了解划分进度情况。

以上就是如何使用labelimg来标注数据集,然后如果通过脚本自动划分数据集,最终通过封装好gui来实现更进一步的数据集划分,中间细节难免有些疏漏,如有问题,可以评论区进行讨论。

如何用labelimg标注yolo数据集,并利用工具自动划分数据集的更多相关文章

  1. 教你从头到尾利用DQN自动玩flappy bird(全程命令提示,GPU+CPU版)【转】

    转自:http://blog.csdn.net/v_JULY_v/article/details/52810219?locationNum=3&fps=1 目录(?)[-] 教你从头到尾利用D ...

  2. 仿照CIFAR-10数据集格式,制作自己的数据集

    本系列文章由 @yhl_leo 出品,转载请注明出处. 文章链接: http://blog.csdn.net/yhl_leo/article/details/50801226 前一篇博客:C/C++ ...

  3. 【机器学习PAI实战】—— 玩转人工智能之利用GAN自动生成二次元头像

    前言 深度学习作为人工智能的重要手段,迎来了爆发,在NLP.CV.物联网.无人机等多个领域都发挥了非常重要的作用.最近几年,各种深度学习算法层出不穷, Generative Adverarial Ne ...

  4. CVE-2014-6271 Bash漏洞利用工具

    CVE-2014-6271 Bash漏洞利用工具 Exploit 1 (CVE-2014-6271) env x='() { :;}; echo vulnerable' bash -c "e ...

  5. 【教程】手把手教你如何利用工具(IE9的F12)去分析模拟登陆网站(百度首页)的内部逻辑过程

    [前提] 想要实现使用某种语言,比如Python,C#等,去实现模拟登陆网站的话,首先要做的事情就是使用某种工具,去分析本身使用浏览器去登陆网页的时候,其内部的执行过程,内部逻辑. 此登陆的逻辑过程, ...

  6. linux(以ubuntu为例)下Android利用ant自动编译、修改配置文件、批量多渠道,打包生成apk文件

    原创,转载请注明:http://www.cnblogs.com/ycxyyzw/p/4555328.html  之前写过一篇<windows下Android利用ant自动编译.修改配置文件.批量 ...

  7. SQLServer2005利用维护计划自动备份数据库

    经常性忘了给数据库备份,结果当数据库发生问题的时候,才发现备份是1个月以前的,那个后悔与懊恼还加惭愧啊,别提有对难受了.要认为的记住去备份比较难,每天事情又那么多,所以有了这个自动备份就不用愁了.先拷 ...

  8. jenkins远程命令执行利用工具

    昨天看小飞侠写的py的jenkins的脚本,昨天晚上在微信里评论今天写一个JAVA的GUI的tools. 早上花了点时间写一下: code: package com.tools; import jav ...

  9. Pytorch划分数据集的方法

    之前用过sklearn提供的划分数据集的函数,觉得超级方便.但是在使用TensorFlow和Pytorch的时候一直找不到类似的功能,之前搜索的关键字都是"pytorch split dat ...

  10. 7. Vulnerability exploitation tools (漏洞利用工具 11个)

    Metasploit于2004年发布时,将风暴带入了安全世界.它是开发,测试和使用漏洞利用代码的高级开源平台. 可以将有效载荷,编码器,无操作生成器和漏洞利用的可扩展模型集成在一起,使得Metaspl ...

随机推荐

  1. 重写IE的showModalDialog模态框以兼容现代浏览器

    背景 之前有个项目是 jsp 的,之前都是在 IE 浏览器上运行,现在要将这个项目做兼容性改造(信创),需要兼容谷歌.所以需要将项目中的公共弹框给改掉,而项目中模态框基本上都是用的 showModal ...

  2. LLaMA (以LLaMA2为例,文末附加对比1 2 3 三个版本的变化)

    补充背景: 关于Transformer和Llama架构的演进 一.背景 LLaMA 2 和 LLaMA2-Chat 参数规模:70亿.130亿和700亿 数据和训练规模: 上下文长度 训练资源 性能表 ...

  3. MySQL 主从延迟导致业务数据不一致

    场景: 写入一条优惠劵数据,然后将该优惠劵信息读取出来同步给下游数据 现象: 本地写入优惠劵数据成功,同步信息成功.上周同步数据代码正常,周末改了发送优惠劵的信息,然后周一来了发现同步数据无法同步. ...

  4. wc记录

    WC记录 咋可 随机化 CF1746F 给每个值随机成\(0/1\),然后查询区间内的所有数的和是否\(\equiv0\mod k\) 考虑错误率,对于一个不合法的权值,设其有\(r\)个,考虑区间内 ...

  5. ChatGPT搅动AI芯片的“一池春水”

    这是IC男奋斗史的第37篇原创 本文1520字,预计阅读4分钟. ChatGPT是什么以及它的发展历程,相信各位老铁们都已经很清楚,杰哥便不再赘述.大家都知道,杰哥是做AI芯片的,ChatGPT与杰哥 ...

  6. C# 托盘图标缓存清除

    https://blog.csdn.net/weixin_42953003/article/details/119676004 using System; using System.Collectio ...

  7. RFKILL 调研

    RFkill 调研. 概念 可使其处于可被软件重新激活的状态(软锁定)或者将其放在软件无法重新激活的位置(硬锁定). 命令执行 E:rfkill list 获 得 设 备 列 表 ,每 个 都 包 含 ...

  8. 企业如何通过ETL工具实现主数据的同步

    1. 主数据的定义与重要性 主数据,作为企业的核心数据资产,涵盖了客户.产品.供应商.员工等关键业务实体信息.这些数据的稳定性.共享性和对决策的影响力,使其成为企业运营和战略决策不可或缺的基础.主数据 ...

  9. SciTech-Mathmatics-Analysis-Calculus: Difference+Derivative+Integral+Limit:极限(变化测度与量化,高阶)+Series无穷级数+Field:Closure+Theories{RealTheory:Continuity+Measure:Metric+Set(Countability,Set Vs. Element-Wise)}

    SciTech-Mathmatics-Analysis Mathematical Thinking 数学思维:集合论,数和数域,运算符号,函数关系,数形结合: 导数.微分.积分的奥秘就在(例如变形:同 ...

  10. Kafka为什么吞吐量大,速度快?

    前言 根据个人的经历,无论在工作中,还是即将要经历的面试,MQ这部分是肯定要了解的,虽然之前工作中一直使用Kafka但是一些详细的细节知识还是了解的不深,所以这次总结一波. Kafka为什么吞吐量这么 ...