3、YOLOv8模型训练准备:数据集标注工具LabelImg介绍、COCO数据集格式、自定义数据集制作

好,到了第三章节。前两章我们把树莓派的环境和YOLOv8的框架搭好了,但有个关键问题——模型拿什么学?

说白了,YOLOv8再厉害,它也是个“睁眼瞎”。你得先给它看一堆标注好的图片,告诉它“这是猫”、“那是狗”、“这个红绿灯是红灯”。这个过程,就是数据集制作。

我个人习惯把这一步叫做“喂数据”。数据喂得好不好,直接决定模型能不能用。我在项目里见过太多人,模型结构调得飞起,结果数据集一塌糊涂,最后训练出来的模型根本没法部署。嗯,咱们今天就把这个地基打牢。

3.1 数据集标注工具:LabelImg

标注工具很多,但LabelImg是最经典、最轻量的一个。它用Python写的,界面简单,支持YOLO和VOC两种输出格式。对于咱们树莓派部署的场景,完全够用。

我的建议:别一上来就折腾那些花里胡哨的在线标注平台。LabelImg离线运行,数据不出本地,对于小规模自定义数据集,效率反而更高。

3.1.1 安装LabelImg

安装很简单,我一般用pip直接装:

pip install labelImg

装完之后,在终端输入 labelImg 就能启动。如果你用的是Python虚拟环境,记得先激活环境再运行。

我曾经踩过的坑:在树莓派上直接跑LabelImg的图形界面会非常卡,因为它的GUI依赖Qt。我建议你在性能更好的PC或笔记本上完成标注,然后把标注好的文件拷贝到树莓派上。别在派上硬扛标注工作,那是跟自己过不去。

3.1.2 标注流程

打开LabelImg后,界面很直观。我简单说一下操作步骤:

  1. 打开图片目录:点击“Open Dir”,选择你存放原始图片的文件夹。
  2. 选择保存格式:点击“Change Save Dir”,设置标注文件的输出目录。然后在菜单栏 View 里勾选“Auto Save mode”,省得每标一张点一次保存。
  3. 创建矩形框:按键盘 W 键,鼠标会变成十字。在目标物体上拖拽出矩形框。
  4. 输入标签名:弹窗里输入类别名称,比如 person、car、helmet。注意,标签名不要带空格和特殊字符。
  5. 切换下一张:按 D 键切换到下一张图片,按 A 键回退。

标注完一张,LabelImg会自动在同目录下生成一个同名的 .txt 文件(如果你选的是YOLO格式)。这个文件里存的就是目标框的坐标信息。

3.2 COCO数据集格式

聊完工具,咱们得说说数据格式。YOLOv8原生支持两种格式:YOLO格式和COCO格式。我个人更推荐大家理解COCO格式,因为它是目前目标检测领域的事实标准。

COCO格式说白了就是一个大的JSON文件。里面包含了图片信息、标注信息、类别信息。结构大概是这样的:

{
  "images": [
    {"id": 1, "file_name": "000001.jpg", "width": 640, "height": 480}
  ],
  "annotations": [
    {"id": 1, "image_id": 1, "category_id": 1, "bbox": [100, 150, 200, 300], "area": 60000}
  ],
  "categories": [
    {"id": 1, "name": "person"}
  ]
}

这里有个关键点:bbox 的格式是 [x, y, width, height],其中 x, y 是矩形框左上角的坐标。这和YOLO格式的 [center_x, center_y, width, height] 不一样。很多新手在这里搞混,导致训练出来的模型检测框全偏了。

核心区别:
  • COCO格式:左上角坐标 + 宽高,单位是像素。
  • YOLO格式:中心点坐标 + 宽高,单位是相对于图片宽高的归一化值(0~1)。

YOLOv8在训练时,会自动把COCO格式的JSON转换成内部的张量。所以如果你用LabelImg标注时选了YOLO格式,其实也可以直接用,但需要把图片和txt文件按YOLO的目录结构放好。

3.3 自定义数据集制作

好了,理论讲完,咱们来动手。假设你要做一个“安全帽检测”的数据集,用来部署到树莓派上监控工地安全。

3.3.1 数据采集

数据采集这块,我建议你遵循“三多原则”:多角度、多光照、多背景。别只拍正面的安全帽,侧面的、背面的、逆光的、阴天的,都得有。

我在项目里遇到过这种情况:训练集里全是红色安全帽,结果部署到现场,工人戴的是黄色安全帽,模型直接漏检。所以采集数据时,尽量覆盖所有可能的变体。

3.3.2 目录结构

YOLOv8对数据集目录结构有约定。我个人习惯这样组织:

datasets/
  helmet/
    images/
      train/
        img_001.jpg
        img_002.jpg
        ...
      val/
        img_100.jpg
        img_101.jpg
        ...
    labels/
      train/
        img_001.txt
        img_002.txt
        ...
      val/
        img_100.txt
        img_101.txt
        ...

注意:图片和标注文件的名字必须一一对应,后缀不同而已。比如 img_001.jpg 对应 img_001.txt。

3.3.3 数据集配置文件

YOLOv8训练时需要一个 .yaml 文件来告诉模型数据在哪。内容如下:

# helmet.yaml
path: ./datasets/helmet  # 数据集根目录
train: images/train      # 训练集图片路径
val: images/val          # 验证集图片路径

nc: 2                    # 类别数量
names: ['helmet', 'head']  # 类别名称列表

这里 nc 是类别数,names 是类别名列表。顺序要和标注时的标签名一致。比如标注时 helmet 是第一个出现的标签,那它在列表里就排第一。

3.3.4 数据划分

数据采集完、标注完,最后一步是划分训练集和验证集。我一般按8:2的比例随机划分。可以用一个简单的Python脚本搞定:

import os
import random
import shutil

# 假设所有图片都在 raw_images 文件夹
images = os.listdir('raw_images')
random.shuffle(images)

split_idx = int(len(images) * 0.8)
train_images = images[:split_idx]
val_images = images[split_idx:]

# 然后分别复制到 images/train 和 images/val
# 同时复制对应的 .txt 文件到 labels/train 和 labels/val
一个小技巧:划分完后,检查一下验证集里是否包含了所有类别。如果某个类别只在训练集里出现,验证集里没有,那验证指标会不准。我一般会写个脚本统计一下。

3.4 本章知识结构图

下面这张图总结了数据集制作的完整流程,从原始图片到可训练的YOLOv8数据集:

自定义数据集制作流程 自定义数据集制作流程 原始图片采集 LabelImg 标注 生成 .txt 标注文件 整理目录结构 8:2 划分训练/验证 创建 data.yaml ✅ 可训练的 YOLOv8 数据集 关键:图片与标注文件同名、类别ID从0开始、验证集覆盖所有类别

3.5 避坑指南

最后,我把自己这些年踩过的坑总结一下,你遇到了可以少走弯路:

常见问题 现象 解决方案
类别ID混乱 训练时loss不收敛,mAP为0 检查 data.yaml 中 names 的顺序是否与标注时的标签顺序一致
标注框超出图片边界 训练报错或检测框异常 标注时注意框不要超出图片边缘,LabelImg会自动限制
图片与标注文件不匹配 训练时提示找不到标注文件 确保文件名完全一致(包括大小写),且放在对应的 labels 目录下
类别样本不均衡 模型只检测出多数类,漏检少数类 采集数据时有意增加少数类的样本量,或者使用数据增强
我曾经犯过的错:有一次我标注了1000张图片,结果训练时发现mAP只有0.2。排查了半天,发现是 data.yaml 里的 nc 写成了3,但我实际只有2个类别。YOLOv8不会报错,它会默默地把第三个类别当成空类,导致模型学歪了。所以,训练前一定要用 yolo checks 命令验证一下数据集配置。