BDD100K数据集全解析:从入门到实战的计算机视觉指南

1次阅读
没有评论

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

image.webp

一、BDD100K 数据集背景与价值

BDD100K 是由加州大学伯克利分校发布的自动驾驶领域大规模数据集,包含 10 万张高清行车视频帧(1280×720 分辨率),覆盖不同天气(晴天 / 雨天 / 雪天)、时段(白天 / 夜间)和驾驶场景(城市 / 高速 / 乡村)。其标注体系包含:

BDD100K 数据集全解析:从入门到实战的计算机视觉指南

  • 目标检测(100k 图像,8 类物体)
  • 语义分割(10k 图像,19 类标签)
  • 车道线检测(100k 图像)
  • 可驾驶区域分割(10k 图像)

该数据集因场景多样性和标注完整性,成为自动驾驶算法研发的基准测试集,在 CVPR、ICCV 等顶会论文中频繁出现。

二、数据集结构深度解析

解压后的目录结构如下:

bdd100k/
├── images/               # 原始图像
│   ├── train/           # 训练集(70k)│   ├── val/             # 验证集(10k)│   └── test/            # 测试集(20k)└── labels/              # JSON 标注文件
    ├── train.json
    └── val.json

标注文件采用 COCO 风格 JSON 格式,关键字段说明:

{
  "name": "b1c66a42-6f7d68ca.jpg",
  "attributes": {
    "weather": "rainy",  # 天气标签
    "scene": "highway",  # 场景标签
    "timeofday": "day"   # 时间段
  },
  "labels": [
    {
      "category": "car",
      "box2d": {"x1": 712.4, "y1": 521.3, "x2": 810.2, "y2": 562.7},
      "occluded": false  # 是否被遮挡
    }
  ]
}

三、PyTorch 数据加载实战

1. 自定义 Dataset 实现

import torch
from torch.utils.data import Dataset
import json
from PIL import Image

class BDD100KDataset(Dataset):
    def __init__(self, image_dir, label_path, transform=None):
        self.image_dir = image_dir
        with open(label_path) as f:
            self.labels = json.load(f)
        self.transform = transform
        # 类别 ID 映射(示例)self.class_map = {"car":0, "person":1, "traffic light":2}

    def __len__(self):
        return len(self.labels)

    def __getitem__(self, idx):
        label_info = self.labels[idx]
        img_path = os.path.join(self.image_dir, label_info["name"])
        image = Image.open(img_path).convert("RGB")

        # 解析标注
        boxes, classes = [], []
        for obj in label_info["labels"]:
            if "box2d" in obj:  # 只处理目标检测标注
                box = [obj["box2d"]["x1"], obj["box2d"]["y1"], 
                       obj["box2d"]["x2"], obj["box2d"]["y2"]]
                boxes.append(box)
                classes.append(self.class_map[obj["category"]])

        # 转换为 Tensor
        boxes = torch.tensor(boxes, dtype=torch.float32)
        classes = torch.tensor(classes, dtype=torch.int64)

        if self.transform:
            image = self.transform(image)

        return image, {"boxes": boxes, "labels": classes}

2. 数据增强策略

推荐使用 Albumentations 库处理目标检测任务:

import albumentations as A

train_transform = A.Compose([A.HorizontalFlip(p=0.5),
    A.RandomBrightnessContrast(p=0.2),
    A.Resize(height=640, width=960),  # 适当降低分辨率
    A.Normalize(mean=(0.485, 0.456, 0.406), std=(0.229, 0.224, 0.225))
], bbox_params=A.BboxParams(format="pascal_voc", label_fields=["class_labels"]))

四、YOLOv3 训练示例

1. 模型适配

修改 YOLO 的 anchor 配置(BDD100K 目标尺寸统计):

# 在 config/yolov3.cfg 中调整 anchors
[anchors]
10,13,  16,30,  33,23    # 小目标
30,61,  62,45,  59,119   # 中目标
116,90, 156,198, 373,326 # 大目标

2. 训练循环关键代码

dataset = BDD100KDataset("bdd100k/images/train", "bdd100k/labels/train.json")
dataloader = DataLoader(dataset, batch_size=16, shuffle=True, collate_fn=collate_fn)

for epoch in range(50):
    for imgs, targets in dataloader:
        imgs = imgs.to(device)
        # 转换 target 格式为 YOLO 所需
        yolo_targets = convert_to_yolo_format(targets)

        optimizer.zero_grad()
        loss = model(imgs, yolo_targets)
        loss.backward()
        optimizer.step()

五、避坑指南

1. 标注问题处理

  • 错误标注识别:使用可视化工具检查(如 labelImg)

    def show_annotations(image, boxes):
        plt.imshow(image)
        ax = plt.gca()
        for box in boxes:
            rect = patches.Rectangle((box[0],box[1]), box[2]-box[0], box[3]-box[1],
                                   linewidth=2, edgecolor='r', facecolor='none')
            ax.add_patch(rect)

  • 常见问题

  • 部分遮挡物体标注不完整(需手动补全)
  • 远处小物体漏标(建议过滤像素面积 <20 的框)

2. 内存优化技巧

  • 分块加载 :使用torch.utils.data.Subset 分割大数据集
  • 延迟加载 :在__getitem__ 中读取图像而非__init__
  • 梯度累积:小 batch 训练时设置accumulation_steps

3. 多 GPU 训练策略

# 使用 DistributedDataParallel
model = torch.nn.parallel.DistributedDataParallel(
    model, 
    device_ids=[local_rank], 
    output_device=local_rank
)
# 数据分片
sampler = torch.utils.data.distributed.DistributedSampler(dataset)
dataloader = DataLoader(dataset, sampler=sampler)

六、进阶思考

  1. 如何利用 BDD100K 的场景属性(天气 / 时间段)提升模型鲁棒性?
  2. 对比 COCO 格式,BDD100K 的 JSON 标注设计有哪些优缺点?
  3. 当处理 4K 分辨率图像时,如何优化检测模型的计算效率?

实验环境复现

pip install torch==1.12.0+cu113 torchvision==0.13.0+cu113
pip install albumentations opencv-python matplotlib
# 推荐使用 RTX 3060 及以上显卡

通过本文的实践,你应该能够快速搭建基于 BDD100K 的目标检测 Pipeline。建议先从验证集抽取 1000 张样本快速验证流程,再扩展到全量数据训练。

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