BDD100K数据集YOLO格式转换实战:从标注到训练的全流程指南

1次阅读
没有评论

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

image.webp

BDD100K 数据集结构解析

BDD100K 是一个大规模自动驾驶数据集,包含 10 万张图片的标注信息。原始标注采用 JSON 格式存储,每个 JSON 文件对应一个图片的标注信息,主要包括以下字段:

BDD100K 数据集 YOLO 格式转换实战:从标注到训练的全流程指南

  • name: 图片文件名
  • attributes: 图片属性(如天气、场景等)
  • labels: 物体标注列表,每个标注包含:
  • category: 物体类别
  • box2d: 边界框坐标(x1, y1, x2, y2)

与 YOLO 格式相比,主要差异在于:

  1. 坐标表示:BDD100K 使用绝对坐标,YOLO 使用归一化后的相对坐标
  2. 类别表示:BDD100K 使用字符串类别名,YOLO 使用数字 ID
  3. 文件组织:YOLO 要求每个图片对应一个同名的 txt 标注文件

关键技术点解析

1. 坐标转换公式

YOLO 格式要求边界框中心坐标和宽高都归一化到 [0,1] 范围。转换公式如下:

x_center = (x1 + x2) / (2 * image_width)
y_center = (y1 + y2) / (2 * image_height)
width = (x2 - x1) / image_width
height = (y2 - y1) / image_height

2. 类别 ID 映射

BDD100K 有 10 个主要物体类别,我们需要建立到 YOLO 类别 ID 的映射关系:

class_map = {
    'pedestrian': 0,
    'rider': 1,
    'car': 2,
    'truck': 3,
    'bus': 4,
    'train': 5,
    'motorcycle': 6,
    'bicycle': 7,
    'traffic light': 8,
    'traffic sign': 9
}

Python 转换脚本实现

以下是完整的转换脚本,包含异常处理和进度显示:

import json
import os
from tqdm import tqdm

# 配置参数
json_dir = 'bdd100k/labels/'
image_dir = 'bdd100k/images/'
output_dir = 'bdd100k_yolo/'

class_map = {...}  # 上面的类别映射

os.makedirs(output_dir, exist_ok=True)

for json_file in tqdm(os.listdir(json_dir)):
    if not json_file.endswith('.json'):
        continue

    try:
        with open(os.path.join(json_dir, json_file)) as f:
            data = json.load(f)

        # 获取图片尺寸
        img_path = os.path.join(image_dir, data['name'].replace('.json', '.jpg'))
        img_width, img_height = 1280, 720  # BDD100K 固定尺寸

        # 准备 YOLO 格式内容
        yolo_lines = []
        for label in data['labels']:
            if 'box2d' not in label:
                continue

            category = label['category']
            if category not in class_map:
                continue

            box = label['box2d']
            x1, y1, x2, y2 = box['x1'], box['y1'], box['x2'], box['y2']

            # 坐标转换
            x_center = (x1 + x2) / (2 * img_width)
            y_center = (y1 + y2) / (2 * img_height)
            width = (x2 - x1) / img_width
            height = (y2 - y1) / img_height

            yolo_lines.append(f"{class_map[category]} {x_center} {y_center} {width} {height}\n")

        # 写入 YOLO 格式文件
        output_file = os.path.join(output_dir, data['name'].replace('.json', '.txt'))
        with open(output_file, 'w') as f:
            f.writelines(yolo_lines)

    except Exception as e:
        print(f"Error processing {json_file}: {str(e)}")

转换效率优化方案

处理 10 万张图片的标注时,可以考虑以下优化:

  1. 多进程处理:
from multiprocessing import Pool

def process_file(json_file):
    # 上面的处理逻辑
    pass

if __name__ == '__main__':
    json_files = [f for f in os.listdir(json_dir) if f.endswith('.json')]
    with Pool(processes=8) as pool:
        list(tqdm(pool.imap(process_file, json_files), total=len(json_files)))
  1. 内存优化:
  2. 避免一次性加载所有 JSON 文件
  3. 使用生成器逐文件处理
  4. 及时释放不再需要的数据

常见问题排查指南

1. 标注错误处理

  • 检查边界框坐标是否在图片范围内
  • 验证类别名称是否在映射表中
  • 处理空标注文件

2. 格式验证方法

可以使用以下脚本验证转换后的 YOLO 格式:

def validate_yolo_format(txt_file):
    with open(txt_file) as f:
        for line in f:
            parts = line.strip().split()
            if len(parts) != 5:
                return False
            try:
                class_id = int(parts[0])
                coords = list(map(float, parts[1:]))
                if not all(0 <= x <= 1 for x in coords):
                    return False
            except ValueError:
                return False
    return True

数据集质量检查与训练验证

1. 质量检查

  • 使用可视化工具检查标注是否正确叠加在图片上
  • 统计各类别的分布情况
  • 检查标注覆盖率

2. YOLOv5 训练验证

  1. 准备 YOLO 格式的数据集目录结构:
dataset/
├── images/
│   ├── train/
│   └── val/
└── labels/
    ├── train/
    └── val/
  1. 创建 dataset.yaml 配置文件:
train: dataset/images/train/
val: dataset/images/val/

nc: 10
names: ['pedestrian', 'rider', 'car', 'truck', 'bus', 'train', 'motorcycle', 'bicycle', 'traffic light', 'traffic sign']
  1. 启动训练:
python train.py --img 640 --batch 16 --epochs 50 --data dataset.yaml --weights yolov5s.pt

总结

通过本文的详细指导,你应该已经掌握了将 BDD100K 数据集转换为 YOLO 格式的完整流程。这个过程虽然有些繁琐,但是理解其中的原理和实现方法后,可以轻松应对其他类似数据集的格式转换需求。在实践中如果遇到问题,可以参考我们提供的排查指南,或者查阅 YOLO 官方文档获取更多帮助。

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