深度学习图像分割(二)——如何制作自己的PASCAL-VOC2012数据集

前言

在之前的那篇文章中:深度学习图像分割(一)——PASCAL-VOC2012数据集(vocdevkit、Vocbenchmark_release)详细介绍 我们大概了解了VOC2012图像分割数据集的基本格式,现在我们来讨论一下我们具体需要什么样的数据格式和我们如何去制作自己的数据集。

数据格式

实际我们在使用FCN算法进行深度学习训练过程中,对于图像的分割我们只需要两种数据:

一种是原始图像,就是我们要进行训练的图像:

而另一种是可以携带图像分割信息的图像或者标记语言文件,相当于分类中的label,不论是图像还是标记语言文件,我们都可以通过程序来得到我们需要的图像格式,一般来说我们最终需要的结果是一维的图像(这里的一维是指像灰度图一样只有一个通道的图像,图像中像素点只有固定的几个类型像素点,比如背景是0,分割物分别是1、2、3…):

  • 携带图像分割信息的图像:
  • 或者之前文章中提到的携带分割信息的.mat格式的文件。
  • 也或者是携带分割信息的json图像,当然json提供的是边缘点而不是具体的分割信息,相比上面那两个需要的处理过程稍微多一些。
  "shapes": [
    {
      "label": "plane",
      "line_color": null,
      "fill_color": red,
      "points": [
        [
          54,
          120
        ],
        [
          85,
          115
        ],
        [
          118,
          116
        ],
        [
          164,
          127
        ],
        [
          212,
          145
        ],
        [
          259,
          161
        ],
        [
          272,
          165
        ],
        [
          280,
          157
        ],
        [
          283,
          142
        ],
        [
          288,
          122
        ],
        [
          292,
          109
        ],
        [
          298,
          110
        ],
        [
          292,
          167
        ],
        [
          297,
          173
        ],
        [
          299,
          178
        ],
        [
          356,
          175
        ],
        [
          363,
          177
        ],
        [
          363,
          180
        ],
        [
          497,
          174
        ],
        [
          498,
          180
        ],
        [
          452,
          184
        ],
        [
          397,
          189
        ],
      .... 
      ]
    }
  ],
  "lineColor": [
    0,
    255,
    0,
    128
  ],
  "fillColor": [
    255,
    0,
    0,
    128
  ],
  "imagePath": "2007_000033.jpg",
  "imageData": "/9j/4AAQSkZJRgABAQAAAQABAAD/2wBDAAIBAQEBAQIBAQECAgICAgQDAgICAgUEBAMEBgUGBgYFBgYGBwkIBgcJBwYGCAsICQoKCgoKBggLDAsKDAkKCgr/2wBDAQICAgICAgUDAwUKBwYHCgoKCgoK
  ...
}

我们需要的数据格式

刚才说到在训练过程中,我们投入原图和携带分割信息的图片。

这里有个地方需要注意一下,VOC数据集中的png标记图是8-bit彩色图像:

我们平时使用的彩色图是24-bit真彩色图,也就是RGB三通道都是8bit,值的范围分别是0-255,。而8-bit彩色图则是假彩色图片,这8位中是这样分配的:

Bit    7  6  5  4  3  2  1  0
Data   R  R  R  G  G  G  B  B

R、G各占3位,B占2位,组合起来能表示256种颜色。

我们通过程序来读取一下:

In[4]: import PIL.Image
# 通过PIL库读取8bit的png标记图
In[5]: img = PIL.Image.open('/home/prototype/Desktop/PycharmProjects/pytorch-fcn-master/examples/voc/VOC/VOCdevkit/VOC2012/SegmentationClass/2007_000039.png')  
In[6]: import numpy as np
In[7]: img_32 = np.array(img, dtype=np.int32)  # 将读取的png标记图转化为numpy数组
In[8]: import scipy
In[9]: import scipy.io
# 通过scipy库读取携带图像分割信息的.mat文件
In[10]: mat = scipy.io.loadmat('/home/prototype/Desktop/PycharmProjects/pytorch-fcn-master/examples/voc/VOC/benchmark_RELEASE/dataset/cls/2008_000008.mat')
# 取出.mat文件中有关标记信息的部分
In[11]: lbl = mat['GTcls'][0]['Segmentation'][0].astype(np.int32)
In[12]: lbl.shape
Out[12]: (442, 500) # .mat文件中的标记信息格式
In[15]: lbl_r[lbl_r > 0]  
Out[15]: array([15, 15, 15, ..., 13, 13, 13], dtype=int32)   
In[16]: img_32[img_32>0]
Out[16]: array([255, 255, 255, ..., 255, 255, 255], dtype=int32)
In[19]: img_32[img_32==255] = -1
In[20]: img_32[img_32>0]
Out[20]: array([20, 20, 20, ..., 20, 20, 20], dtype=int32)

我们在通过PIL读取的时候已经将8-bit的图像数据格式进行了转化,将8-bit彩色转化为8-bit灰度图,灰度的值就是这个假彩色的值。而且要注意上面我们把通过PIL读取然后转化为numpy数组的图像进行了这个img_32[img_32==255] = -1操作,这个操作会作用是什么,我们发现了在png标记图中,每个要分割的内容颜色填充都有一层白色轮廓:

这个白色边框在训练中这白色边框所占的像素点并不参与训练,边框只是为了能够更加清晰地显示要分割的目标,以及更好地和背景进行区分而设置的,实际操作中我们其实是可以忽略的。所以上面的执行代码就是将这些白色边框抹掉,赋予-1值在之后的训练中可以通过操作过滤掉。

制作自己的数据集

制作数据集有很多工具,matlab上面自带工具但是比较繁琐,这里我们使用wkentaro编写的labelme,这个软件是使用pyqt编写的轻量级软件,github地址:https://github.com/wkentaro/labelme。

这是软件界面。

至于软件怎么使用github项目页面上都有详细的介绍,我这也就不多赘述了。

唯一需要注意的是这个软件标记出来的文件是json文件,然后通过python代码将json文件转化为我们需要的png标记图,这个标记图的读取方式和我之前写的类似,作者也是建议使用PIL去读取然后转化为numpy格式,最后转化为上面说到的我们需要的格式:

# see load_label_png.py also.
>>> import numpy as np
>>> import PIL.Image

>>> label_png = 'apc2016_obj3_json/label.png'
>>> lbl = np.asarray(PIL.Image.open(label_png))
>>> print(lbl.dtype)
dtype('int32')
>>> np.unique(lbl)
array([0, 1, 2, 3], dtype=int32)
>>> lbl.shape
(907, 1210)

大概就说这么些,下篇文章介绍使用FCN做图像分割训练的原理。

文章来源于:https://oldpan.me/

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

编辑于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏CreateAMind

keras中文文档

Keras是一个极简和高度模块化的神经网络库,Keras由纯Python编写而成并基于Theano或Tensorflow。Keras 为支持快速实验而生,如果你...

1395
来自专栏Python中文社区

GAFT:一个使用Python实现的遗传算法框架

專 欄 ❈PytLab,Python 中文社区专栏作者。主要从事科学计算与高性能计算领域的应用,主要语言为Python,C,C++。熟悉数值算法(最优化方法,...

1699
来自专栏WOLFRAM

Mathematica 在图与网络中的应用

903
来自专栏应兆康的专栏

扭曲你的数据,让其变得具有视觉吸引力

经常有这样的情况,你用数据画出图像有看起来会很丑,如何让你的图像变得好看一点呢?本文给大家介绍如何扭曲你的数据,在不影响结果和其他属性的情况下,使得你数据画出来...

2714
来自专栏人工智能头条

从Theano到Lasagne:基于Python的深度学习的框架和库

1511
来自专栏marsggbo

Python数据增强(data augmentation)库--Augmentor 使用介绍

Augmentor 使用介绍 原图 ? 1.random_distortion(probability, grid_height, grid_width, ma...

4058
来自专栏有趣的Python

5- OpenCV+TensorFlow 入门人工智能图像处理-图片的几何变换(一)

图片的几何变换 图片的几何变换章节介绍 图片位移 & 图片缩放 图片剪切 & 图片镜像 图片仿射变换 Hog + Svm 小狮子识别 计算机视觉的基础: 裁剪样...

3613
来自专栏有趣的Python

6- OpenCV+TensorFlow 入门人工智能图像处理-图片移位

2127
来自专栏林欣哲

自然语言处理--文本处理

自然语言处理的目的是让机器试图理解和处理人类的文字。通常来说,人的语言是冗余的,含有歧义的,而机器是准确的,无歧义的,要让机器理解,这之间存在一个转换的问题。 ...

3288
来自专栏机器学习实践二三事

fine-tuning的二三事

日常的应用中,我们会很经常遇到一个问题: 如何应用强大的model(比如ResNet)去训练我们自己的数据? 考虑到这样的几个事实: 通常我们自己的数据集都...

18410

扫码关注云+社区