利用SegNet训练自己的数据集----制作自己的数据集

制作自己的数据集

鉴于论文原作者开源的SegNet网络是基于caffe框架的,而我们所用的框架是tensorflow,所以在github上找了一些tensorflow代码。本次全天空云图分割实验就是用的https://github.com/aizawan/segnet,整个代码很清晰,稍作修改就可以在CamVid数据集上进行Segnet网络训练。
  
  但是仅仅在CamVid数据集上跑通SegNet网络是实验开始的第一步,我们的目标是想利用segnet网络来分割我们收集到的全天空云图,因此该怎样制作数据集呢?

制作的步骤(以制作训练集为例):

从全天空云图仪网址上,按照顺序收集原图像以及分割后的标注图,分别放在两个文件夹里,命名为原图及标注。
  
(1)观察收集到的原图以及标注图,都是jpg格式的RGB图,size为2000×1944。由于图片尺寸过大,难以训练,因此首先对两个文件下的图片resize成480×360,并保存为png格式。

(2)再对resize后的标注图进行批量灰度化,保存在“灰度标注图”的文件夹下。批量灰度化后时,一定将标注图的灰度固定为三个值0,1,2,代表三个类别,分别为云,天空,太阳。不能有多余的其他灰度值,否则会出错。

(3)制作训练文本,将原图与灰度化后的标注图对应联系起来

以下是具体代码:

(1) 制作输入图像

利用下述代码,对原图文件夹的图像批量resize,并保存在原图修改大小这个文件夹下,作为segnet神经网络的输入,也就是训练集的原图。

#提取目录下所有图片,更改尺寸后保存到另一目录
from PIL import Image
import os.path
import glob
def convertjpg(jpgfile, outdir, width=480, height=480):
    img = Image.open(jpgfile)
    new_img = img.resize((width, height), Image.NEAREST)
    #采用最近邻算法进行缩放,主要是保证灰度化后不同类之间的灰度值差异大
    outdir1 = os.path.join(outdir, os.path.basename(jpgfile))
    outdir2 = outdir1.split('.')
    new_img.save(outdir2[0], 'png')#将图像保存为.png格式
    
for jpgfile in glob.glob("原图/*.jpg"):
    convertjpg(jpgfile, "原图修改大小")

(2) 制作标注图像

首先对收集到的标注文件夹中的图像做同样的resize操作,并保存在标注修改大小文件夹下,再对这个文件夹下的图像批量灰度化,并保存在灰度图文件夹下。

from PIL import Image 
import numpy as np
import os.path
import glob

def convert_gray(pngfile):
    img=Image.open(pngfile).convert('L')
    img.save(os.path.join('灰度图', os.path.basename(pngfile)),'png')

for pngfile in glob.glob('标注修改大小/*'):
    convert_gray(pngfile)

灰度化之后,可通过im.show()查看单张图像灰度值,突然发现,同一类的灰度值是变化的,显然并不符合标注的要求(标注要求同一类的物体其灰度值是不变的),因此需要对此进行固定灰度。
 经过用ps查看灰度值,发现云、天空、太阳这三类的灰度值虽然是变化的,但存在明显的分段,因此在这里将灰度值在20-60之间的像素其灰度值重设为1(代表云类),60-80之间的像素灰度值重设为2(代表天空类),其余设为0(代表太阳)。
 经上述处理的灰度图保存为灰度标注图文件下,即可获得训练集的标注图。

from PIL import Image
from pylab import *
import numpy
import glob
import os.path

def convert(pngfile):
    im = array(Image.open(pngfile))
    w = im.shape[0]
    h = im.shape[1]
    for x in range(w):
        for y in range(h):
            if im[x][y]>=20 and im[x][y]<60:#云
                im[x][y]=1
            elif im[x][y]>=60 and im[x][y]<100:#天空
                im[x][y]=2
            else:
                im[x][y] = 0
    img = Image.fromarray(im.astype('uint8'))
    img.save(os.path.join('灰度标注图', os.path.basename(pngfile)), 'png')

for pngfile in glob.glob('灰度图/*'):
    convert(pngfile)

取原图修改大小文件中的图片为segnet网络的输入,取灰度标注图中的图片为Segnet网络的标注。

(3) 制作训练与测试文本

对于原图与标注而言,是放入两个文件夹下的,总得有一个联系将输入图像与对应的标注串起来。下图就是训练的文本,ASC100-1006_001是图片的名称,前面的是输入图像中的路径与图像名,后者是标注的路径与图像名。segnet通过读取这个txt文本,即可获取路径,提取图片进行训练。

利用SegNet训练自己的数据集----制作自己的数据集_第1张图片
由此,真正得到了训练集。测试集的步骤类似不再赘述。

注意到:
 1、上述文件都是相对路径,可以根据自己的情况,修改为绝对路径,也是能行的;
 2、保存为png格式时有点诡异,我并没有在图像名后面加上.png后缀,有些Windows可能无法显示,只要加上.png后缀就可以显示图像,反正在ubuntu下是可以看见的,而且在读取图像时,按照名称读取,如果名称没有包含jpg、png等后缀,则不需要加上;
 3、之前用python一直不报错但是没有出处理结果,对于这种批量文件处理,可以先对单一图像进行处理,有结果了,再写个循环,对文件批量处理。

你可能感兴趣的:(全天空云图分割)