October 17, 2018
by Frank
cityscapes 通常被用作语义分割,里面的数据一共分为 8 个 category,其中包含一个名为 void 的 category,每个 category 中又有多个 class,cityscapes 一共有 30 个 class,但是 cityscapes 编号过后的 label 一共有 35 种,其中也包含 unlabeled 等并没有算作 class 的 label。
cityscapes 通常被用作语义分割,里面的数据一共分为 8 个 category,其中包含一个名为 void 的 category,每个 category 中又有多个 class,cityscapes 一共有 30 个 class,但是 cityscapes 编号过后的 label 一共有 35 种,其中也包含 unlabeled 等并没有算作 class 的 label。
paper 中常用的数据大概只有一部分,即 fine 标记过的数据集,其它一些额外的粗糙标记的数据使用相对比较少,下面先介绍一下这些常用的数据。
常用的一些数据如下图:
上面两个是标记之后的 mask,下面两个是原始的数据,即 8 位的照片,这两对数据也分成了两个部分,一部分是 fine 标记过的,另一部分为粗糙标记的额外数据,对应于 train_extra,通常不用来训练。对于 fine 标记的数据,一共有 5000 张照片和对应的标记,其中有 2975 张用于 train,500 张用于 val,1525 张用于 test 和 benchmark。
这里重点介绍一下 cityscapes 的标记数据,这一块比较麻烦一些,对于每一张图片,其标记数据有四种,也包含在 gtFine 的文件夹里面,每个图片所对应的 4 种标记分别为:xxx_gtFine_color.png,xxx_gtFine_instanceIds.png,xxx_gtFine_labelIds.png,xxx_gtFine_polygons.json。其中 xxx_gtFine_color.png 为标记的彩色表示,主要用于可视化,xxx_gtFine_instanceIds.png 是 instance-level 分割的任务所使用的标记,xxx_gtFine_labelIds.png 是 pixel-level 分割所使用的标记,xxx_gtFine_polygons.json 是标记的具体信息,包括图像尺寸,标记的类别和多边形的顶点。
需要注意的是,这里面的文件并不适合直接拿来训练,cityscapes 对每个 label 都进行了编号,包括天空之类的,这个编号我们称之为绝对编号。
对于 instance-level 的任务,在 xxx_gtFine_instanceIds.png 中,其每个像素对应的灰度值和这些 ID 并不是一一对应的,而需要一些函数来将其进行转换,这些函数可以在 citycapesscripts 里面找到,转换之后的文件为 xxx_gtFine_instanceTrainIds.png,然后才能将其用于 instance-level 的训练。
对于 pixel-level 的任务,同样也不能直接使用 xxx_gtFine_labelIds.png 作为标记,这里面的灰度值代表 cityscapes 对每个 label 进行的编号,也就是绝对编号,而其中很多 label 并不会用在训练和最后的 val 之中,比如天空等,所以也需要对这些编号进行转换,可以利用 citycapesscripts 里面的 createTrainIdLabelImgs 函数,将其转换为 xxx_gtFine_labelTrainIds.png,这里面每个像素对应的灰度值是一个临时编号,包含-1,0->18,255 的编号,其中-1 和 255 的编号都不会在 val 里面被检测,所以可以将二者归类为 19 编号,即最后训练的编号变成了 0-19 这 20 类 label,因此一共进行分类的类别有 20 种。需要注意的是,如果要提交结果到 cityscapes 的 benchmark 上,那么必须将这些分类转换为绝对编号再上传,各种编号与颜色之间的对应关系可以在 citycapesscripts 中的 labels.py 文件中找到,其中的 trainId 也就相当于拿来做 pixel-level segmentation 训练的临时编号。