Cityscapes数据集详解:从入门到实战的避坑指南

1次阅读
没有评论

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

image.webp

背景与重要性

Cityscapes 是自动驾驶和计算机视觉领域广泛使用的街景图像数据集,包含 50 个城市在不同季节和天气条件下采集的 5000 张精细标注图像(另有 20000 张粗标注图像)。其标注涵盖 30 个类别(如道路、车辆、行人等),支持语义分割、实例分割和全景分割任务。作为 ECCV 和 CVPR 等顶会的常用基准数据集,掌握其使用方法对研究者和开发者至关重要。

Cityscapes 数据集详解:从入门到实战的避坑指南

数据集结构解析

解压后的 Cityscapes 目录结构如下(以官方提供的 leftImg8bit_trainvaltest.zip 和gtFine_trainvaltest.zip为例):

cityscapes/
├── leftImg8bit/
│   ├── train/
│   │   ├── aachen/
│   │   │   ├── aachen_000000_000019_leftImg8bit.png
│   │   │   └── ...
│   ├── val/
│   └── test/
└── gtFine/
    ├── train/
    │   ├── aachen/
    │   │   ├── aachen_000000_000019_gtFine_instanceIds.png
    │   │   ├── aachen_000000_000019_gtFine_labelIds.png
    │   │   ├── aachen_000000_000019_gtFine_polygons.json
    │   │   └── ...
    ├── val/
    └── test/

关键文件夹说明:

  • leftImg8bit: 存储原始街景图像(分辨率 2048×1024)
  • gtFine: 精细标注文件,包含:
  • *_labelIds.png: 语义分割标签(每个像素值为类别 ID)
  • *_instanceIds.png: 实例分割标签(相同实例共享唯一 ID)
  • *_polygons.json: 多边形标注元数据

标注格式详解

1. 语义分割(PNG 格式)

labelIds.png使用单通道 PNG,像素值对应 cityscapesscripts/helpers/labels.py 中定义的类别 ID。例如:

  • 0: 忽略区域
  • 7: 道路
  • 24: 人

2. 实例分割(PNG 格式)

instanceIds.png的像素值编码规则:ID = 1000 * 类别 ID + 实例编号。例如:

  • 24001: 第 1 个人实例
  • 24002: 第 2 个人实例

3. JSON 标注结构

polygons.json包含每个对象的精确多边形边界和属性,典型结构如下:

{
  "objects": [
    {
      "label": "car",
      "polygon": [[x1,y1], [x2,y2], ...],
      "id": 26001
    }
  ]
}

数据加载实战

使用 PyTorch 加载示例

import os
import cv2
import torch
from torch.utils.data import Dataset

class CityscapesDataset(Dataset):
    def __init__(self, root, split='train', target_type='semantic'):
        self.images_dir = os.path.join(root, 'leftImg8bit', split)
        self.targets_dir = os.path.join(root, 'gtFine', split)
        self.target_type = target_type
        self.samples = []

        # 遍历所有城市文件夹
        for city in os.listdir(self.images_dir):
            city_img_dir = os.path.join(self.images_dir, city)
            for img_name in os.listdir(city_img_dir):
                if img_name.endswith('_leftImg8bit.png'):
                    base_name = img_name.replace('_leftImg8bit.png', '')
                    self.samples.append((os.path.join(city_img_dir, img_name),
                        os.path.join(self.targets_dir, city, 
                                    f"{base_name}_gtFine_labelIds.png")
                    ))

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

    def __getitem__(self, idx):
        img_path, label_path = self.samples[idx]

        # 加载图像(OpenCV 默认 BGR 格式)image = cv2.imread(img_path)
        image = cv2.cvtColor(image, cv2.COLOR_BGR2RGB)  # 转为 RGB

        # 加载语义标签
        label = cv2.imread(label_path, cv2.IMREAD_UNCHANGED)

        # 转换为 PyTorch 张量并归一化
        image = torch.from_numpy(image).permute(2, 0, 1).float() / 255.0
        label = torch.from_numpy(label).long()

        return image, label

避坑指南

  1. 忽略标注 ID 映射
  2. 问题:直接使用原始标签 ID 会导致类别不连续(如 0 -33 有缺失值)
  3. 解决:使用官方提供的 trainId 映射(见labels.py)

  4. 图像尺寸不一致

  5. 问题:不同来源的预处理代码可能改变原始分辨率(2048×1024)
  6. 解决:保持评估时与训练时尺寸一致

  7. 错误处理实例标签

  8. 问题:将 instanceIds.png 直接当作语义标签使用
  9. 解决:明确区分labelIds.png(语义)和instanceIds.png(实例)

  10. 内存不足

  11. 问题:直接加载全分辨率图像导致显存溢出
  12. 解决:使用随机裁剪或降低分辨率(如 1024×512)

  13. 忽略 ignore_label

  14. 问题:训练时未过滤 ID 为 0 的忽略区域
  15. 解决:在损失函数中设置ignore_index=0

数据增强策略

推荐组合增强方式:

  1. 基础增强:
  2. 随机水平翻转(p=0.5)
  3. 随机缩放(0.5-2.0 倍)
  4. 随机裁剪(固定尺寸如 768×768)

  5. 高级增强:

  6. 颜色抖动(亮度、对比度、饱和度)
  7. 高斯模糊
  8. 随机遮挡(模拟树木遮挡等)

  9. 注意事项:

  10. 增强时保持图像与标签同步变换
  11. 避免过度增强导致语义失真

进阶思考

  1. 如何利用 polygons.json 实现更精确的分割边界?
  2. 在多任务学习框架中,如何同时利用语义和实例标注?
  3. 针对自动驾驶实时性要求,如何优化 Cityscapes 模型的计算效率?

结语

掌握 Cityscapes 数据集的使用是进入自动驾驶计算机视觉领域的重要一步。本文从实际项目经验出发,梳理了从数据加载到训练的关键流程,特别强调了新手容易忽略的细节问题。建议读者运行示例代码后,进一步尝试在自己的项目中应用这些技巧,并探索数据集的更多可能性。

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