YOLOv8交通目标检测实战:从BDD100K到TT100K数据集训练全流程

1次阅读
没有评论

共计 2171 个字符,预计需要花费 6 分钟才能阅读完成。

image.webp

背景痛点

交通目标检测是智能驾驶和交通监控中的核心任务,但数据集格式混乱给开发者带来了不少困扰。主流数据集如 BDD100K、TT100K 和 CCTSDB2017 各自采用不同的标注格式,导致预处理成本居高不下。

YOLOv8 交通目标检测实战:从 BDD100K 到 TT100K 数据集训练全流程

  • BDD100K 采用 JSON 格式存储标注,包含车辆、行人、交通标志等多类目标
  • TT100K 提供 YOLO 格式标签,但类别定义与 BDD100K 不一致
  • CCTSDB2017 使用专门的 XML 标注,国内交通标志覆盖全面

这种格式差异导致:
1. 需要编写复杂的数据转换脚本
2. 类别 ID 映射容易出错
3. 训练前的数据校验工作量大

技术方案

JSON 转 YOLO 格式脚本

核心转换逻辑需要处理三点:
1. 坐标归一化:将绝对坐标转为相对坐标
2. 类别映射:统一不同数据集的类别 ID
3. 异常处理:跳过无效标注框

def convert_bdd_to_yolo(json_path, output_dir, class_map):
    """BDD100K JSON 转 YOLO txt 格式"""
    with open(json_path) as f:
        data = json.load(f)

    for img in data:
        txt_path = os.path.join(output_dir, f"{img['name']}.txt")
        with open(txt_path, 'w') as f_txt:
            for obj in img['labels']:
                if obj['category'] not in class_map:
                    continue

                # 坐标归一化
                x_center = (obj['box2d']['x1'] + obj['box2d']['x2']) / 2 / img['width']
                y_center = (obj['box2d']['y1'] + obj['box2d']['y2']) / 2 / img['height']
                width = (obj['box2d']['x2'] - obj['box2d']['x1']) / img['width']
                height = (obj['box2d']['y2'] - obj['box2d']['y1']) / img['height']

                # 写入 YOLO 格式
                class_id = class_map[obj['category']]
                f_txt.write(f"{class_id} {x_center:.6f} {y_center:.6f} {width:.6f} {height:.6f}\n")

data.yaml 配置模板

关键参数说明:

train: ../datasets/tt100k/train/images
val: ../datasets/tt100k/val/images

nc: 45  # 类别总数
names: [
    'i2', 'i4', 'i5', 'il100', 'il60', 
    'il80', 'io', 'ip', 'p10', 'p11',
    # ... 其他 TT100K 类别
]

代码实践

数据集可视化校验

建议训练前运行校验脚本,确认标注是否正确:

def visualize_annotations(image_path, label_path):
    img = cv2.imread(image_path)
    h, w = img.shape[:2]

    with open(label_path) as f:
        for line in f:
            class_id, x, y, w, h = map(float, line.split())
            # 转换回绝对坐标
            x1 = int((x - w/2) * w)
            y1 = int((y - h/2) * h)
            x2 = int((x + w/2) * w)
            y2 = int((y + h/2) * h)

            cv2.rectangle(img, (x1,y1), (x2,y2), (0,255,0), 2)

    cv2.imshow('Preview', img)
    cv2.waitKey(0)

模型训练

YOLOv8 版本选择

根据硬件条件选择合适的模型尺寸:

  • YOLOv8n:2.4M 参数,适合嵌入式设备
  • YOLOv8s:11.4M 参数,平衡精度与速度
  • YOLOv8m:26.3M 参数,高精度需求场景

关键训练参数

yolo detect train \
    data=tt100k.yaml \
    model=yolov8s.pt \
    epochs=100 \
    imgsz=640 \
    batch=16 \
    optimizer="AdamW" \
    lr0=0.001

避坑指南

  1. 编码问题:Windows 生成的 UTF-8-BOM 文件会导致 YOLO 读取失败
  2. 解决方案:用 encoding='utf-8-sig' 重新保存文件

  3. 路径问题:建议使用绝对路径或相对于 yaml 文件的路径

  4. 类别不平衡:对小样本类别启用 oversampling

    train: ../datasets/tt100k/train/images
    val: ../datasets/tt100k/val/images
    
    # 过采样配置
    oversample: [10, 15, 8]  # 对第 10、15、8 类过采样

性能验证

在 RTX 3090 上的测试结果:

模型 mAP@0.5 FPS (640×640)
YOLOv8n 0.623 142
YOLOv8s 0.701 98
YOLOv8m 0.734 52

总结

通过本文的流程,我们实现了从多源数据集到 YOLOv8 模型的完整训练链路。实际部署时建议:
1. 使用 TensorRT 加速推理
2. 对交通标志检测任务增加角度预测头
3. 融合多数据集提升泛化能力

完整代码已上传 Colab:实践链接

正文完
 0
评论(没有评论)