资讯详情

资讯详情

Cityscapes数据集详解:自动驾驶语义分割的工业级标尺

简介本资源为Cityscapes数据集的精细标注子集第一部分面向计算机视觉方向的研究者、深度学习工程师及自动驾驶算法学习者聚焦像素级语义分割任务支撑模型训练、泛化能力验证与IoU等核心指标评估。压缩包含2000个JSON格式文件均为gtFine_polygons类型即基于多边形标注的高精度真值标签涵盖道路、车辆、行人等30类城市场景对象可直接用于U-Net、DeepLab等分割网络的数据加载与监督训练。资源大小730.44MB结构精简、无图像冗余适配快速下载与本地标注解析需求。目前已有2144人学习下载读者可直接获取欧洲30城街景的标准化精细标注样本结合官方训练/验证/测试划分逻辑开展数据预处理、标签映射、损失函数调试及分割结果可视化等全流程实践是构建鲁棒城市理解模型的关键基础组件。1. Cityscapes 数据集一不是“又一个街景图库”而是自动驾驶感知模块落地前必须啃透的硬标尺你手头刚跑通一个语义分割模型在自制小数据集上 IoU 轻松破 85%信心满满切到真实道路场景——结果在交叉口区域漏检三辆自行车、把施工锥桶识别成“road”、雨天反光路面直接崩出大片噪声。这不是模型不行大概率是你还没真正和 Cityscapes 打过照面。它不是公开数据集中最“大”的那个但却是工业界公认的城市道路场景感知能力校准基线50 类精细标注含 19 类主类别31 类细粒度子类、2975 张高质量全帧精细标注图 20000 张粗略标注图、严格按驾驶视角采集前视双目GPSIMU同步、所有图像均经人工逐像素校验。它不解决“能不能训出来”的问题专治“训出来后敢不敢上车”的焦虑。适合正在做 ADAS 模块验证、车载视觉算法鲁棒性压测、或准备投稿 CVPR/ICCV 目标检测/分割方向论文的工程师与研究生——尤其当你发现自己的模型在 BDD100K 上表现尚可但在 Cityscapes val set 上掉点超过 3.5% 时这份数据集就是你该打开的第一份“诊断报告”。2. 数据结构解剖从 raw 文件夹到 gtFine 的三层嵌套逻辑Cityscapes 的目录设计不是随意堆叠而是按“采集原始性→标注精细度→任务适配性”三级分层。理解这三层才能避免后续加载时反复解压、重命名、路径报错。2.1 第一层raw —— 原始传感器数据的“时间胶囊”leftImg8bit/下存放的是未经任何处理的 8-bit 彩色图像分辨率统一为2048×1024注意不是常见的 1920×1080采用cityscapes/leftImg8bit/train/aachen/aachen_000000_000019_leftImg8bit.png这种四级路径结构。关键点在于train/val/test三目录严格物理隔离test 集无标注仅用于官方服务器评测aachen/bochum/...是采集城市名共 50 个每个城市下图像按xxx_yyy_zzz编号其中xxx为序列 IDyyy为帧序号zzz为采集设备标识所有图像均为 JPEG 格式但色域为 sRGB非 Adobe RGB若用 OpenCV 读取后直接送入训练需确认cv2.cvtColor(img, cv2.COLOR_BGR2RGB)后是否触发 gamma 校正实测多数框架默认忽略建议显式转为 float32 并除以 255.0。提示不要试图用glob.glob(leftImg8bit/**/*png)一次性扫全路径——Cityscapes 官方脚本强制要求路径必须含城市名一级目录否则csHelpers.py会抛KeyError: city。这是第一处隐性约束。2.2 第二层gtFine —— 精细标注的“黄金标准”来源gtFine/是核心标注目录结构与leftImg8bit/完全镜像gtFine/train/aachen/aachen_000000_000019_gtFine_labelIds.png。这里藏着三个关键文件labelIds.png单通道 uint8 图像像素值 0~33 对应 34 个语义类别含unlabeled0,ego vehicle1,rectification border2等特殊类这是训练分割模型的直接标签instanceIds.png单通道 uint16 图像编码格式为class_id * 1000 instance_id用于实例分割任务如区分同一类别的不同车辆color.png三通道 RGB 可视化图仅用于调试不可用于训练因含抗锯齿伪影且部分颜色映射非一一对应。import numpy as np from PIL import Image # 正确加载 labelIds.png 的方式 label_path gtFine/train/aachen/aachen_000000_000019_gtFine_labelIds.png label np.array(Image.open(label_path), dtypenp.uint8) # 必须指定 dtypePIL 默认 int32 print(Unique labels:, np.unique(label)) # 输出应为 [0 1 2 ... 33]代码说明np.array(Image.open(...))若不指定dtypePIL 会返回 int32 数组导致后续torch.nn.CrossEntropyLoss输入维度报错期望 long 类型。这是新手高频翻车点——看似加载成功实则数据类型已污染。2.3 第三层gtCoarse —— 大规模预训练的“燃料补给站”gtCoarse/存放 20000 张粗略标注图由众包平台完成精度约 70%官方评估。其价值不在最终评测而在冷启动阶段的数据增广与leftImg8bit/中的train_extra/目录配对注意train_extra不在leftImg8bit/train/下而是平级目录标注格式同gtFine但文件名后缀为_gtCoarse_labelIds.png实践中我通常将gtCoarse与gtFine的train集合并按 8:2 划分训练/验证集再用gtFine/val作为独立测试集——这样既保证验证集纯净又让模型早期见过更多城市变体。3. 标签体系深度解析为什么 19 类主类 31 类细类是工业落地的刚需Cityscapes 的标签设计远超学术竞赛的“19 类分割”表象。它的labelTrainIds.png位于gtFine/同级目录才是工程部署的真相入口。3.1 从 34 类原始标签到 19 类训练标签的映射逻辑原始labelIds.png含 34 类但其中out of roi1,static3,dynamic4,ground5等 15 类被归为ignore值设为 255仅保留 19 类有效类别参与 loss 计算。这个映射由csLabelTools.py中的create_trainId_to_evalId_mapping()函数定义。关键参数如下原始 labelId类别名trainId是否参与训练说明0unlabeled255否全图背景强制 ignore1ego vehicle255否自车部件遮挡区域7road0是主干道8sidewalk1是人行道24person11是行人含骑车人26rider12是骑行者单车/摩托注意rider与person分离是 Cityscapes 的核心设计——在高速路口骑行者行为模式与行人截然不同混为一类会导致模型在预测“是否需紧急制动”时误判。这是它区别于 COCO 或 Pascal VOC 的本质差异。3.2 细粒度子类31 类如何支撑功能安全验证gtFine/中的labelIds.png实际包含 31 个细粒度子类如car,truck,bus,train,motorcycle,bicycle它们全部映射到trainId13即vehicle大类。但当你做 ASAMAutomotive Safety Analysis Methodology合规验证时必须能回答“模型对卡车的召回率是否显著低于轿车”。此时需启用子类统计# 加载子类标签需额外下载 gtFine_polygons.json import json with open(gtFine/train/aachen/aachen_000000_000019_gtFine_polygons.json) as f: data json.load(f) for obj in data[objects]: if obj[label] truck: print(Truck polygon points:, obj[polygon][:3]) # 输出前3个顶点坐标代码说明polygons.json提供矢量级标注比labelIds.png的栅格标注精度高一个数量级适用于 ISO 21448 SOTIF 场景分析——例如验证模型在“卡车侧方盲区”区域的响应一致性。3.3 城市风格迁移的隐藏线索光照/天气/季节标签Cityscapes 官方未提供元数据 CSV但通过解析文件名可提取强相关特征aachen_000000_000019中000000为序列 ID同一序列内图像采集时间间隔 2s可视为同场景连续帧所有train集图像采集于2015–2016 年春季/夏季val集含少量秋季图像树叶变色test集含冬季雪景需单独下载leftImg8bit_testextra.zip关键技巧用exiftool读取 JPEG EXIF可获取拍摄时间戳DateTimeOriginal与 GPS 坐标GPSLatitude/GPSLongitude结合 OpenStreetMap API 反查该位置当日天气晴/多云/小雨构建光照条件标签。4. 避坑指南五个让模型训练突然崩溃的真实现场这些坑我都在某高校自动驾驶实验室的实车项目里踩过血泪经验总结如下4.1 现象PyTorch DataLoader 报OSError: Too many open files进程卡死原因Cityscapes 单个train目录含 2975 张图若num_workers 4且未设置ulimit -n 8192Linux 默认文件句柄数1024被迅速耗尽。解决在训练脚本开头插入import resource; resource.setrlimit(resource.RLIMIT_NOFILE, (8192, 8192))或在 shell 中执行ulimit -n 8192后再运行。4.2 现象模型在val集上 mIoU 突然跳变 ±5%但train损失曲线平滑原因gtFine/val/中部分城市的图像存在labelIds.png与leftImg8bit/val/尺寸不匹配如2048x1024vs2047x1023OpenCV 读取后自动 padding 导致标签偏移。解决加载时强制校验尺寸img cv2.imread(img_path) label cv2.imread(label_path, cv2.IMREAD_UNCHANGED) assert img.shape[:2] label.shape, fSize mismatch: {img.shape} vs {label.shape}4.3 现象使用cv2.resize()对标签图下采样后验证指标暴跌原因cv2.resize(label, (512,256), interpolationcv2.INTER_NEAREST)中INTER_NEAREST是唯一正确插值方式若误用INTER_LINEAR会产生非法中间值如 7.3torch.nn.CrossEntropyLoss报IndexError。解决永远用cv2.INTER_NEAREST处理标签图且 resize 后需label np.clip(label, 0, 19)二次校验。4.4 现象gtCoarse数据加载后unique labels出现 35 值原因gtCoarse/中部分图像由不同众包团队标注存在trainId映射不一致如某团队将wall标为 18另一团队标为 19。解决弃用gtCoarse/labelIds.png改用官方提供的gtCoarse/train_extra/..._gtCoarse_labelTrainIds.png已统一映射。4.5 现象模型在test集提交后car类召回率 99.2%但rider类仅 83.7%原因test集中rider样本量仅占train集的 1/12且多为小目标 32×32 像素而你的数据增强未启用RandomResizedCrop(scale(0.5, 2.0))。解决对rider类样本单独加权采样并在transforms中加入albumentations.RandomScale(scale_limit0.5, p0.7)。5. 验证 pipeline 构建用 Cityscapes val 集做一次完整的模型健康体检拿到一个新模型别急着跑 test server先用val集做四层穿透式验证。这套流程我在某公司 L2 系统交付前强制执行曾提前两周发现一个traffic light类在黄昏场景下的系统性漏检。5.1 第一层基础指标验证5 分钟用官方cityscapesScripts/evaluation/evalPixelLevelSemanticLabeling.py脚本生成results.json重点盯三个指标road类 IoU ≥ 98.5%若 97%检查是否误将sidewalk当roadperson类 Recall ≥ 92%若 90%检查ignore区域是否过大rider类 Precision ≥ 85%若 80%检查 NMS 阈值是否过高。提示evalPixelLevelSemanticLabeling.py默认输出confusion matrix但实际只需关注per class results表格中的IoU列。其他列如acc因ignore类占比高而失真。5.2 第二层场景切片分析15 分钟将val集按city和time-of-day切片用自定义脚本统计各 slice 的person类 F1-score# city_time_slice.py import pandas as pd from pathlib import Path slices { aachen_day: [aachen_.*_day.*], jena_dusk: [jena_.*_dusk.*], zurich_night: [zurich_.*_night.*] } results {} for slice_name, patterns in slices.items(): # 用正则匹配对应图像 matched [p for p in val_img_paths if any(re.match(pat, p.name) for pat in patterns)] # 计算该 slice 的 F1 results[slice_name] compute_f1(model, matched) pd.DataFrame(results).to_csv(slice_f1.csv)若zurich_night的riderF1 比aachen_day低 12%说明模型缺乏低光照泛化能力需引入LowLightAugmentation。5.3 第三层错误模式聚类30 分钟对val集所有person类误检样本提取其labelIds.png中的误分类像素坐标用 DBSCAN 聚类若聚类中心集中在图像底部 10% 区域 → 检查ego vehicle掩膜是否未正确应用若聚类呈水平条带状y 坐标集中→ 检查resize是否导致标签压缩变形若聚类点与traffic sign边界重合 → 模型存在上下文混淆需增加BoundaryAwareLoss。5.4 第四层对抗样本压力测试20 分钟用foolbox库生成FGSM对抗样本攻击目标设为person类import foolbox as fb fmodel fb.PyTorchModel(model, bounds(0, 1)) attack fb.attacks.LinfFastGradientAttack() epsilons [0.001, 0.01, 0.03] raw, clipped, is_adv attack(fmodel, images, labels, epsilonsepsilons) # 统计各 epsilon 下 person 类置信度下降率若epsilon0.01时person类平均置信度下降 40%说明模型对微小扰动敏感需在训练中加入AdversarialTraining。从那以后我每次交付新模型前都强制走一遍这四层验证——哪怕客户只要求一个 mIoU 数字。因为 Cityscapes val 集不是终点而是你模型能否走出实验室、真正面对城市街道的第一道安检门。希望帮到你。本文还有配套的精品资源点击获取
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →