深度学习与图像处理实战-FCN 实现斑马线分割_第1页
深度学习与图像处理实战-FCN 实现斑马线分割_第2页
深度学习与图像处理实战-FCN 实现斑马线分割_第3页
深度学习与图像处理实战-FCN 实现斑马线分割_第4页
深度学习与图像处理实战-FCN 实现斑马线分割_第5页
已阅读5页,还剩21页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

FCN实现斑马线分割深度学习与图像处理实战知识要点9.1FCN简介9.2数据集介绍及处理9.3主干网络搭建与训练9.4模型训练结果测试目录9.1FCN简介美国加州大学的乔纳森·朗等人提出了全卷积网络(FullyConvolutionalNetwork,FCN),用于图像的分割。该网络试图从抽象的特征中恢复出每个像素所属的类别,即从图像级别的分类进一步延伸到像素级别的分类。使用FCN的分割效果如图所示。使用FCN的分割效果9.1FCN简介FCN对图像进行像素级的分类,解决了语义级别的图像分割问题。与经典的CNN在卷积层之后使用全连接层得到固定长度的特征向量进行分类(全连接层+Softmax输出)不同,FCN可以接收任意尺寸的输入图像,首先采用反卷积层对最后一个卷积层的特征图进行上采样,使它恢复到与输入图像相同的尺寸,从而可以对每个像素都产生一个预测,同时保留原始输入图像中的空间信息,接着在上采样的特征图上进行逐像素分类,最后逐个像素计算Softmax分类的损失,相当于每一个像素对应一个训练样本。用于语义分割的FCN结构如图所示。FCN结构9.1FCN简介为了将这个分辨率低的粗略图像恢复到原图的分辨率,FCN使用了上采样。上采样分为3种方式,分别为线性插值、反卷积以及空洞卷积。FCN中常用的方式为线性插值,在Tensorflow.keras中表示为UpSampling2D。UpSampling2D官方说明文档如图所示,UpSampling2D只是简单地用复制插值对原张量进行修改,也就是平均池化的逆操作。UpSampling2D官方说明文档9.1FCN简介可以使用如下代码来理解这个流程。fromkeras.layersimportUpSampling2Dimportnumpyasnpimporttensorflowastfx=np.array([1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16])x=x.reshape(1,4,4,1)print(x)x=tf.convert_to_tensor(x)y=UpSampling2D(size=(2,2))(x)withtf.Session()assess:print(sess.run(y))假设输入的4×4的矩阵为[[[[1][2][3][4]][[5][6][7][8]][[9][10][11][12]][[13][14][15][16]]]],那么经过上采样层之后输出的矩阵如图所示。

经过上采样层之后输出的矩阵9.1FCN简介通过输出的矩阵,可以看见原先维度为(1,4,4,1)的数组被上采样成维度为(1,8,8,1)的数组。还可以发现,被扩充的行和列其实是通过复制原来的数据得到的,该过程可以简单地表示如下。UpSampling2D矩阵扩充9.2数据集介绍及处理前面说到FCN的输入就是一张图片,而输出是图片每个像素对应的标签。这里以斑马线分割数据集为例,数据集分为jpg和png格式的图片,jpg格式的图片就是数据,而png格式的图片则是标签,数据集如图所示。斑马线分割数据集train.txt文件内容9.2数据集介绍及处理jpg文件夹里面存放的是不同角度的斑马线图片(数据图片)。而png文件夹存放的是看似黑色的图片(标签图片)。数据图片标签图片可以通过下面的代码将标签图片像素值放大,结果如图所示。importcv2path=r'E:\DataSets\zebra_crossing\png\1.png'img=cv2.imread(path)dWindow('label',cv2.WINDOW_NORMAL)cv2.imshow('label',img*120.)cv2.waitKey(0)将像素值放大9.2数据集介绍及处理为了方便对比,还可以将这个标签图片和原图叠加起来,代码如下,可以看到图所示的叠加效果。importcv2path=r'E:\DataSets\zebra_crossing\png\1.png'path2=r'E:\DataSets\zebra_crossing\jpg\1.jpg'img1=cv2.imread(path)img2=cv2.imread(path2)print(img1.shape)dst=cv2.addWeighted(img2,1,img1*100,0.8,0)dWindow('label',cv2.WINDOW_NORMAL)cv2.imshow('label',img1*100)cv2.waitKey(0)标签图片和原图叠加效果9.2数据集介绍及处理这时候读者应该可以看见数据和标签的对应关系,其实标签图片中存放的是原图中每个像素对应的标签。右图中,标签图片的数据简单表示为0、1,其中0是背景,而1则是斑马线。所以以现在的数据集来说,实验本质上是对图片上每个像素的二分类。标签图片的数据9.2数据集介绍及处理9.2数据集介绍及处理importosimportnumpyasnpimportrandomfromPILimportImagefrommatplotlib.colorsimportrgb_to_hsv,hsv_to_rgbimportglob首先是数据集处理,先新建一个load_data.py文件,在其中导入依赖库,代码如下。01OPTION数据集处理【动手实验】该函数的功能是将输入的根路径进行处理,得到原图和标签对应的路径列表,并对其进行打乱和分割,最后返回训练数据和测试数据,代码如下。02OPTION创建一个load_data函数9.2数据集介绍及处理#加载数据defload_data(path,split=0.9):data_name='jpg'label_name='png'txt=path+r'\train.txt'

#打开标签文件获取数据withopen(txt)asf:res=f.readlines()data_path=[]label_path=[]#组合图片数据与标签数据的路径fornameinres:jpg_,png_=name.strip().split(';')[0],name.strip().split(';')[1]jpg_path=path+'\%s\%s'%(data_name,jpg_)png_path=path+'\%s\%s'%(label_name,png_)data_path.append(jpg_path)label_path.append(png_path)9.2数据集介绍及处理#打乱数据random_int=random.randint(1,10000)random.seed(random_int)random.shuffle(data_path)random.seed(random_int)random.shuffle(label_path)

#分割数据train_num=int(len(data_path)*split)x_train=data_path[:train_num]y_train=label_path[:train_num]x_test=data_path[train_num:]y_test=label_path[train_num:]returnx_train,y_train,x_test,y_test该函数主要是将输入的原图和标签路径进行加载和统一大小,然后将标签的每个像素处理成独热编码(one-hot)的格式,代码如下。03OPTION创建get_random_data函数9.2数据集介绍及处理defget_random_data(x,y,size,num_class):data=Image.open(x)label=Image.open(y)h,w=size,size#统一缩放image_data=data.resize((h,w),Image.BICUBIC)label=label.resize((h,w))image_data=np.array(image_data)/255.#print(label)label=np.array(label)image_label=np.zeros((size,size,num_class))y=label[...,1]#将标签转换成one-hot格式foriinrange(image_label.shape[0]):forjinrange(image_label.shape[1]):index=int(y[i][j])#将对应标签的位置的值变为1,如第一个像素标签为0,则转换为[[[1.,0.],...]]#第二个像素标签为1,则转换为[[[1.,0.],[0.,1.],...]]image_label[i,j,index]=1.returnimage_data,image_label该函数的功能是数据生成,可以在训练的时候一边训练一边载入数据,缓解内存不足的问题,代码如下。04OPTION编写gan_data函数9.2数据集介绍及处理defgan_data(x_data,y_data,size,num_class,batch_szie):whileTrue:data=[]label=[]forindex,image_pathinenumerate(x_data):data_,label_=get_random_data(image_path,y_data[index],size,num_class,random_=True)data.append(data_)label.append(label_)iflen(data)==batch_szie:data=np.array(data).reshape(-1,size,size,3)label=np.array(label).reshape(-1,size,size,num_class)yielddata,labeldata=[]label=[]9.3主干网络搭建与训练接下来进行主干网络的搭建。FCN的搭建比较简单,其网络结构如图所示。可以看见经过几层的卷积和池化之后,直接通过一个大尺寸的UpSampling2D来进行上采样,并且最后使用一个1×1的卷积将通道数转换为和类别数相同,再使用Softmax激活,获得最后的分类结构。FCN结构9.3主干网络搭建与训练实现的代码如下。fromExperiment.FCN.load_dataimportgan_data,load_datafromtensorflow.keras.layersimport*importtensorflow.kerasaskfromtensorflow.kerasimportcallbacksdefcreate_model1(inpt):input=k.Input(inpt)x=Conv2D(96,(3,3),2,padding='same',activation='relu')(input)x=BatchNormalization()(x)x=MaxPool2D()(x)x=Conv2D(256,(3,3),1,padding='same',activation='relu')(x)x=BatchNormalization()(x)x=MaxPool2D()(x)x=Conv2D(384,(3,3),1,padding='same',activation='relu')(x)x=Conv2D(384,(3,3),1,padding='same',activation='relu')(x)x=Conv2D(256,(3,3),1,padding='same',activation='relu')(x)x=MaxPool2D()(x)x=UpSampling2D((16,16))(x)x=Conv2D(2,(1,1),padding='same',activation='softmax')(x)returnk.models.Model(input,x)9.3主干网络搭建与训练然后就可以编译模型进行训练了,这里还使用了3个回调函数来控制训练过程,训练代码如下。path=r'E:\DataSets\zebra_crossing'batch_size=2size=224class_num=2model=create_model((size,size,3))model.summary()model=k.models.load_model('fcn_scse.h5')k.utils.plot_model(model,show_shapes=True,to_file='fcn.png')x_train,y_train,x_test,y_test=load_data(path)#print(x_train.shape,y_train.shape)pile(optimizer=k.optimizers.Adam(lr=1e-5),loss='categorical_crossentropy',metrics=['acc'])save=callbacks.ModelCheckpoint('logs/fcn_scse_ep{epoch:03d}-val_loss{val_loss:.3f}.h5',monitor='val_loss',save_best_only=True,period=1)low_lr=callbacks.ReduceLROnPlateau(monitor='val_loss',factor=0.2,patience=5,min_lr=1e-6,verbose=1)early_stop=callbacks.EarlyStopping(monitor='val_loss',patience=15,verbose=1,mode='auto')9.3主干网络搭建与训练model.fit_generator(gan_data(x_train,y_train,size,class_num,batch_size),steps_per_epoch=len(x_train)//batch_size,validation_data=gan_data(x_test,y_test,size,class_num,batch_size),validation_steps=len(x_test)//batch_size,epochs=20,callbacks=[save,low_lr,early_stop])model.save('fcn.h5')9.4

模型训练结果测试本实验仅使用20个周期进行训练。训练结束后,编写测试函数观察模型的分割结果,代码如下。importtensorflowastfimportnumpyasnpfromPILimportImage#不同类别对应的颜色corlor=np.array([(0,0,0),(0,255,0)])#加载模型model=tf.keras.models.load_model(r'\FCN\logs\fcn_scse_ep005-val_loss0.040.h5')foriinrange(1,100):path=r'E:\DataSets\zebra_crossing\jpg\%s.jpg'%iimg=Image.open(path)

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论