4、数据集标注实战(上):创建项目与设置类别、矩形框标注技巧、单张图片标注全流程、标签文件保存与检查
好,咱们进入真正的动手环节了。
前面几章讲了理论、环境、工具安装,说实话,那些都是热身。从这一章开始,你要亲手拿着鼠标,一张一张地框图了。我当年第一次做标注的时候,觉得这活儿有啥技术含量?不就是画框吗?结果第一天就翻车了——类别名拼写错误,导致训练出来的模型把猫认成了狗。嗯,这种低级错误,我希望你别再犯。
4.1 创建项目与设置类别
打开 labelImg,界面很简洁。左上角有个「Open Dir」和「Change Save Dir」,分别用来选图片文件夹和标签保存位置。我个人习惯把图片和标签放在同一个父目录下,比如:
dataset/
├── images/ # 原始图片
└── labels/ # 标注后的txt文件
然后点击「Change Save Dir」指向 labels 文件夹。这样后续训练时路径管理会清爽很多。
接下来是关键——设置类别。点击左侧工具栏的「Edit」→「Create RectBox」,或者直接按快捷键 w。在弹出框里输入你的类别名。注意:类别名必须和后续训练用的 data.yaml 文件完全一致,大小写、空格都不能错。
举个例子,假设你要检测交通场景:
| 类别索引 | 类别名 | 说明 |
|---|---|---|
| 0 | person | 行人 |
| 1 | car | 小汽车 |
| 2 | bus | 公交车 |
| 3 | traffic_light | 交通灯 |
设置好之后,右侧的「Label List」会显示这些类别。每次画框时,直接选就行,不用再打字了。
4.2 矩形框标注技巧
标注不是随便拉个框就完事的。这里有几个实战技巧,能帮你省下大量时间:
- 快捷键要背熟:
w画框,a上一张,d下一张,ctrl+s保存。我刚开始用鼠标点菜单,一天标了200张,手腕都快废了。后来改用快捷键,效率直接翻倍。 - 框要贴着物体边缘:别留太多背景,也别切掉目标的关键部位。比如标一个人,框的上沿贴着头发,下沿贴着脚底,左右贴着身体最宽处。你想想看,如果框里有一半是背景,模型学到的特征就掺杂了噪声。
- 遮挡物体怎么标?:如果目标被遮挡了一部分,只标可见部分。比如一个人被柱子挡住了一半,你就标露出来的那一半。模型会自己学习推断完整形状的。
- 小目标要放大标:图片里很小的物体(比如远处的行人),建议用
ctrl+滚轮放大图片再标。我见过有人偷懒,小目标直接画个像素点大小的框,结果训练出来的模型根本检测不到小物体。
ctrl+s 保存,然后按 d 切换到下一张。这样形成肌肉记忆后,手基本不用离开键盘。
4.3 单张图片标注全流程
咱们走一遍完整的标注流程,拿一张街景图片举例:
- 打开图片:点击「Open Dir」选择 images 文件夹,双击第一张图片加载。
- 画框:按
w,鼠标左键按住拖动,松开后弹出类别选择框。选「person」。 - 调整框:如果框没对齐,可以拖动框的四个角或边线微调。注意,labelImg 不支持旋转框,所以尽量让框的边和物体主轴平行。
- 继续标注:同一张图里可能有多个目标。比如还有一辆 car,再按
w画第二个框,选「car」。 - 检查:看看有没有漏标的目标。我习惯从左上角到右下角扫视一遍,确保每个明显物体都被框了。
- 保存:按
ctrl+s,标签文件会自动生成到 labels 文件夹里。 - 下一张:按
d继续。
整个过程熟练后,一张图大概30秒到1分钟。复杂场景(比如拥挤的人群)可能需要2-3分钟。别急,质量比数量重要。
4.4 标签文件保存与检查
保存后,去 labels 文件夹看看。你会看到一个和图片同名的 .txt 文件。比如 img001.jpg 对应 img001.txt。用记事本打开,内容长这样:
0 0.523 0.412 0.156 0.334
1 0.789 0.567 0.223 0.445
每一行代表一个目标框,格式是:
类别索引 中心点x 中心点y 宽度 高度
注意,这些坐标都是归一化的,范围在0到1之间。怎么算的?比如图片宽1920像素,框的中心点x坐标是1000像素,那归一化后就是 1000/1920 ≈ 0.521。
- 类别索引是否在0~(类别总数-1)之间?比如你只设了 person(0) 和 car(1),那索引不能出现2。
- 坐标值是否都在0~1之间?如果出现负数或大于1,说明框画到图片外面去了,需要重新调整。
- 文件是否和图片一一对应?每张图片必须有一个同名的 .txt 文件,不能多也不能少。
我建议你每标完50张图,就批量检查一次。写个简单的 Python 脚本:
import os
labels_dir = "dataset/labels"
images_dir = "dataset/images"
for f in os.listdir(labels_dir):
if f.endswith(".txt"):
# 检查对应的图片是否存在
img_name = f.replace(".txt", ".jpg")
if not os.path.exists(os.path.join(images_dir, img_name)):
print(f"警告:标签 {f} 没有对应的图片!")
# 检查标签内容
with open(os.path.join(labels_dir, f)) as fp:
for line in fp:
parts = line.strip().split()
if len(parts) != 5:
print(f"格式错误:{f} 中的 {line}")
else:
cls = int(parts[0])
if cls < 0 or cls > 3: # 假设有4个类别
print(f"类别索引越界:{f} 中的 {line}")
这个脚本我每次做新数据集都会跑一遍。说白了,标注阶段多花10分钟检查,能省下训练阶段调试的10小时。
好了,这一章的内容就到这儿。下一章咱们会讲更复杂的标注场景——多边形、关键点、以及如何用半自动工具加速标注。你先把手头的图片标好,别急着往后看。标注这事儿,练得越多,手感越好。