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

数据集结构解析
解压后的 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
避坑指南
- 忽略标注 ID 映射
- 问题:直接使用原始标签 ID 会导致类别不连续(如 0 -33 有缺失值)
-
解决:使用官方提供的
trainId映射(见labels.py) -
图像尺寸不一致
- 问题:不同来源的预处理代码可能改变原始分辨率(2048×1024)
-
解决:保持评估时与训练时尺寸一致
-
错误处理实例标签
- 问题:将
instanceIds.png直接当作语义标签使用 -
解决:明确区分
labelIds.png(语义)和instanceIds.png(实例) -
内存不足
- 问题:直接加载全分辨率图像导致显存溢出
-
解决:使用随机裁剪或降低分辨率(如 1024×512)
-
忽略 ignore_label
- 问题:训练时未过滤 ID 为 0 的忽略区域
- 解决:在损失函数中设置
ignore_index=0
数据增强策略
推荐组合增强方式:
- 基础增强:
- 随机水平翻转(p=0.5)
- 随机缩放(0.5-2.0 倍)
-
随机裁剪(固定尺寸如 768×768)
-
高级增强:
- 颜色抖动(亮度、对比度、饱和度)
- 高斯模糊
-
随机遮挡(模拟树木遮挡等)
-
注意事项:
- 增强时保持图像与标签同步变换
- 避免过度增强导致语义失真
进阶思考
- 如何利用
polygons.json实现更精确的分割边界? - 在多任务学习框架中,如何同时利用语义和实例标注?
- 针对自动驾驶实时性要求,如何优化 Cityscapes 模型的计算效率?
结语
掌握 Cityscapes 数据集的使用是进入自动驾驶计算机视觉领域的重要一步。本文从实际项目经验出发,梳理了从数据加载到训练的关键流程,特别强调了新手容易忽略的细节问题。建议读者运行示例代码后,进一步尝试在自己的项目中应用这些技巧,并探索数据集的更多可能性。
