最近在做语义分割,需要用到VOC2012 数据库进行处理。发现网上的教程很多也很杂。我在这里按自己的理解把过程写出来。
首先是原始的VOC 2012 数据集。大家在网上下载下来解压以后可以看到几个文件夹。如下
这里于一系列的文件夹。第一个是一些标签,有些是我自己扩增数据的文件夹。主要是 第 1 4 5 6 8 这个几个文件夹。这几个文件夹具体是干什么的。大家看一下里面内容就知道了。我么进行语义分割时的需要用到 ImageSets 文件下的 Segmentation 文件夹
里面主要有下面几个东西
这几个表示的是语义分割的训练集和验证集。当然还有一个测试集。因为VOC 2012 没有发出test 数据集的标签,想要验证好坏需要去官网上面验证。这里我就不进行说明了。
打开这个文件train.txt可以发现数据量分布是 1464 for training, 1449 for validation, and 1456 for testing;
因为在这里的标签是RGB 文件需要进行一个转换,转成类别索引的文件。都是。png 文件。
具体代码如下
def convert_from_color_segmentation(arr_3d):
arr_2d = np.zeros((arr_3d.shape[0], arr_3d.shape[1]), dtype=np.uint8)
palette = pascal_palette()
for c, i in palette.items():
m = np.all(arr_3d == np.array(c).reshape(1, 1, 3), axis=2)
arr_2d[m] = i
return arr_2d
这样就可以转换了,转换成之后变成这样。
可以看到转换后的图像是全黑的 这里无所谓的后期还会进行处理。
下面是介绍VOC 2012 数据扩增的数据,SBD 数据。因为原始的数据只有1464张进行训练,这明显是不不够的,后面进行了扩增。打开VOC 2012 训练/验证数据集和SBD数据集我们可以看到,原始 VOC 2012 的标注使用的是彩色标注,SBD数据集是使用matlab中 .mat 后缀的文件标注的,要将二者进行融合,我们需要对标注数据做一个简单地转换。这里需要用到两个 python 脚本:mat2png.py 用于将 .mat 标注转换为灰度标注图像,。这里两个函数具体如下
from __future__ import print_function
import os
import sys
import glob
from PIL import Image as PILImage
from utils import mat2png_hariharan
def main():
input_path, output_path = process_arguments(argv)
if os.path.isdir(input_path) and os.path.isdir(output_path):
mat_files = glob.glob(os.path.join(input_path, '*.mat'))
convert_mat2png(mat_files, output_path)
else:
help('Input or output path does not exist!\n')
def process_arguments():
num_args = len(argv)
# input_path ='H:\\segdata3\\benchmark_RELEASE\\dataset\\cls'
# output_path = 'H:\\segdata3\\VOCdevkit\\VOC2012\\Augimageclass'
#
if num_args == 3:
input_path = argv[1]
output_path = argv[2]
else:
help()
#
return input_path, output_path
def convert_mat2png(mat_files, output_path):
if not mat_files:
help('Input directory does not contain any Matlab files!\n')
for mat in mat_files:
numpy_img = mat2png_hariharan(mat)
pil_img = PILImage.fromarray(numpy_img)
pil_img.save(os.path.join(output_path, modify_image_name(mat, 'png')))
# Extract name of image from given path, replace its extension with specified one
# and return new name only, not path.
def modify_image_name(path, ext):
return os.path.basename(path).split('.')[0] + '.' + ext
def help(msg=''):
print(msg +
'Usage: python mat2png.py INPUT_PATH OUTPUT_PATH\n'
'INPUT_PATH denotes path containing Matlab files for conversion.\n'
'OUTPUT_PATH denotes path where converted Png files ar going to be saved.'
, file=sys.stderr)
exit()
if __name__ == '__main__':
main()
这样.mat 文件就转好了。
我们最好看一下这个扩增数据的分布是什么样的。
这里train 包含的图片数量为:8498 for training and 2857 for validation;
最好把这两个数据集融合 (也就是复制粘贴的作用)
制作完成的增强数据集图片分布为:10582, 1449 and 1456 images for training, validation and testing respectively.
然后重新制作一个 train.txt 文件。
说到这里发现都没有问题,但是当大家把这两个数据融合之后发现,得到的训练数据量并不是10582这个数字。但是发现许多论文中大家用的都是这个数据。我们得出的结就是其中有重复的数据集,也就是验证的数据集也在训练里面了。
那么这个10582到底怎么来的呢,pascal的官网上也没有这个下载链接,找了好久之后,终于找到一个有这个数据下载的blog,数据获得。10582个数据的augtrain.txt.
这样大家就可以得到10582个数据集用于训练了。