3. LabelImg实战:从安装到验证的完整标注流程
标注工具那么多,为什么我偏偏推荐 LabelImg?
说白了,它够轻量、够直接。你不需要配置复杂的环境,也不用学一堆新概念。打开软件,画框,命名,保存——就这么简单。我最早做目标检测项目时,用的就是它。那时候数据量不大,几百张图,LabelImg 帮我扛过了最基础的标注阶段。
好,咱们直接进入正题。
3.1 LabelImg 安装与配置
安装方式有两种,我分别说说。
3.1.1 方式一:pip 安装(推荐)
这是我最常用的方式。干净、快速、好卸载。
pip install labelImg
labelImg
嗯,就两行命令。如果你用的是 Python 3.6 以上版本,基本不会出问题。我在 Windows 和 Ubuntu 上都试过,一路绿灯。
3.1.2 方式二:源码运行
如果你需要二次开发,或者想看看它底层怎么实现的,可以走这条路。
git clone https://github.com/tzutalin/labelImg.git
cd labelImg
pip install -r requirements/requirements-linux-python3.txt
python labelImg.py
注意,不同系统要选不同的 requirements 文件。Windows 用 requirements-windows-python3.txt,macOS 同理。
python labelImg.py,结果报了个 Qt 相关的错。后来发现是 PyQt5 没装全。解决方案很简单:pip install pyqt5 单独装一下就好。
3.1.3 启动后的界面认识
启动后你会看到这样一个界面:左侧是工具栏,中间是图像显示区,右侧是标注列表。别被它简陋的外表骗了——该有的功能一个不少。
3.2 图像标注流程
安装好了,咱们开始干活。标注这件事,看着简单,但细节决定成败。
3.2.1 准备工作:数据组织
我个人习惯把图片按类别分文件夹放好。比如:
datasets/
├── images/
│ ├── train/
│ │ ├── img_001.jpg
│ │ ├── img_002.jpg
│ │ └── ...
│ └── val/
│ ├── img_100.jpg
│ └── ...
└── labels/ # 标注文件会自动生成在这里
├── train/
└── val/
为什么要这样分?因为 YOLO 训练时需要区分训练集和验证集。你想想看,如果所有图片混在一起,后面还得再写脚本去分,多麻烦。一步到位,省心。
3.2.2 开始标注:画框与命名
打开 LabelImg,按以下步骤操作:
- 设置保存格式: 点击
View→Auto Save mode,勾上。再点击PascalVOC切换为YOLO格式。 - 打开图片目录: 点击左侧
Open Dir,选择你的图片文件夹。 - 设置保存目录: 点击
Change Save Dir,选择 labels 文件夹。 - 画框: 点击左侧
Create RectBox按钮(或按快捷键W),在目标物体上拖拽画框。 - 命名: 松开鼠标后,弹出对话框输入类别名称。比如
person、car。 - 保存: 按
Ctrl+S或点击Save。 - 下一张: 按
D键切换到下一张图片。
| 操作 | 快捷键 |
| 画框 | W |
| 删除选中框 | Delete |
| 上一张 | A |
| 下一张 | D |
| 保存 | Ctrl+S |
| 缩放 | 滚轮 |
| 平移 | 按住 Ctrl + 拖拽 |
3.2.3 标注时的几个关键原则
我在项目中遇到过不少因为标注不规范导致模型训练效果差的情况。这里总结几条铁律:
- 框要贴边: 标注框必须紧贴目标物体的边缘,不要留白太多,也不要切掉物体的一部分。
- 遮挡处理: 如果物体被遮挡,只标注可见部分。不要脑补被挡住的部分。
- 类别一致: 同一个类别,命名必须完全一致。大小写、空格都不能错。
person和Person会被当成两个不同的类。 - 小目标标注: 对于很小的物体(比如远处的行人),也要标注。YOLO 对小目标的检测能力,很大程度上取决于你有没有标注它。
car 写成了 car (多了一个空格)。训练时模型把 car 当成了一个独立类别,导致检测结果全乱套。后来我写了个脚本批量替换才救回来。所以,命名时一定要仔细。
3.3 标注文件检查与验证
标注完了,别急着训练。先检查一下标注文件的质量。这一步很多人会跳过,但我建议你千万别省。
3.3.1 YOLO 标注文件格式
LabelImg 保存的 YOLO 格式标注文件是 .txt 文件,每张图片对应一个同名文件。格式如下:
class_id x_center y_center width height
注意,这里的坐标都是归一化后的值(0~1 之间)。举个例子:
0 0.5 0.5 0.3 0.4
1 0.2 0.3 0.1 0.15
这表示:第一行是类别 0 的物体,中心点在图片的 (0.5, 0.5) 位置,宽高占图片的 30% 和 40%。第二行是类别 1 的物体。
3.3.2 检查清单
我每次标注完都会做这几步检查:
| 检查项 | 检查方法 | 常见问题 |
|---|---|---|
| 文件完整性 | 确保每张图片都有对应的 .txt 文件 | 漏标、跳标 |
| 坐标合法性 | 所有坐标值在 0~1 之间 | 负数或大于 1 的异常值 |
| 类别 ID 范围 | 类别 ID 从 0 开始,连续递增 | 跳号、重复号 |
| 框大小合理性 | width 和 height 不能为 0 | 误操作产生的零宽零高框 |
| 图片与标注匹配 | 图片文件名和标注文件名一致 | 后缀名不匹配、命名错误 |
3.3.3 用脚本批量验证
手动检查几百个文件太累了。我写了个小脚本,一键验证:
import os
def check_labels(label_dir, num_classes):
errors = []
for fname in os.listdir(label_dir):
if not fname.endswith('.txt'):
continue
path = os.path.join(label_dir, fname)
with open(path, 'r') as f:
lines = f.readlines()
for i, line in enumerate(lines):
parts = line.strip().split()
if len(parts) != 5:
errors.append(f"{fname}: 第{i+1}行格式错误")
continue
cls_id = int(parts[0])
if cls_id < 0 or cls_id >= num_classes:
errors.append(f"{fname}: 类别ID {cls_id} 超出范围")
coords = [float(x) for x in parts[1:]]
if any(c < 0 or c > 1 for c in coords):
errors.append(f"{fname}: 坐标值异常 {coords}")
if errors:
for e in errors:
print(e)
else:
print("所有标注文件检查通过!")
# 使用示例
check_labels("datasets/labels/train", num_classes=2)
check_labels.py,每次标注完跑一遍。花 10 秒钟检查,能省下后面几小时的调试时间。
3.3.4 可视化验证
除了脚本检查,我还会用可视化方式看一眼。LabelImg 本身就支持:重新打开一张图片,看看框的位置对不对。或者用 OpenCV 画框显示:
import cv2
import numpy as np
def draw_yolo_boxes(image_path, label_path, class_names):
img = cv2.imread(image_path)
h, w = img.shape[:2]
with open(label_path, 'r') as f:
for line in f.readlines():
cls_id, xc, yc, bw, bh = map(float, line.strip().split())
x1 = int((xc - bw/2) * w)
y1 = int((yc - bh/2) * h)
x2 = int((xc + bw/2) * w)
y2 = int((yc + bh/2) * h)
cv2.rectangle(img, (x1, y1), (x2, y2), (0, 255, 0), 2)
cv2.putText(img, class_names[int(cls_id)], (x1, y1-5),
cv2.FONT_HERSHEY_SIMPLEX, 0.5, (0, 255, 0), 1)
cv2.imshow('Check', img)
cv2.waitKey(0)
# 使用示例
draw_yolo_boxes("datasets/images/train/img_001.jpg",
"datasets/labels/train/img_001.txt",
["person", "car"])
看到框和物体匹配上了,心里才踏实。
3.4 本章小结
标注这件事,说白了就是「细心活」。工具本身不复杂,复杂的是你怎么保证每一张图、每一个框都准确无误。我见过太多人因为标注质量差,导致模型训练效果不好,最后反过来怀疑算法有问题。其实问题往往出在数据上。
记住三个要点:
- 安装用 pip,省事
- 标注要规范,框贴边、名一致
- 检查不能省,脚本+可视化双重验证