从零到一:手把手教你用LabelImg打造专属VOC/YOLO目标检测数据集
1. 环境准备与LabelImg安装
目标检测的第一步是准备好标注工具。LabelImg作为开源图像标注工具中的佼佼者,支持VOC和YOLO两种主流格式。这里以Windows系统为例演示安装过程(其他系统类似):
Python环境配置:
# 创建虚拟环境(推荐) python -m venv labelimg_env labelimg_env\Scripts\activate # 安装LabelImg pip install labelimg -i https://pypi.tuna.tsinghua.edu.cn/simple安装完成后,直接在命令行输入labelimg即可启动工具。第一次运行时建议准备两个文件夹:
JPEGImages/:存放待标注的原始图片Annotations/:用于保存标注结果
注意:如果遇到PyQt相关报错,可以尝试先安装
pip install pyqt5 lxml。Linux用户可能需要额外执行sudo apt-get install pyqt5-dev-tools
2. 数据标注实战技巧
2.1 标注界面详解
启动LabelImg后,你会看到这样的工作区:
- 左侧:图片显示区域
- 右侧:标注类别列表
- 顶部工具栏:保存、切换图片等常用功能
高效标注的3个关键设置:
- 在View菜单中勾选
Auto Save mode(切换图片自动保存) - 开启
Display Labels实时显示标注框和标签 - 启用
Advanced Mode让标注框持续显示
2.2 快捷键大全
记住这些快捷键能提升3倍效率:
W:创建标注框 A:上一张图片 D:下一张图片 Ctrl+鼠标滚轮:缩放图片 Del:删除当前标注框 Space:标记为已校验 Ctrl+S:手动保存2.3 类别管理技巧
在标注前,建议先创建predefined_classes.txt文件定义所有类别,例如:
cat dog person car启动时通过命令加载预设类别:
labelimg JPEGImages/ predefined_classes.txt3. 标注结果格式解析
3.1 VOC格式详解
选择PascalVOC格式时,每个图片会生成对应的XML文件,包含以下关键信息:
<annotation> <size> <width>800</width> <height>600</height> </size> <object> <name>dog</name> <bndbox> <xmin>100</xmin> <ymin>200</ymin> <xmax>300</xmax> <ymax>400</ymax> </bndbox> </object> </annotation>坐标系统以图片左上角为原点(0,0),向右为x正方向,向下为y正方向。
3.2 YOLO格式解析
选择YOLO格式会生成txt文件,其内容示例:
0 0.25 0.5 0.1 0.2 1 0.75 0.3 0.15 0.15每行表示一个物体,五个数字分别代表:
- 类别ID(对应classes.txt中的顺序)
- 中心点x坐标(归一化到0-1)
- 中心点y坐标
- 框宽度
- 框高度
4. 构建VOC标准数据集
4.1 目录结构规范
完整的VOC数据集应包含以下结构:
VOCdevkit/ └── VOC2024/ ├── Annotations/ # 存放XML标注文件 ├── JPEGImages/ # 存放原始图片 ├── ImageSets/ │ └── Main/ # 划分训练集/验证集 │ ├── train.txt │ └── val.txt4.2 自动划分训练集
使用Python脚本快速划分数据集:
import os import random img_dir = "VOCdevkit/VOC2024/JPEGImages" all_imgs = [f.split('.')[0] for f in os.listdir(img_dir)] random.shuffle(all_imgs) split = int(0.8 * len(all_imgs)) # 80%训练集 with open('VOCdevkit/VOC2024/ImageSets/Main/train.txt', 'w') as f: f.write('\n'.join(all_imgs[:split])) with open('VOCdevkit/VOC2024/ImageSets/Main/val.txt', 'w') as f: f.write('\n'.join(all_imgs[split:]))5. VOC转YOLO格式实战
5.1 转换原理
转换的核心是将VOC的绝对坐标(xmin,ymin,xmax,ymax)转换为YOLO的相对坐标:
def voc_to_yolo(size, box): dw = 1./size[0] dh = 1./size[1] x = (box[0] + box[1])/2.0 y = (box[2] + box[3])/2.0 w = box[1] - box[0] h = box[3] - box[2] return (x*dw, y*dh, w*dw, h*dh)5.2 批量转换脚本
使用这个脚本一键转换整个数据集:
import xml.etree.ElementTree as ET import os classes = ["cat", "dog"] # 替换为你的类别 def convert(size, box): # ...同上... for xml_file in os.listdir("Annotations"): tree = ET.parse(f"Annotations/{xml_file}") root = tree.getroot() with open(f"labels/{xml_file.replace('.xml','.txt')}", 'w') as f: for obj in root.findall('object'): cls = obj.find('name').text cls_id = classes.index(cls) xmlbox = obj.find('bndbox') b = (float(xmlbox.find('xmin').text), float(xmlbox.find('xmax').text), float(xmlbox.find('ymin').text), float(xmlbox.find('ymax').text)) bb = convert((w,h), b) f.write(f"{cls_id} {' '.join([str(a) for a in bb])}\n")6. 常见问题解决方案
问题1:标注时出现重复类别
- 解决方法:删除
labelImg/data/predefined_classes.txt文件
问题2:YOLO格式转换后坐标异常
- 检查点:确保图片尺寸读取正确,XML中的width/height与实际图片一致
问题3:标注框漂移
- 技巧:使用方向键微调选框位置(按住Shift加速移动)
在实际工业质检项目中,我发现保持标注一致性至关重要。建议团队制定明确的标注规范,例如:
- 对于部分遮挡物体:标注可见部分
- 小物体:至少占图片面积5%才标注
- 模糊物体:标记为difficult