4、经典数据集详解:Cityscapes、KITTI、BDD100K,数据标注格式与特点

做语义分割,尤其是道路场景理解,数据集就是你的“弹药库”。

我见过不少新手,模型结构搭得挺漂亮,结果在数据集上翻了车——要么标注格式搞错,要么类别对不上,白白浪费几天时间。今天咱们就把三个最经典的数据集掰开揉碎了讲清楚。

4.1 Cityscapes:城市道路场景的“标杆”

Cityscapes 是我个人用得最多的数据集,没有之一。它专注于城市街道场景,覆盖了 50 个不同城市,包含 5000 张精细标注的图像和 20000 张粗略标注的图像。

核心特点:

  • 分辨率高:图像尺寸为 2048×1024,细节非常丰富。我在做小目标检测(比如远处的交通灯)时,Cityscapes 的高分辨率帮了大忙。
  • 类别精细:定义了 30 个类别,但通常只用其中的 19 个进行训练和评估。这 19 类涵盖了道路、车辆、行人、建筑等关键元素。
  • 标注质量:每张图都经过人工精细标注,边缘贴合度极高。说白了,这是“教科书级”的标注。
避坑指南:Cityscapes 的标注是 trainIdid 两套体系。id 是原始类别编号(0~33),trainId 才是训练时用的(0~18,255 表示忽略区域)。我曾经直接拿 id 去训练,结果模型把“道路”和“人行道”搞混了,因为它们的 id 是连续的。

标注格式:

Cityscapes 使用 JSON 格式的标注文件,但语义分割任务通常直接使用 PNG 图像作为标签。每个像素的值就是类别 ID。

# Cityscapes 标签图像示例
# 像素值 0 表示道路,1 表示人行道,2 表示建筑...
# 注意:训练时通常使用 trainId,而不是 id

# 读取标签图像
import cv2
label = cv2.imread('gtFine_trainvaltest/leftImg8bit/train/aachen/aachen_000000_000019_gtFine_labelIds.png', cv2.IMREAD_GRAYSCALE)
print(np.unique(label))  # 输出: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 255]
我的习惯:写一个 cityscapes_utils.py 工具脚本,专门处理 idtrainId 的映射。这样不管数据集怎么变,我都能快速适配。

4.2 KITTI:自动驾驶的“老前辈”

KITTI 数据集诞生于 2012 年,由德国卡尔斯鲁厄理工学院和丰田美国研究院联合创建。它虽然年头久,但在道路场景理解领域依然是绕不开的基准。

核心特点:

  • 多模态:包含双目图像、激光雷达点云、GPS/IMU 数据。如果你做多传感器融合,KITTI 是首选。
  • 场景真实:数据采集于卡尔斯鲁厄市区、乡村和高速公路,包含晴天、阴天、傍晚等多种光照条件。
  • 标注稀疏:语义分割标注只有 200 张训练图和 200 张测试图。嗯,数量确实少,但每张图的质量很高。
注意:KITTI 的语义分割标注只覆盖了 11 个类别(道路、人行道、汽车、行人、自行车等),而且没有“建筑”这个类别。如果你需要识别建筑物,Cityscapes 会更合适。

标注格式:

KITTI 使用 PNG 图像作为标签,但它的像素值编码方式与 Cityscapes 不同。KITTI 的标签图像是 彩色图像,每个像素的 RGB 值对应一个类别。

# KITTI 标签图像示例
# 颜色编码示例:
# (128, 64, 128) -> 道路
# (244, 35, 232) -> 人行道
# (0, 0, 142)    -> 汽车

# 读取标签图像
label = cv2.imread('training/semantic_rgb/000000_10.png')
# 需要将 RGB 值映射到类别 ID
color_to_class = {
    (128, 64, 128): 0,  # 道路
    (244, 35, 232): 1,  # 人行道
    (0, 0, 142): 2,     # 汽车
    # ... 其他类别
}
避坑指南:KITTI 的标签图像中,有些像素的 RGB 值不在预定义的颜色映射表中。这些像素通常属于“忽略区域”(比如远处的物体)。我在处理时,会把这些像素统一设为 255(忽略类别)。

4.3 BDD100K:大规模、多样化的“后起之秀”

BDD100K 是伯克利大学在 2018 年发布的数据集,包含 10 万张图像,覆盖了美国多个城市的不同天气、时间和场景。它最大的优势就是——

核心特点:

  • 规模大:10 万张图像,其中 7 万张用于训练,1 万张用于验证,2 万张用于测试。相比 Cityscapes 的 5000 张,BDD100K 的规模是它的 20 倍。
  • 多样性高:包含晴天、阴天、雨天、雪天、雾天,以及白天、夜晚、黄昏等多种条件。你想想看,一个模型如果在 BDD100K 上表现好,那它在真实场景中的泛化能力大概率不会差。
  • 多任务标注:除了语义分割,还包含目标检测、车道线检测、实例分割、全景分割等标注。一个数据集搞定多个任务。
我的经验:BDD100K 的语义分割标注有 19 个类别,与 Cityscapes 的 19 类高度重合。所以,我经常先在 Cityscapes 上预训练模型,然后在 BDD100K 上微调。这样既能利用 Cityscapes 的高质量标注,又能享受 BDD100K 的大规模多样性。

标注格式:

BDD100K 使用 JSON 格式存储标注信息,但语义分割标签也提供了 PNG 图像格式。它的标签图像是灰度图,像素值直接对应类别 ID。

# BDD100K 标签图像示例
# 像素值 0 表示道路,1 表示人行道,2 表示建筑...
# 与 Cityscapes 的 trainId 几乎一致

# 读取标签图像
label = cv2.imread('bdd100k/labels/sem_seg/train/0000f77c-6257be58.png', cv2.IMREAD_GRAYSCALE)
print(np.unique(label))  # 输出: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 255]
注意:BDD100K 的 JSON 标注文件中,语义分割的标注是以 polygon(多边形)形式存储的。如果你需要从 JSON 生成 PNG 标签图像,需要自己写一个渲染函数。我个人建议直接下载官方提供的 PNG 标签文件,省时省力。

4.4 三个数据集的对比总结

特性 Cityscapes KITTI BDD100K
发布年份 2016 2012 2018
图像数量 5000(精细)+ 20000(粗略) 400(语义分割) 100000
图像分辨率 2048×1024 1242×375 1280×720
类别数 19(常用) 11 19
标注格式 PNG(灰度图,trainId) PNG(彩色图,RGB映射) PNG(灰度图,类别ID)
场景多样性 中等(城市街道) 低(德国城市) 高(美国多城市、多天气)
多模态支持 有(双目、激光雷达)
我的建议:
  • 如果你刚入门,从 Cityscapes 开始。标注质量高,社区资源丰富,踩坑少。
  • 如果你做多传感器融合或目标跟踪,KITTI 是绕不开的。
  • 如果你追求模型的泛化能力,BDD100K 的大规模多样性会让你受益匪浅。

好了,三个数据集的核心内容就这些。记住,数据集的选择取决于你的具体任务和资源。没有最好的数据集,只有最合适的。