3. 语义分割数据集详解
做语义分割,数据集就是你的「食材」。食材不好,厨艺再高也白搭。我这些年踩过的坑,有一半都跟数据集有关——不是标签对不上,就是颜色映射搞反了。今天咱们就把两个最经典的数据集掰开揉碎讲清楚。
核心观点:PASCAL VOC 2012适合入门和快速验证,Cityscapes才是工业级实战的标配。别搞反了。
3.1 PASCAL VOC 2012:入门首选
这个数据集,说白了就是计算机视觉界的「Hello World」。它最早是2005年出来的,后来2012年版本成了最常用的基准。我刚开始做分割时,第一个跑通的就是它。
基本概况:
- 类别数:20个物体类 + 1个背景类
- 训练集:1464张(原版),加上增强版有10582张
- 验证集:1449张
- 测试集:1456张(标签不公开)
- 图像分辨率:平均500×375左右
嗯,这里要注意——原版训练集只有1464张,对于深度学习来说太少了。所以大家普遍用的是增强版(augmented),也就是VOC 2012 + SBD(Semantic Boundaries Dataset)的组合。我在项目中习惯直接用增强版,效果明显好一截。
类别列表:
| 类别ID | 名称 | 颜色(RGB) |
|---|---|---|
| 0 | 背景 | (0, 0, 0) |
| 1 | 飞机 | (128, 0, 0) |
| 2 | 自行车 | (0, 128, 0) |
| 3 | 鸟 | (128, 128, 0) |
| 4 | 船 | (0, 0, 128) |
| 5 | 瓶子 | (128, 0, 128) |
| 6 | 公交车 | (0, 128, 128) |
| 7 | 汽车 | (128, 128, 128) |
| 8 | 猫 | (64, 0, 0) |
| 9 | 椅子 | (192, 0, 0) |
| 10 | 牛 | (64, 128, 0) |
| ... | ... | ... |
我的小技巧:颜色映射表最好存成numpy数组,每次加载数据集时直接查表。我曾经手写if-else判断颜色,结果又慢又容易出错。
3.2 Cityscapes:工业级标准
Cityscapes是奔驰实验室搞出来的,专门针对街景理解。你想想看,自动驾驶、智慧城市,哪个离得开它?我个人觉得,如果你要做落地项目,Cityscapes比VOC有价值得多。
基本概况:
- 类别数:30个类,但常用的是19个(去掉rare类)
- 训练集:2975张精细标注 + 20000张粗糙标注
- 验证集:500张
- 测试集:1525张
- 图像分辨率:2048×1024(高清!)
为什么说它「工业级」?你看分辨率就知道了——2048×1024,一张图顶VOC好几张。我刚开始跑Cityscapes时,显卡直接爆显存,后来才学会用滑动窗口或者下采样。
19类常用类别:
| 类别ID | 名称 | 颜色(RGB) |
|---|---|---|
| 0 | 道路 | (128, 64, 128) |
| 1 | 人行道 | (244, 35, 232) |
| 2 | 建筑 | (70, 70, 70) |
| 3 | 墙 | (102, 102, 156) |
| 4 | 围栏 | (190, 153, 153) |
| 5 | 杆子 | (153, 153, 153) |
| 6 | 交通灯 | (250, 170, 30) |
| 7 | 交通标志 | (220, 220, 0) |
| 8 | 植被 | (107, 142, 35) |
| 9 | 地形 | (152, 251, 152) |
| 10 | 天空 | (70, 130, 180) |
| ... | ... | ... |
避坑指南:我曾经在Cityscapes上犯过一个低级错误——直接用19类去训练,但忘了把ignore类(ID=255)排除掉。结果mIoU死活上不去,查了两天才发现是loss计算时把ignore类也算进去了。
3.3 数据集下载与目录结构
下载这事儿,说起来简单,但网络不好的时候能急死人。我建议直接用脚本下载,别手动点。
PASCAL VOC 2012下载:
# 方式一:直接wget
wget http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar
# 方式二:用Python脚本
import urllib.request
url = "http://host.robots.ox.ac.uk/pascal/VOC/voc2012/VOCtrainval_11-May-2012.tar"
urllib.request.urlretrieve(url, "VOCtrainval_11-May-2012.tar")
Cityscapes下载:需要注册账号,然后从官网下载。我个人习惯用脚本配合cookie,不然每次手动输密码太烦了。
目录结构对比:
# PASCAL VOC 2012
VOCdevkit/
VOC2012/
JPEGImages/ # 原始图像
SegmentationClass/ # 语义分割标签(彩色)
SegmentationObject/ # 实例分割标签
ImageSets/ # 训练/验证/测试集划分
Segmentation/
train.txt
val.txt
trainval.txt
# Cityscapes
cityscapes/
leftImg8bit/ # 原始图像
train/
val/
test/
gtFine/ # 精细标注
train/
val/
test/
gtCoarse/ # 粗糙标注(可选)
train/
val/
我的习惯:把两个数据集统一成一个加载接口。这样换数据集时,只需要改配置文件,不用改代码。具体做法就是写一个BaseDataset类,VOC和Cityscapes都继承它。
3.4 标签与颜色映射:最容易翻车的地方
标签映射,说白了就是「像素值」和「类别」之间的翻译。你想想看,模型输出的是类别ID(比如0,1,2...),但可视化时需要转成RGB颜色。这个映射关系一旦搞错,可视化出来的图就是一团乱码。
VOC的映射逻辑:
- 标签图是彩色PNG,每个像素的RGB值直接对应类别
- 比如(128, 0, 0)对应飞机,(0, 128, 0)对应自行车
- 背景是(0, 0, 0)
Cityscapes的映射逻辑:
- 标签图也是彩色PNG,但颜色更丰富
- 有19个训练类 + 11个忽略类(用255标记)
- 忽略类包括:摩托车、卡车、火车等(因为标注不一致)
颜色映射代码示例:
import numpy as np
# VOC颜色映射
voc_palette = {
0: (0, 0, 0), # 背景
1: (128, 0, 0), # 飞机
2: (0, 128, 0), # 自行车
# ... 省略其他
}
def voc_label_to_color(label):
"""将类别ID转成RGB颜色"""
h, w = label.shape
color_img = np.zeros((h, w, 3), dtype=np.uint8)
for cls_id, color in voc_palette.items():
mask = (label == cls_id)
color_img[mask] = color
return color_img
# Cityscapes颜色映射
cityscapes_palette = {
0: (128, 64, 128), # 道路
1: (244, 35, 232), # 人行道
# ... 省略其他
255: (0, 0, 0), # 忽略类(通常显示为黑色)
}
我曾经踩过的坑:有一次我直接用VOC的颜色映射去可视化Cityscapes,结果道路变成了飞机,天空变成了自行车。排查了半天才发现是调用了错误的调色板。后来我学乖了,每个数据集单独写一个映射函数,绝不混用。
3.5 知识体系总览
下面这张图,是我自己总结的数据集知识体系。你照着这个思路去学,不会乱。
这张图把数据集的核心要素分成了三块:类型、组成、操作。你只要把这三块吃透了,不管换什么数据集,都能快速上手。
总结一下:VOC适合练手,Cityscapes适合实战。下载时注意网络,映射时注意别搞混。目录结构要记牢,因为后面写数据加载器时全靠它。