FCN源码解读之infer.py

转载自 https://blog.csdn.net/qq_21368481/article/details/80286809

infer.py是FCN中用于测试的python文件,每次可以单独测试一张图片在训练好的模型下的分割效果(直观上的以图片形式展示的分割效果)。

其源码如下:


   
     
     
     
     
  1. import numpy as np
  2. from PIL import Image
  3. import caffe
  4. import vis
  5. # the demo image is "2007_000129" from PASCAL VOC
  6. # load image, switch to BGR, subtract mean, and make dims C x H x W for Caffe
  7. im = Image.open( 'demo/image.jpg')
  8. in_ = np.array(im, dtype=np.float32)
  9. in_ = in_[:,:,:: -1]
  10. in_ -= np.array(( 104.00698793, 116.66876762, 122.67891434))
  11. in_ = in_.transpose(( 2, 0, 1))
  12. # load net
  13. net = caffe.Net( 'voc-fcn8s/deploy.prototxt', 'voc-fcn8s/fcn8s-heavy-pascal.caffemodel', caffe.TEST)
  14. # shape for input (data blob is N x C x H x W), set data
  15. net.blobs[ 'data'].reshape( 1, *in_.shape)
  16. net.blobs[ 'data'].data[...] = in_
  17. # run net and take argmax for prediction
  18. net.forward()
  19. out = net.blobs[ 'score'].data[ 0].argmax(axis= 0)
  20. # visualize segmentation in PASCAL VOC colors
  21. voc_palette = vis.make_palette( 21)
  22. out_im = Image.fromarray(vis.color_seg(out, voc_palette))
  23. out_im.save( 'demo/output.png')
  24. masked_im = Image.fromarray(vis.vis_seg(im, out, voc_palette))
  25. masked_im.save( 'demo/visualization.jpg')

源码解读如下:


   
     
     
     
     
  1. #coding=utf-8
  2. import numpy as np
  3. from PIL import Image
  4. import caffe
  5. import vis #即vis.py文件
  6. # the demo image is "2007_000129" from PASCAL VOC
  7. # load image, switch to BGR, subtract mean, and make dims C x H x W for Caffe
  8. im = Image.open( 'demo/image.jpg') #可以自行替换相应的测试图片名
  9. """
  10. 以下部分和voc_layers.py中一样,也可参见https://blog.csdn.net/qq_21368481/article/details/80246028
  11. - cast to float 转换为float型
  12. - switch channels RGB -> BGR 交换通道位置,即R通道和B通道交换(感觉是用了opencv库的原因)
  13. - subtract mean 减去均值
  14. - transpose to channel x height x width order 将通道数放在前面(对应caffe数据存储的格式)
  15. """
  16. in_ = np.array(im, dtype=np.float32)
  17. in_ = in_[:,:,:: -1]
  18. in_ -= np.array(( 104.00698793, 116.66876762, 122.67891434))
  19. in_ = in_.transpose(( 2, 0, 1))
  20. # load net 加载训练好的caffemodel
  21. # deploy.prototxt为网络的构造文件;.caffemodel是训练好的模型文件(即参数信息);网络模式为test模式
  22. net = caffe.Net( 'voc-fcn8s/deploy.prototxt', 'voc-fcn8s/fcn8s-heavy-pascal.caffemodel', caffe.TEST)
  23. # shape for input (data blob is N x C x H x W), set data
  24. net.blobs[ 'data'].reshape( 1, *in_.shape) #数字1表示测试图片为一张,即这里的第一维N=1
  25. net.blobs[ 'data'].data[...] = in_
  26. # run net and take argmax for prediction
  27. net.forward() #前向计算
  28. # 计算score层每一像素点的归属(像素归属于得分最高的那类)
  29. out = net.blobs[ 'score'].data[ 0].argmax(axis= 0) #

这里的axis=0表示第一维,而data[0]的大小表示C*H*W,也即argmax(axis=0)表示按C这一维进行取最大值,具体理解可看下面例子(注:caffe中的blob中的data是按N*C*H*W的数组存储的,即data[N][C][H][W],如果输入一张彩色图像大小为500*500,则data中的最后一个元素为data[0][2][499][499]):


   
     
     
     
     
  1. import numpy as np
  2. a = np.array([[[ 1, 2, 3],[ 4, 5, 6]],[[ 7, 8, 9],[ 10, 11, 12]],[[ 13, 14, 15],[ 16, 17, 18]]])
  3. b=np.max(a,axis= 0)
  4. print(str(a))
  5. print(str(b))

运行结果为:


   
     
     
     
     
  1. [[[ 1 2 3]
  2. [ 4 5 6]]
  3. [[ 7 8 9]
  4. [ 10 11 12]]
  5. [[ 13 14 15]
  6. [ 16 17 18]]]
  7. [[ 13 14 15]
  8. [ 16 17 18]]

从结果从可以看出b的维数为a的后两维,即2*3(a的维数为3*2*3),即np.max(a,axis=0)表示按a的第一维进行取最大值操作,如果修改为b=np.max(a,axis=1),则运行结果为:


   
     
     
     
     
  1. [[[ 1 2 3]
  2. [ 4 5 6]]
  3. [[ 7 8 9]
  4. [ 10 11 12]]
  5. [[ 13 14 15]
  6. [ 16 17 18]]]
  7. [[ 4 5 6]
  8. [ 10 11 12]
  9. [ 16 17 18]]

从结果中看出b的维数为3*3,即是按a的第二维进行取最大值操作,如果再修改为b=np.max(a,axis=2),则是按a的第三维进行取最大值操作,即b的维数应为3*2,结果如下:


   
     
     
     
     
  1. [[[ 1 2 3]
  2. [ 4 5 6]]
  3. [[ 7 8 9]
  4. [ 10 11 12]]
  5. [[ 13 14 15]
  6. [ 16 17 18]]]
  7. [[ 3 6]
  8. [ 9 12]
  9. [ 15 18]]

继续分析剩余代码如下


   
     
     
     
     
  1. # visualize segmentation in PASCAL VOC colors 调用vis.py中的函数可视化分割结果
  2. voc_palette = vis.make_palette( 21)
  3. out_im = Image.fromarray(vis.color_seg(out, voc_palette))
  4. out_im.save( 'demo/output.png') #保存分割好的图像
  5. masked_im = Image.fromarray(vis.vis_seg(im, out, voc_palette))
  6. masked_im.save( 'demo/visualization.jpg') #保存含有分割掩膜的原图

直观说明一下分割好的图像(左)与含有分割掩膜的原图(右)之间的区别,如下图所示:

FCN源码解读之infer.py_第1张图片          FCN源码解读之infer.py_第2张图片

你可能感兴趣的:(Deep,Learning,FCN,caffe)