news 2026/9/6 2:28:49

Cityscapes 数据集全解析:从下载到标注,语义分割与自动驾驶视觉的实战指南

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Cityscapes 数据集全解析:从下载到标注,语义分割与自动驾驶视觉的实战指南

简介:Cityscapes 数据集的 gtFine 子集标注文件,是面向城市街景语义分割任务的核心数据资源。这套压缩包内含 2000 个 JSON 文件,整体约 730MB,每个文件保存一张高分辨率街景图像的精细多边形标注,覆盖道路、建筑、行人、车辆等 30 个类别,可供研究者直接用于训练 FCN、U-Net、DeepLab 等分割网络,或结合原始 RGB 图进行数据增强与预处理。由于标注精度达到像素级、且来自多个欧洲城市的不同天气与时段,它在自动驾驶、智能交通等场景中具有很强的实用价值,能够有效验证模型在真实复杂城市环境下的泛化能力。已有 2130 人学习/下载,适合计算机视觉、深度学习领域的学生与工程师使用,可省去大量人工标注成本,专注开展模型设计与调优。配合其他分卷还可构建完整训练流程,支撑城市级场景理解与无人驾驶技术研究。 做语义分割和自动驾驶视觉这块的人,几乎绕不开 Cityscapes 这个数据集。不管是发论文刷榜单,还是做工业级感知模型的评估基准,Cityscapes 都是默认的“第一站”。我最初接触这个数据集是在做车道线检测和可行驶区域分割时,当时为了把数据下载下来并且正确解析标注文件,折腾了不少时间。这篇就把 Cityscapes 数据集本身讲透,包括它的任务定义、目录结构、标注体系,以及实际操作中容易踩的坑,给后面要上手的朋友一个完整的参考。

1. 项目背景与核心价值

1.1 Cityscapes 是做什么的

Cityscapes 是一个面向城市街道场景理解的图像数据集,由奔驰实验室联合多个学术机构在 2016 年发布,CVPR 上那篇论文《The Cityscapes Dataset for Semantic Urban Scene Understanding》是它的官方出处。数据集采集了德国和法国多个城市的街道影像,涵盖 50 个不同城市的白天、良好天气条件下的驾驶场景,一共包含 5000 张精细标注图像和 20000 张粗糙标注图像。

从任务角度来看,Cityscapes 主要支持三类视觉任务:

  • 语义分割:把图像中每个像素分类到预定义的类别,比如道路、人行道、建筑、车辆、行人等。这是 Cityscapes 最核心的任务,也是绝大多数人使用它的目的。
  • 实例分割:在语义分割的基础上区分同一类别的不同个体,比如两辆相邻的汽车要分为 car 1 和 car 2。Cityscapes 对车辆、行人、自行车等类别提供了实例级标注。
  • 全景分割:将语义分割和实例分割统一起来,既要给每个像素语义标签,又要区分可数物体的个体。Cityscapes 的标注结构天然支持全景分割任务。

所以,不管你是研究语义分割、实例分割还是全景分割,Cityscapes 都是一个绕不开的标准数据集。

1.2 为什么它这么重要

Cityscapes 之所以能成为行业标准,原因有三点。

第一是数据质量高。图像分辨率达到 2048x1024,远高于当时其他数据集(比如 CamVid 只有 960x720),标注精细到像素级多边形轮廓,而不是简单的矩形框。这意味着模型能学到更精细的边界信息。

第二是场景复杂度高。Cityscapes 采集的真实道路画面包含大量挑战性元素——行人遮挡、车辆密集、建筑阴影、光照变化、不同材质的路面等。一个模型如果能在 Cityscapes 上取得好的表现,基本可以说明它在真实城市场景中有较强的泛化能力。

第三是评估体系成熟。官方提供了严格的 train/val/test 划分,test 集的标注不公开,需要提交到官网服务器评估,这保证了论文之间对比的公平性。语义分割、实例分割、全景分割三种任务都有独立的评估指标,大家可以在同一起跑线上比较算法效果。

1.3 适合谁使用这个数据集

如果你是下面这几类人,Cityscapes 会是你需要认真研究的数据集:

  • 刚入门语义分割的研究生或工程师,需要在一个公认的数据集上验证自己的模型效果;
  • 做自动驾驶感知的算法工程师,需要训练道路场景的分割模型(比如用 mmsegmentation 训练 Cityscapes 是很多公司内部的标准流程);
  • 做模型压缩、知识蒸馏、域自适应等方向的研究者,Cityscapes 常作为源域数据集或基准数据集使用;
  • 用 nnUNet 等框架做医疗或其他领域分割的同学,也经常先把 Cityscapes 作为算法验证的标准数据集。

这篇先讲透数据集的获取、目录结构、标注文件格式和可视化方法,下一部分再展开训练细节。

2. 数据集获取与目录结构详解

2.1 下载方式与账号注册

Cityscapes 的下载入口在官网,和很多学术数据集不同,它不是直接给一个链接让你点,而是需要先注册账号,同意数据使用协议后才能下载。这个流程卡住了不少人,我第一次下载时就因为网络延迟和注册审核等了两天。

具体操作流程是:

  1. 访问 Cityscapes 官网,点击右上角的 Register 注册账号。
  2. 填写个人信息,包括姓名、单位、邮箱、使用目的等。这里建议使用学校或公司的企业邮箱,审核通过率更高。
  3. 提交后等待审核,通常在 1-2 个工作日内会收到激活邮件。
  4. 激活账号后登录,在 Downloads 页面就能看到数据集的 6 个部分:gtFine、gtCoarse、leftImg8bit、leftImg8bit_trainextra、camera、vehicle、disparity。

下载时建议用官方提供的脚本,在服务器上直接拉取比较方便。官方 GitHub 仓库 cityscapesScripts 里提供了prepare_cityscapes_dataset.pyDownload相关脚本,也可以用简单的 wget 或者 curl 加上账号 cookie 下载。

注意:登录后的下载链接是临时的,带有 session 信息,直接用 wget 下载时需要在浏览器里复制带有 token 的完整链接,或者用脚本配合账号密码自动获取。手动复制链接时不要用迅雷等多线程工具,容易被服务器断开连接。

2.2 六大文件包的职责划分

下载解压后,你会看到 6 个文件夹,每个文件夹的职责非常清晰,我整理成了一张表:

文件夹内容作用
leftImg8bit原始图像,8-bit PNG,分辨率 2048x1024模型输入图像
gtFine精细标注,包含语义、实例、多边形等语义/实例/全景分割训练与评估
gtCoarse粗糙标注,包含语义标签大规模预训练或半监督学习
camera相机参数,内外参矩阵3D 重建、深度估计等任务
vehicle车辆轨迹、GPS、速度等信息轨迹预测、多任务学习
disparity视差图,DispNet 预测结果深度估计任务

其中,最常用的是leftImg8bitgtFineleftImg8bit其实就是原始拍摄图像,按城市和序列组织成 train/val/test 三个子集。gtFine则是人工精细标注的结果,也是我们做语义分割时最关心的部分。

2.3 图像文件命名规则

Cityscapes 的文件命名非常规范,从文件名就能提取全部信息。格式是:

城市名_序列号_帧号_leftImg8bit.png

比如:

aachen_000000_000019_leftImg8bit.png

对应的是 aachen 城市、序列 000000、第 000019 帧的图像。注意leftImg8bit表示这是左侧摄像头拍摄的 8-bit 图像。

对应的标注文件命名格式是:

aachen_000000_000019_gtFine_labelIds.png aachen_000000_000019_gtFine_instanceIds.png aachen_000000_000019_gtFine_color.png aachen_000000_000019_gtFine_polygons.json

这里能看到 gtFine 下会有多种文件,分别是:

  • _labelIds.png:像素值为 0~33 的语义标签图,每个像素的数值直接对应类别 ID,这也是训练模型时实际使用的文件。
  • _instanceIds.png:像素值为实例 ID 的图,其中物体实例的 ID 编码是"类别 ID * 1000 + 实例编号",背景区域像素值为 0。
  • _color.png:用彩色标注的语义可视化图,方便人眼查看。
  • _polygons.json:JSON 格式的多边形标注文件,记录了每个物体实例的轮廓点坐标。

理解这些文件命名规则很重要,因为后续写数据加载代码时,你需要根据leftImg8bit的文件名去拼接出对应的标注文件路径。

3. 标注体系与任务类型全面拆解

3.1 33 类标注与 19 类评估

Cityscapes 的标签体系经过精心设计,官方定义了 30 个类别,加上 ignore 区域共 33 个标签值。这 30 个类别被划分为 8 个大类:平面(flat)、人(human)、车辆(vehicle)、建筑(construction)、物体(object)、自然(nature)、天空(sky)、未知(void)。

但在实际训练和评估时,我们通常只用 19 个类别。原因在于,很多类别在真实场景中出现频率极低,比如卡车、巴士、房车,如果都参与训练和评估,会造成严重的类别不平衡,模型会偏向学习高频类别。

官方推荐使用的 19 类分别是:

  • 道路、人行道、建筑、墙、围栏、电线杆、交通灯、交通标志、植被、地形、天空、人、骑手、汽车、卡车、巴士、火车、摩托车、自行车

这 19 个类别是语义分割论文中通行的标准(mIoU 的计算基准)。下载的gtFine_labelIds.png中像素值虽然包含 0~33,但在实际训练时需要做一个映射,把 33 类映射到 19 类,映射关系在官方脚本labels.py中有定义。

3.2 精细标注与粗糙标注的区别

Cityscapes 提供两套标注:精细标注(gtFine)和粗糙标注(gtCoarse)。

  • gtFine:5000 张图像,像素级精细标注,质量高。分为 train(2975 张)、val(500 张)、test(1525 张)。这是官方推荐的训练和评估标准。
  • gtCoarse:20000 张图像,标注相对粗糙,多边形轮廓没有那么精细。主要用于大规模预训练,或者作为半监督学习中的无标注数据补充。

需要注意的是,gtCoarse 只有 train 和 val 的划分,对应leftImg8bit_trainextra文件夹(额外的 20000 张原始图像)。如果你决定用 gtCoarse 做预训练,需要额外下载leftImg8bit_trainextra,因为它不在默认的leftImg8bit里。

3.3 三种任务的数据支撑

Cityscapes 的标注结构可以同时支撑三种分割任务,这也是它的设计精妙之处。

语义分割:直接使用_labelIds.png。每个像素的值就是 19 类(映射后)的类别 ID。模型输出的预测图也是 19 通道的概率图,计算交叉熵损失时直接用这个文件做 ground truth。这是最简单直接的方式,也是入门第一个要做对的任务。

实例分割:使用_instanceIds.png。这张图中每个像素的值为category_id * 1000 + instance_id。比如一辆汽车的实例 ID 是 24000(汽车类别 ID 24 + 实例 0),另一辆是 24001。背景和不可数类别(比如道路、建筑)的像素值为 0。处理时,先对 instanceIds 除以 1000 取整得到语义类别,对 1000 取余得到实例编号。Cityscapes 官方对实例标注的范围覆盖 person、rider、car、truck、bus、train、motorcycle、bicycle 这 8 个类别。

全景分割:结合_labelIds.png_instanceIds.png。全景分割的评价体系分 stuff 类和 thing 类,Cityscapes 已经把这套体系设计好了。不可数的 stuff 类别直接用语义标签,可数的 thing 类别用实例标签。有些框架如 mmsegmentation 在训练全景分割时,会直接读取这两个文件并将其合并成全景标签图(panoptic label)。

我个人的经验是,先把语义分割跑通,再扩展实例分割和全景分割,不要一上来就三线作战,容易在数据加载时出各种问题。

4. 数据读取与可视化实操

4.1 安装官方工具包 cityscapesscripts

Cityscapes 官方提供了一个 Python 工具包cityscapesscripts,它不仅能帮我们验证标注文件是否完整、可视化标注结果,还提供将 labelIds 映射到 trainIds 的完整逻辑。这个工具包很重要,因为官方训练时使用的 trainId 和原始 labelId 不同。

安装非常简单:

pip install cityscapesscripts

然后把项目仓库克隆下来(或者直接从 pip 的安装路径下找脚本):

git clone https://github.com/mcordts/cityscapesScripts.git cd cityscapesScripts

仓库里的helpers/labels.py定义了所有类别信息,包括nameidtrainIdcategorycolor等关键字段。这个文件是我做数据处理时最重要的参考文件。

4.2 将标注转换为训练可用的 trainId 格式

原始的gtFine_labelIds.png中,像素值对应的是id字段(0~33),其中很多类别的 id 是不连续的,比如汽车是 24,自行车是 33。在语义分割训练中,类别 ID 必须是连续的 0~18(对应 19 类),这样在计算交叉熵损失和评估 mIoU 时才不会出错。

官方提供了createTrainIdLabelImgs.py,用于将 labelIds 转换为使用 trainId 的图片:

python cityscapesscripts/preparation/createTrainIdLabelImgs.py \ --gtFineDir /path/to/gtFine \ --outputDir /path/to/gtFine_trainIds \ --trainId

转换后,每个标注图的像素值就是 0~18(或 255 表示 ignore 区域)。实际训练时,我都是直接读取转换后的 trainId 图像,而不是在训练时动态映射,这样可以少写不少调试代码。

4.3 可视化标注,快速理解数据

在动手训练之前,强烈建议先可视化几张标注图,直观理解数据长什么样。官方提供了visualizeAnnotations.py脚本:

python cityscapesscripts/visualization/visualizeAnnotations.py \ --city aachen \ --sequence 000000 \ --frame 000019

它会显示原始图像、语义标注、实例标注三者的对比。另外,你也可以直接用 OpenCV 读取_color.png文件,这个文件就是官方预先做好的人眼可读的彩色标注图。

我自己还写过一个简单的可视化脚本,把原始图和 labelIds 叠加起来,半透明显示,方便快速查看某个区域的标注是否精细。这个步骤对排查标注边界模糊、类别空洞等问题很有帮助。

4.4 数据加载的两种常见方式

在实际项目里,Cityscapes 数据加载有两种常见方式。

第一种是直接写一个 Dataset 类,用 OpenCV 或者 PIL 读取图像文件。流程是:

  1. 读取leftImg8bit图像。
  2. 根据文件名拼接出对应的 trainId 标注图路径。
  3. 对原始图像做数据增强(缩放、裁剪、翻转、色彩抖动等),对标注图做相同的几何变换(注意不要对标注图做颜色增强)。
  4. 将图像转为 Tensor,进行归一化。
  5. 返回图像、标注和文件名。

第二种是使用现成的框架,比如 mmsegmentation。mmsegmentation 里已经内置了 Cityscapes 数据集的加载器,你只需要配置好数据路径和类别信息即可:

dataset_type = 'CityscapesDataset' data_root = 'data/cityscapes/'

这种方式的好处是不用重复造轮子,mmsegmentation 的 dataloader 已经把 trainId 映射、ignore_index 处理等细节都封装好了。

我目前更多的训练流程用的是 mmsegmentation,但建议初学者还是先自己写一遍 Dataset 类,彻底理解图像和标注的对应关系,遇到问题才能自己排查。

5. 常见问题与避坑指南

5.1 下载慢、断连怎么办

Cityscapes 官方服务器在欧洲,国内访问速度不稳定,经常下载到一半断开。我实测过的几个方案:

  • 使用浏览器直接下载,不要用多线程下载工具。浏览器会带着 session 信息,基本能保持连接,速度慢点但稳定。
  • 分割下载,把每个压缩包单独下载,不要一次性下载整个文件夹。比如先下载 gtFine,再下载 leftImg8bit,每个包都独立传输。
  • 如果服务器在国外,可以用wget --user=账号 --password=密码配合官方脚本。如果服务器在国内,建议用 filezilla 等 FTP 工具配合浏览器复制出的带 token 的完整链接,断点续传能力更强,实测比 wget 更稳。

5.2 解压后路径对不上

很多人在配置 mmsegmentation 时会遇到路径对不上的问题。Cityscapes 解压后的原始目录结构是:

cityscapes/ ├── leftImg8bit/ │ ├── train/ │ ├── val/ │ └── test/ ├── gtFine/ │ ├── train/ │ ├── val/ │ └── test/ └── gtCoarse/

而 mmsegmentation 期望的目录结构通常是把数据集放在data/cityscapes下,并且gtFine中要有 trainId 转换后的文件。如果直接拷贝原始数据进去,训练时会报"找不到 gtFine_trainIds"之类的错误。

解决办法是先运行createTrainIdLabelImgs.py生成 trainId 文件,或者注意 mmsegmentation 的数据预处理说明,有时根本不需要转换而是要在配置中指定reduce_zero_label=Trueignore_index=255。我在这里踩过坑,明明数据路径对,但训练时 loss 一直不下降,查了半天发现是标签映射没有对齐。

5.3 trainId 映射错误导致 mIoU 异常

Cityscapes 训练时最容易出问题的就是类别映射。直接使用原始的 labelIds(0~33)去算损失,会导致:

  • 某些类别缺失,因为训练时只会使用出现过的类别 ID;
  • 评估时类别 ID 和 mIoU 计算不匹配,导致结果完全错误。

正确做法是严格使用 trainId 映射。官方labels.py中的映射关系是固定的,下面是常用的几个:

原始 id名称trainId
0road0
1sidewalk1
2building2
3wall3
4fence4
5pole5
6traffic light6
7traffic sign7
8vegetation8
9terrain9
10sky10
11person11
12rider12
13car13
14truck14
15bus15
16train16
17motorcycle17
18bicycle18
-1ignore255

5.4 类别不平衡问题

Cityscapes 中类别分布极不平衡,道路像素占比远超行人、摩托车等类别。直接用交叉熵损失训练,模型会偏向把大部分像素预测为道路,导致小车类别的 mIoU 很低。

实际处理中,我常用的策略是:

  • 使用带类别权重的损失函数(CrossEntropyLoss(weight=...)),权重和类别像素占比成反比。
  • 使用 OHEM(在线难例挖掘)或多尺度监督,加强对小目标区域的学习。
  • 在数据增强时增加随机裁剪和多尺度缩放,让模型能看到更多小物体的细节。

很多开源实现里默认是不加类别权重的,需要自己根据数据集统计计算。如果想偷懒,可以直接用 mmsegmentation 提供的OHEMPixelSampler,效果也不错。

5.5 粗糙标注与精细标注混用导致评估失真

有些朋友为了提升训练数据量,把 gtCoarse 也加入训练集,但评估时还是用 val 的 500 张精细标注图。注意 gtCoarse 的标注质量比 gtFine 差,轮廓粗糙,边缘噪声大。直接混用会导致模型在精边缘上的表现下降。建议的做法是:

  • 用 gtCoarse 做预训练或半监督学习的伪标签增强,但权重要调低;
  • 或者在 fine-tune 阶段(最后几十个 epoch)只用 gtFine,让模型适应精细标注的分布。

6. 关于 Cityscapes 的进一步规划

在做完基本的数据解析和可视化之后,Cityscapes 数据集的下一步通常就是训练分割模型。从我个人的实际体验来看,在动手训练前把数据准备、类别映射、评估指标这些问题彻底搞明白,能帮你节省至少一周的排错时间。

对于后面要发的系列文章,我大致规划了三个方向:一是用 mmsegmentation 从零训练 Cityscapes 语义分割模型,包括配置文件的详细解读和训练命令;二是深入解读 Cityscapes 在实例分割与全景分割上的数据加载与评估细节;三是在实际工业项目中,Cityscapes 预训练模型如何迁移到自有数据集(比如无人机航拍、x 光安检物品检测等场景)上的经验。每个方向都有不少坑值得单独写一篇。

Cityscapes 虽然是个老数据集,但凡是做视觉感知的人,总会在某个时刻和它打交道。把基础打牢,后续无论换什么数据集、什么框架,你都会轻松很多。这篇先到这里,下一篇我们直接上手训练。

本文还有配套的精品资源,点击获取

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 13:03:55

嵌入式C/C++单元测试首选CppUTest:从入门到落地

简介:CppUTest是C/C生态中主流的单元测试与模拟框架,专为测试驱动开发(TDD)设计,内置内存泄漏检测和Mock支持,可有效降低回归风险,尤其适用于嵌入式、IoT、后端服务等对稳定性要求较高的项目。这…

作者头像 李华
网站建设 2026/9/5 10:14:59

保险理赔App开发实战:文件上传、网络幂等与系统适配要点

简介:这是一份基于Java与Android Studio开发的保险理赔应用完整项目,面向Android移动开发初学者、Java学习者以及保险科技领域的技术人员,用于掌握理赔类App从界面设计到功能实现的全过程。项目覆盖用户登录注册、理赔表单填写、进度反馈等核…

作者头像 李华
网站建设 2026/9/4 17:57:35

机器人工具箱实操:RobotStudio安装部署与虚拟工作站搭建全指南

简介:这套机器人工具箱为Matlab环境打造,面向从事机器人学教学、科研或算法设计的工程师与学生,可用于串联机械臂、移动机器人等对象的运动学、动力学建模与仿真控制。包内共327个文件,以134个m脚本、15个mdl模型、143个html帮助文…

作者头像 李华
网站建设 2026/9/3 12:53:39

Vue3 + TypeScript 实现模块化配置式布局引擎

做后台管理系统的人应该都有体会:页面本身并不复杂,无非是表格、图表、卡片、表单几种模块的组合。但真正拉开工作量的,往往是“把这些模块摆到一个页面上”这件小事。今天要调整间距,明天要加一个区块,后天要适配一块…

作者头像 李华
网站建设 2026/9/5 2:07:52

论文双检时代,我把AI工具按分工捋了一遍

又是一年开题季,后台收到最多的私信就是:“学长,论文到底用什么写?用什么降?ChatGPT改完为什么越改越红?AIGC率是什么鬼,怎么我自己写的也被标了?” 说实话,2026年写论文…

作者头像 李华
网站建设 2026/9/5 10:20:22

HP打印机驱动适配、共享打印错误码与开发集成实战

简介:《HP打印机开发者指南》是一套面向打印软件开发与系统集成人员的系统性参考资料,围绕HP打印机技术原理、API接口与开发工具展开,从硬件接口到上层应用,内容涵盖PCL/PostScript页面描述语言、JetDirect网络协议、OXP开放平台、…

作者头像 李华