第4章:数据集准备与标注——从原始图像到训练燃料

做目标检测,有个绕不开的坎——数据。模型再牛,没有高质量的数据集,也是白搭。我见过太多同学花大把时间调参,结果模型效果差,最后发现是标注数据出了问题。这一章,咱们就把数据准备这件事彻底讲透。

4.1 标注工具怎么选?

市面上标注工具不少,但真正好用的就那么几个。我个人习惯根据项目阶段来选:

工具 适用场景 优点 缺点
LabelImg 个人/小团队,快速标注 轻量、离线、免费 功能单一,无协同
CVAT 团队协作,中大型项目 Web端、自动标注、多人协同 部署稍复杂
Roboflow 数据管理与增强一体化 标注+增强+导出一条龙 免费版有数量限制

4.1.1 LabelImg:最朴实的入门选择

LabelImg 是我最早用的工具。它就是个 Python 写的桌面应用,打开就能用。操作很简单:

  1. 用 pip install labelImg 安装
  2. 终端输入 labelImg 启动
  3. 选择图片目录,按 W 键画框
  4. 输入类别名,保存

嗯,这里要注意——LabelImg 默认保存为 Pascal VOC 格式(XML),但 YOLO 需要的是 TXT 格式。你需要在菜单里切换一下:View → Auto Save Mode 和 PascalVOC → YOLO。

我的小技巧: 标注前先把类别文件 classes.txt 写好,这样标注时直接下拉选择,不用每次都手打。能省不少时间。

4.1.2 CVAT:团队协作的利器

如果你带团队做项目,CVAT 是更好的选择。它是个 Web 应用,部署在服务器上,大家用浏览器就能标注。

我曾经在一个智慧城市项目里,5个人同时标注10万张图片。用 CVAT 的自动标注功能,先拿一个预训练模型跑一遍,人工再修正,效率提升了至少3倍。

部署方式我推荐用 Docker:

docker run -p 8080:8080 \
  -e CVAT_HOST=your-server-ip \
  cvat/cvat:latest

启动后访问 http://localhost:8080,注册账号就能用了。

4.1.3 Roboflow:数据管理的一站式方案

Roboflow 是我最近比较喜欢的工具。它不只是标注,还能做数据增强、格式转换、版本管理。说白了,它把数据准备的全流程都包了。

你上传图片,在线标注,然后一键导出为 YOLO 格式。它还内置了各种增强策略,比如旋转、裁剪、色彩抖动。我一般用它来做快速原型验证。

注意: Roboflow 免费版最多只能存 1000 张图片。商业项目建议用自部署的版本,或者结合 CVAT 使用。

4.2 格式转换:COCO 与 VOC 的相爱相杀

做目标检测,绕不开两个格式:Pascal VOC 和 COCO。很多公开数据集用的是 COCO 格式,但 YOLO 训练需要的是 TXT 格式。所以格式转换是基本功。

格式 存储方式 坐标表示 典型工具
Pascal VOC XML 文件,每张图一个 xmin, ymin, xmax, ymax LabelImg
COCO JSON 一个 JSON 文件包含所有标注 x, y, width, height COCO API
YOLO TXT TXT 文件,每张图一个 class_id, x_center, y_center, w, h YOLO 训练脚本

为什么会有这么多格式?说白了,历史原因。VOC 是早期标准,COCO 是微软推的,YOLO 为了效率自己搞了一套。你想想看,如果每个框架都用不同格式,那转换代码就得写一堆。

我写了个简单的转换脚本,把 COCO JSON 转成 YOLO TXT:

import json
import os

def coco_to_yolo(coco_json_path, output_dir):
    with open(coco_json_path, 'r') as f:
        coco = json.load(f)
    
    # 建立类别映射
    categories = {cat['id']: cat['name'] for cat in coco['categories']}
    
    for img in coco['images']:
        img_id = img['id']
        img_w = img['width']
        img_h = img['height']
        
        txt_path = os.path.join(output_dir, img['file_name'].replace('.jpg', '.txt'))
        
        with open(txt_path, 'w') as f:
            for ann in coco['annotations']:
                if ann['image_id'] != img_id:
                    continue
                # COCO 格式: [x, y, w, h] 左上角坐标
                x, y, w, h = ann['bbox']
                # 转成 YOLO 格式: 中心点坐标 + 宽高,归一化
                x_center = (x + w / 2) / img_w
                y_center = (y + h / 2) / img_h
                w_norm = w / img_w
                h_norm = h / img_h
                class_id = ann['category_id'] - 1  # COCO 类别从1开始
                f.write(f"{class_id} {x_center:.6f} {y_center:.6f} {w_norm:.6f} {h_norm:.6f}\n")
关键点: COCO 的 bbox 是 [x, y, width, height],其中 (x, y) 是左上角坐标。YOLO 需要的是 [class_id, x_center, y_center, width, height],全部归一化到 [0, 1]。这个转换做不对,模型训练出来就是废的。

4.3 数据增强策略:让有限的数据发挥无限价值

数据不够?增强来凑。但增强不是乱加,得有策略。我见过有人把图片旋转90度,结果人倒着站,模型学了一堆错误特征。

下面是我在项目中验证过最有效的几种增强策略:

4.3.1 Mosaic 增强

Mosaic 是 YOLOv4 开始引入的,说白了就是把4张图拼成1张。这样做有几个好处:

  • 小目标检测能力提升——因为图片缩小了,小目标相对变大
  • 上下文信息更丰富——模型能看到更多场景
  • 相当于变相增加了 batch size

实现思路很简单:

def mosaic_augmentation(images, labels, img_size=640):
    # 随机选择4张图
    # 随机确定拼接中心点
    # 把4张图分别放到左上、右上、左下、右下
    # 处理边界框的坐标变换
    # 返回拼接后的图和标签
    pass  # 具体实现参考 YOLOv5 源码

嗯,这里要注意——Mosaic 增强后,有些边界框会被切掉。YOLOv5 的做法是只保留中心点在拼接图内的框,或者框面积大于一定阈值的。

4.3.2 MixUp 增强

MixUp 更狠——它把两张图按比例混合。比如 0.7 的猫 + 0.3 的狗,标签也按同样比例混合。模型看到的是模糊的、叠加的图像,但学到的特征更鲁棒。

我曾经在一个工业缺陷检测项目里,用了 MixUp 后,模型的泛化能力提升了 5 个点。为什么?因为缺陷样本太少,MixUp 相当于生成了无数种中间态。

经验之谈: MixUp 的混合系数 α 一般取 0.2~0.5。太小了没效果,太大了图像太模糊,模型学不到东西。我习惯用 0.3。

4.3.3 其他常用增强

增强方法 作用 适用场景 注意事项
HSV 色彩抖动 改变亮度、饱和度、色相 光照变化大的场景 色相变化不要超过 0.1
随机缩放 模拟远近变化 多尺度检测 缩放后要保证目标不畸变
随机裁剪 模拟遮挡 遮挡场景 裁剪比例不要超过 30%
水平翻转 增加对称性 左右对称的场景 文字、车牌等不要翻转

4.4 数据准备全流程

说了这么多,咱们把整个流程串起来。下面这张图是我做项目时用的标准流程:

数据准备全流程 数据准备与标注全流程 原始图像采集 数据清洗与筛选 工具标注(LabelImg/CVAT) 格式转换(VOC/COCO → YOLO) 数据增强(Mosaic/MixUp) 💡 关键检查点 • 标注质量抽检 • 类别平衡性检查 • 格式正确性验证

这个流程我用了很多年,基本没出过大问题。每一步都有坑,我踩过不少,下面分享几个:

我曾经踩过的坑:
  • 标注完才发现类别名拼写错误——比如 "person" 写成 "persom",模型直接忽略这个类别
  • 格式转换时坐标归一化忘记除以图片宽高——训练出来的模型框全偏了
  • Mosaic 增强后标签没同步更新——模型学了一堆错误位置
所以我现在每个步骤都加一个自动化校验脚本,跑完检查一遍。

4.5 数据质量检查清单

最后,我整理了一份检查清单。每次准备数据集,我都会过一遍:

  1. 图片质量:分辨率是否一致?有没有损坏的图片?
  2. 标注完整性:每张图都有对应的标注文件吗?
  3. 类别平衡:各类别样本数量差距大吗?要不要做重采样?
  4. 边界框质量:有没有框超出图片边界?框面积是不是太小?
  5. 格式正确性:YOLO 的坐标是不是在 [0,1] 范围内?
  6. 增强后验证:增强后的图片和标签是否对应?

你想想看,如果这些基础工作没做好,后面调参、改网络结构都是白费力气。数据质量决定了模型效果的上限,算法只是逼近这个上限的手段。

一句话总结: 花 70% 的时间在数据上,30% 的时间在模型上。这是我做了这么多年计算机视觉项目最深的体会。