第2章:数据集准备——LabelImg标注工具安装、Pascal VOC格式详解、COCO格式详解、数据集划分与组织

做目标检测,数据是地基。模型再牛,没有高质量的数据集也是白搭。这一章咱们就聊聊怎么把原始图片变成模型能吃的“标准饲料”。

我个人习惯把数据集准备分成三步:标注工具、格式理解、划分组织。每一步都有坑,我踩过不少,今天一并告诉你。

2.1 LabelImg标注工具安装与使用

LabelImg是款老牌标注工具,轻量、跨平台、支持Pascal VOC和YOLO格式。我最早做检测项目时就用它,到现在依然觉得顺手。

2.1.1 安装方式

推荐用pip安装,干净利落:

# 安装PyQt5和lxml依赖
pip install pyqt5 lxml

# 安装LabelImg
pip install labelImg

# 启动
labelImg

如果你在Linux上,也可以从源码编译。但我建议直接用pip,省时间。

我曾经踩过的坑: 在Windows上直接pip install labelImg后,启动报错“No module named 'PyQt5.sip'”。原因是PyQt5版本冲突。解决办法:先卸载再重装指定版本——pip uninstall pyqt5 sip,然后pip install pyqt5==5.15.6。

2.1.2 标注流程

打开LabelImg后,界面很简洁。我一般按这个步骤操作:

  1. 打开图片目录:点击“Open Dir”选择存放图片的文件夹。
  2. 选择保存目录:点击“Change Save Dir”指定XML文件输出位置。
  3. 切换格式:默认是Pascal VOC格式(XML)。如果要标YOLO格式,点击“View”→“Auto Save mode”和“YOLO”格式切换。
  4. 开始标注:按键盘 W 键进入创建矩形框模式,拖拽鼠标框选目标,输入标签名称。
  5. 快捷键:Ctrl+S 保存,D 下一张,A 上一张。
我的个人习惯: 标注时把“Auto Save mode”打开,每标完一张自动保存,防止意外崩溃丢数据。另外,标签名称统一用小写英文,比如“person”、“car”、“dog”,避免大小写混乱。

2.2 Pascal VOC格式详解

Pascal VOC是计算机视觉领域最经典的标注格式之一。YOLO早期版本也用它。说白了,它就是一张图片对应一个XML文件。

2.2.1 目录结构

一个标准的VOC数据集长这样:

VOCdevkit/
└── VOC2007/
    ├── Annotations/      # 存放XML标注文件
    ├── JPEGImages/       # 存放原始图片
    ├── ImageSets/
    │   └── Main/         # 存放训练/验证/测试的txt列表
    ├── SegmentationClass/ # 语义分割标签(可选)
    └── SegmentationObject/ # 实例分割标签(可选)

我们做目标检测,主要关注前三个文件夹。

2.2.2 XML文件结构

打开一个XML文件,里面内容很清晰:

<annotation>
    <folder>VOC2007</folder>
    <filename>000001.jpg</filename>
    <size>
        <width>500</width>
        <height>375</height>
        <depth>3</depth>
    </size>
    <object>
        <name>person</name>
        <pose>Unspecified</pose>
        <truncated>0</truncated>
        <difficult>0</difficult>
        <bndbox>
            <xmin>100</xmin>
            <ymin>50</ymin>
            <xmax>300</xmax>
            <ymax>250</ymax>
        </bndbox>
    </object>
</annotation>

关键字段:

  • filename:图片文件名,必须和JPEGImages里的一致。
  • size:图片宽、高、通道数。这个很重要,YOLO训练时会用到。
  • object:每个目标一个object块。name是类别,bndbox是边界框坐标(左上角和右下角)。
  • truncated和difficult:表示目标是否被截断、是否难识别。YOLO训练时一般忽略difficult=1的样本。
避坑指南: 我曾经遇到一个项目,标注员把xmin和ymin写反了,导致模型训练时loss死活不降。检查了三天才发现是坐标顺序问题。所以标注完成后,一定要写个脚本可视化检查一下框的位置。

2.3 COCO格式详解

COCO格式是目前最流行的标注格式,YOLOv5/v8/v10都原生支持。它用一个JSON文件管理所有标注信息。

2.3.1 JSON结构

COCO的JSON文件包含五个主要字段:

字段 类型 说明
info dict 数据集描述信息(版本、日期等)
licenses list 许可证信息(可忽略)
images list 所有图片信息(id、文件名、宽、高)
annotations list 所有标注信息(目标id、图片id、类别id、bbox、分割多边形等)
categories list 类别列表(id到名称的映射)

举个例子,images字段的一条记录:

{
    "id": 1,
    "file_name": "000001.jpg",
    "width": 500,
    "height": 375
}

annotations字段的一条记录:

{
    "id": 1,
    "image_id": 1,
    "category_id": 1,
    "bbox": [100, 50, 200, 200],
    "area": 40000,
    "iscrowd": 0
}
注意: COCO的bbox格式是 [x, y, width, height],而VOC是 [xmin, ymin, xmax, ymax]。这两个格式经常搞混。我见过有人直接把VOC的坐标塞进COCO的bbox里,结果框全偏了。转换时一定要做坐标变换。

2.3.2 VOC转COCO

实际项目中,我们经常需要把VOC格式转成COCO格式。我写过一个转换脚本,核心逻辑就是遍历XML文件,提取坐标并做格式转换:

# VOC的[xmin, ymin, xmax, ymax] → COCO的[x, y, width, height]
x = xmin
y = ymin
w = xmax - xmin
h = ymax - ymin
coco_bbox = [x, y, w, h]

2.4 数据集划分与组织

数据标完了,格式转好了,接下来就是划分。这一步看似简单,但划分不好会影响模型评估的可靠性。

2.4.1 划分比例

我一般按这个比例划分:

数据集 比例 用途
训练集 70% - 80% 模型学习参数
验证集 10% - 15% 调参、早停、模型选择
测试集 10% - 15% 最终评估,不参与训练

数据量小(比如不到1000张)时,我会用交叉验证。数据量大(上万张)时,简单随机划分就够了。

2.4.2 划分原则

  • 随机性:用random.shuffle打乱数据,避免类别分布不均。
  • 分层采样:如果某些类别样本极少,要保证每个子集中都有该类别的样本。
  • 避免数据泄露:同一场景的连续帧图片,只能分到同一个子集。否则模型会“作弊”。
我的经验: 划分完成后,写个脚本统计一下每个子集的类别分布。如果发现某个类别在验证集里一个都没有,那评估结果就是假的。我曾经因为这个原因,模型在验证集上mAP很高,上线后却一塌糊涂。

2.4.3 组织方式

对于YOLO训练,我推荐这种目录结构:

dataset/
├── images/
│   ├── train/      # 训练图片
│   ├── val/        # 验证图片
│   └── test/       # 测试图片
├── labels/
│   ├── train/      # 训练标签(YOLO格式的txt文件)
│   ├── val/        # 验证标签
│   └── test/       # 测试标签
└── dataset.yaml    # 数据集配置文件

dataset.yaml的内容:

train: ./images/train
val: ./images/val
test: ./images/test

nc: 3  # 类别数量
names: ['person', 'car', 'dog']  # 类别名称

这种组织方式YOLO可以直接读取,省去很多麻烦。

2.5 本章知识体系

下面这张图帮你理清本章的核心逻辑:

数据集准备知识体系 数据集准备知识体系 标注工具 标注格式 数据划分 pip安装 快捷键标注 Pascal VOC COCO JSON 随机划分 分层采样 核心流程:标注 → 格式转换 → 划分组织 → 训练 每一步都影响最终模型效果,别偷懒

嗯,这一章的内容就这些。工具、格式、划分,每一步都扎实了,后面训练模型才能顺风顺水。记住,数据准备花的时间,会在模型训练和调试阶段加倍还给你。