FCN源码解读之infer.py_伍颜的博客-程序员宅基地

技术标签: FCN  caffe  Deep Learning  

转载自 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') #保存含有分割掩膜的原图

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

          

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/sinat_23853639/article/details/88545625

智能推荐

2018普通本科专业目录计算机类,普通高等学校本科专业目录_weixin_39757212的博客-程序员宅基地

普通高等学校本科专业目录(2012年)本目录由教育部颁布。如有变动请以最新目录为准说明:一、《普通高等学校本科专业目录(2012年)》是高等教育工作的基本指导性文件之一。它规定专业划分、名称及所属门类,是设置和调整专业、实施人才培养、安排招生、授予学位、指导就业,进行教育统计和人才需求预测等工作的重要依据。二、本目录根据《教育部关于进行普通高等学校本科专业目录修订工作的通知》(教高〔2010〕11...

12.JDK1.8 JVM运行时数据区域概览、各区域介绍、程序计数器、Java虚拟机栈、本地方法栈、堆、堆空间内存分配(默认情况下)、字符串常量池、元数据区、jvm参数配置_to.to的博客-程序员宅基地_jdk 元数据区

12.JDK1.8 JVM运行时数据区域概览12.1.JDK1.8 JVM运行时数据区域概览12.2.各区域介绍12.3.各区域介绍12.3.1.程序计数器12.3.2.Java虚拟机栈12.3.3.本地方法栈12.3.4.堆12.3.4.1.堆空间内存分配(默认情况下)12.3.4.2.字符串常量池12.3.5.元数据区12.3.5.1.jvm参数配置12.JDK1.8 JVM运行时数据区域概览转自:https://blog.csdn.net/bruce128/article/d

C语言函数,数组与指针_抓到一只Q的博客-程序员宅基地

指针形参题外话:本想着一次性把和指针有关的东西一次写完,又觉得写在一个博客里把有的重点堆在一起,日后复习看起来感觉很乱。就单独把指针变量的基本操作与指针形参单独罗列出来记录。重拾C并且进一步学习C是为了给接下来自学数据结构与算法打一个厚实的基础,不得不说C primer plus真的是很好的一本书,知识真的很详细,不过有的还是没有讲到,不过都等着我发现了,进一步挖掘最底层的东西。...

android改变整个app字体大小,Android系统字体大小如何影响app的字体大小?_weixin_39737224的博客-程序员宅基地

在Android应用开发过程中,一定会碰到本来完美的布局,在系统字体大小设置【最大】时变成一团浆糊。解决办法网上也有很多,但是分析原理的却几乎没看到。博主在碰到问题的第一时间也是直接用了网上的方法,即在BaseActivity中重写getResources方法如下@Overridepublic Resources getResources() {Resources res = super.getR...

深度学习 1.PyTorch入门_baiyucraft的博客-程序员宅基地

Author:baiyucraftBLog: baiyucraft’s Home原文:《动手学深度学习》一、深度学习简介1.深度学习  首先,我们得知道什么是深度学习:深度学习是一种特殊的机器学习,通过学习将世界使用嵌套的概念层次来表示并实现巨大的功能和灵活性,其中每个概念都定义为与简单概念相关联,而更为抽象的表示则以较不抽象的方式来计算。  其实目前来说我也不太清楚机器学习和深度学习具体的概念,所以这块留白,日后补充。2.PyTorch  在深度学习中,这里我们选择PyTorch作

css引入样式和权重_长脖子的鹿的博客-程序员宅基地

引入样式的四种方法:1、行间样式2、页面级css 在head标签中写style标签3、外部css样式 使用link标签4、导入样式<style>@import url("外部样式表的名称");</style>HTML中的代码:ID选择器在文档中使用一次与类不同,有且仅有一次css权重:!import infinity行间样...

随便推点

Hanlp分词之CRF中文词法分析详解_weixin_33836223的博客-程序员宅基地

这是另一套基于CRF的词法分析系统,类似感知机词法分析器,提供了完善的训练与分析接口。CRF的效果比感知机稍好一些,然而训练速度较慢,也不支持在线学习。默认模型训练自OpenCorpus/pku98/199801.txt,随hanlp 1.6.2以上版本发布。语料格式等与感知机词法分析器相同,请先阅读《感知机词法分析器》。中文分词训练...

Compass项目博客后端学习与开发记录(一)_被裹挟的阿宁的博客-程序员宅基地

Compass项目博客后端学习与开发记录Compass 山东大学软件学院就业信息发布与推荐平台项目使用git进行版本管理前端界面使用bootstrap后端计划使用spring boot框架,使用maven进行辅助构建,目标是能够部署到腾讯云服务器上腾讯云有个蛮好的校园云服务器也不贵今天的这个blog主要就是一个试水,第一次写blog,不知道说些什么对于springboot我们都需要从头学起java -> spring -> spring boot中间还要穿插了解maven这

配置IIS Express以便通过IP地址访问调试的网站_weixin_30695195的博客-程序员宅基地

问题背景最近使用C#编写了一个WebService,希望通过Java进行调用。使用Visual Studio 2013调试WebService时,可以在浏览器中通过localhost地址访问WSDL文件。访问方式如:http://localhost:2256/DataProvider.asmx?WSDL。但是,当使用http://127.0.0.1:2256/DataProvider....

iOS SceneDelegate应用_假装你是大灰狼的博客-程序员宅基地

Xcode 11 建新工程默认会创建通过UIScene管理多个UIWindow的应用,工程中除了AppDelegate外还会有一个SceneDelegate,这是为了实现iPadOS支持多窗口的结果。AppDelegate.h不再有window属性,window属性被定义在了SceneDelegate.h中,AppDelegate中有新增的关于scene的代理方法,SceneDelegate中也有相应的代理方法。因此,当我们用Xcode11针对不同版本的iOS开发应用时,就要做一些适配。创建好一个工程后,

ROS学习笔记(四):ROS主题_一把木剑的博客-程序员宅基地

一,准备工作1.运行roscore$ roscore2.运行小乌龟(新terminal)$ rosrun turtlesim turtlesim_node3.控制小乌龟(新terminal)$ rosrun turtlesim turtle_teleop_key这样我们就可以通过控制方向键来控制小乌龟的运动了。二,ROS主题初探    在上面的过程中,小乌龟程序是一个节点,方向键控

JavaScript 作用域(Scope)详解_weixin_30300523的博客-程序员宅基地

先对需要用到的名词解释一下,再通过例子深入理解一、什么是作用域(Scope)  [[scope]]:每个javascript函数都是一个对象,对象中有些属性我们可以访问,但有些不可以,这些属性仅供javascript引擎存取,[[scope]]就是其中一个。[[scope]]指的就是我们所说的作用域,其中存储了运行期上下文的集合。即作用域决定了代码区块中变量和其他资源的可见性。二...