转载:SSD: Single Shot MultiBox Detector 检测单张图片_ssd单张图片检测-程序员宅基地

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/Jesse_Mx/article/details/52965281
                                        <div class="markdown_views">
            <h2 id="前言"><a name="t0"></a><font color="#0099FF">前言</font></h2> 

博主也算是刚开始研究SSD项目,之前写了一篇SSD:Single Shot MultiBox Detector的安装配置和运行,这次是简单介绍下如何用SSD检测单张图片,其实过程也比较简单,下面正式开始。

准备工作

当然,首先你要把SSD按照教程编译好,设置好python环境变量(相当重要),然后重启计算机(建议),开始本次工作。SSD项目检测单张图片有C++程序和ipython程序,这里建议用ipython,主要是方便简单(最近新增了C++程序使用说明)。该工具路径为/home/mx/caffe/example/ssd_detect.ipynb,使用jupyter notebook工具操作。SSD项目常在更新,如果有模型不匹配的问题(报错信息为:shape mismatch. Source param shape is 12 512 3 3 (55296); target param shape is 16 512 3 3 (73728)),请去github下载最新的文件,包括代码和模型

安装 jupyter notebook

这里用pip安装该工具,安装pip的过的可以跳过下面一段:
下载安装包pip压缩包解压之后,发现里面有个setup.py文件,终端运行:

$ sudo python setup.py install
  
  
   
  • 1

这样,pip就安装上了。
下面用pip安装jupyter notebook

#这里临时使用了清华大学的源,使用前后是蜗牛和火箭的速度对比
$ sudo pip install jupyter -i https://pypi.tuna.tsinghua.edu.cn/simple 
  
  
   
  • 1
  • 2

安装成功后,运行notebook

$ jupyter notebook
  
  
   
  • 1

程序会在浏览器中打开notebook, 点击右上角的New-python2, 就可以新建一个网页一样的文件,扩展名为ipynb。在这个网页上,我们就可以像在命令行下面一样运行python代码了。输入代码后,按shift+enter运行,更多的快捷键,可点击上方的help-Keyboard shortcuts查看,或者先按esc退出编辑状态,再按h键查看。

这里写图片描述

下载SSD模型

该工具使用的模型是VGG_VOC0712_SSD_300x300_iter_120000.caffemodel(以前是60000,作者更新了),为了第一次就成功,我们就用它了,这是下载地址 ,下载完后解压,把里面的VGGNet文件夹移动到/home/mx/caffe/models/之下。当然,你掌握这个程序后,完全可以修改路径,检测其他模型的效果。

顺便说下,部分人下载运行上述SSD模型会报错,有些错误很难排查,可以使用我正在使用的SSD300模型,暂时没有问题(对应的是最新的SSD代码):https://pan.baidu.com/s/1eSECLEU

运行程序检测单张图片

$ cd /home/mx/caffe/examples # 在该目录下打开jupyter notebook
$ jupyter notebook
  
  
   
  • 1
  • 2

在jupyter notebook打开的网页中找到ssd_detect.ipynb,打开后发现是这样:

这里写图片描述

完整的程序我就不放出来了,你打开都和我一样,然后检查下面4个路径是否正确:

labelmap_file = 'data/VOC0712/labelmap_voc.prototxt'
model_def = 'models/VGGNet/VOC0712/SSD_300x300/deploy.prototxt'
model_weights = 'models/VGGNet/VOC0712/SSD_300x300/VGG_VOC0712_SSD_300x300_iter_120000.caffemodel'
image = caffe.io.load_image('examples/images/cat.jpg')
  
  
   
  • 1
  • 2
  • 3
  • 4

如果检查无误,就可以开始从头shift+enter运行了,一般会正常运行,也可能会出错,比如我就遇到如下错误:

这里写图片描述

我的办法是,把caffe路径换成绝对路径:

把 caffe_root = ‘../’ 换成 caffe_root = ‘/home/mx/caffe/’ ,理论上不会再出错了,然后在诸如labelmp的路径前面添加caffe_root构成完整的绝对路径,比如:labelmap_file = caffe_root+’data/VOC0712/labelmap_voc.prototxt’

还有一种模型错误也很常见,NameError:name ‘net’ is not defined

在caffe加载正常的情况下出现这种错误,很有可能是deploy.prototxt文件的问题,如果deploy.prototxt最后一层中能查找到save_output_param超参数,删除后能解决问题(后文有详细说明),如果不是,那还要继续排查。

fish-bike.jpg的检测结果如下:

这里写图片描述

换一张复杂一点的图片image = caffe.io.load_image(‘examples/images/my-pic.jpg’) ,检测结果如下:

这里写图片描述

保存运行Python文件

看来效果也是不错的,但是我觉得如果不是去调试代码,每次都打开jupyter notebook运行程序太麻烦,也不方便保存图片之类的操作。这里我的做法是把程序另存为py文件(使用jupyter notebook打开ipynb文件,然后点选另存为),稍作修改,再单独运行这个py文件即可。改动的地方貌似只有一处,就是把get_ipython().magic(u'matplotlib inline')这句话给注释掉,因为脱离了jupyter notebook的环境,用不上了。然后python ssd_detect.py,代码正常,没有报错,但是无法弹出窗口显示最终的带框图片,上网查询一番,原因是是默认的matplotlib的backend(后端)渲染有问题。那么先查看目前的后端情况:

Python 2.7.12 (default, Jul  1 2016, 15:12:24) 
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import matplotlib
>>> matplotlib.get_backend()
u'Agg'
  
  
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

目前是Agg,但为了正确将图像显示在屏幕上,需要设置为TkAgg,解决方法是安装几个库文件:

$ sudo apt-get install tcl-dev tk-dev python-tk python3-tk
  
  
   
  • 1

重启电脑,再次查看,这里应该是变成了TkAgg,如果没有变化,那还可以sudo pip uninstall matplotlib 先卸载,然后pip install matplotlib 安装回去,重启电脑,这样就可以确保后端设置变成TkAgg。如此设置后再运行py程序,就完全正常了,下图为博主的运行截图。

这里写图片描述

其实这种程序也是学习pycaffe的好帮手,推荐博文:Caffe Python 接口学习笔记,如果不懂某个函数,记得善用help,比如:

>>>import caffe
>>>help(caffe.io)

Help on module caffe.io in caffe:
NAME
    caffe.io
FILE
    /home/mx/caffe/python/caffe/io.py
CLASSES
    Transformer    
    class Transformer
     |  Transform input for feeding into a Net.
     |  
     |  Note: this is mostly for illustrative purposes and it is likely better
     |  to define your own input preprocessing routine for your needs.
     |  
     |  Parameters
     |  ----------
     |  net : a Net for which the input should be prepared
     |  
     |  Methods defined here:
     |  
  
  
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

附:
ssd_detect.ipynb 可运行版
ssd_detect.py

—————————————–分割线————————————-

关于ssd_detect.cpp

好像有部分同学比较关心ssd的C++检测图片程序,也就是ssd_detect.cpp的用法。我们知道,C++程序要经过编译,生成可执行程序才能进行使用(把它作为一个类来调用则是另外一回事了),这个cpp理论上也是可以编译的,有评论说Eclipse中实现了编译,前提是你要会配置那些依赖项,我尝试用“g++ -o ssd_detect ssd_detect.cpp”来进行编译,发现一直报错,主要是找不到需要的include项,很自然的想到添加CPLUS_INCLUDE_PATH环境变量来解决,可是后来又遇到google proto等等的问题,凭我这种三流水平只能投降了,暂时宣告手动编译cpp失败。

其实呢,这个cpp最好是通过make命令(Makefile文件指定包含目录和依赖项等)编译。所以,我们在配置caffe阶段make all的时候,已经从ssd_detect.cpp生成了可执行的二进制文件(留意make all命令的终端显示就可知道),也就是ssd的C++接口程序,路径就在caffe/build/examples/ssd/ssd_detect.bin。那好,我们先看一下它的用法。

ps:最新博客已经实现了eclipse的SSD配置,可以移步:Ubuntu 16.04使用Eclipse运行SSD-Caffe的cpp代码

终端输入:

$ cd caffe
$ build/examples/ssd/ssd_detect.bin
#使用方法说明
ssd_detect.bin: Do detection using SSD mode.
Usage:
    ssd_detect [FLAGS] model_file weights_file list_file


  Flags from examples/ssd/ssd_detect.cpp:
    -confidence_threshold (Only store detections with score higher than the
      threshold.) type: double default: 0.01
    -file_type (The file type in the list_file. Currently support image and
      video.) type: string default: "image"
    -mean_file (The mean file used to subtract from the input image.)
      type: string default: ""
    -mean_value (If specified, can be one value or can be same as image
      channels - would subtract from the corresponding channel). Separated by
      ','.Either mean_file or mean_value should be provided, not both.)
      type: string default: "104,117,123"
    -out_file (If provided, store the detection results in the out_file.)
      type: string default: ""
  
  
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

可以看到,该程序需要三个必选参数以及一些可选参数,必选参数首先是model_file,也就是检测模型描述文件;然后是weights_file,网络权值文件;list_file,待检测文件,格式为txt,里面列出检测图片/视频的路径。可选参数包括阈值、文件格式、均值文件、图片均值、输出文件这些,都有解释,一看就懂。

运行一个命令试试:

$ cd caffe
$ build/examples/ssd/ssd_detect.bin models/VGGNet/VOC0712/SSD_300x300/deploy.prototxt models/VGGNet/VOC0712/SSD_300x300/VGG_VOC0712_SSD_300x300_iter_120000.caffemodel examples/images/test.txt 
  
  
   
  • 1
  • 2

其中test.txt内容为“examples/images/cat.jpg”,是待检测图片的路径,可以写多行。

呵呵,又报错了:“ImportError: libcaffe.so.1.0.0-rc3: cannot open shared object file: No such file or directory”,还好这个错误在本人知识范围内,也就是静态链接库的问题,so easy。

$ cd /etc/ld.so.conf.d
$ sudo vi caffe.conf 
# conf文件加入 /home/mx/caffe/.build_release/lib,保存退出
sudo ldconfig
  
  
   
  • 1
  • 2
  • 3
  • 4

也有可能会出现这种错误:terminate called after throwing an instance of ‘boost::filesystem::filesystem_error’ what(): boost::filesystem::create_directories: Permission denied: “/home-2/wliu/data/VOCdevkit/results/VOC2007/SSD_300x300”。原因是作者提供的最新SSD300模型中deploy.prototxt里面有些东西(代码如下)没有删干净,找到最后一层,直接把超参数save_output_param整个删掉(也可以替换为个人路径)。

save_output_param {
      output_directory: "/home-2/wliu/data/VOCdevkit/results/VOC2007/SSD_300x300/Main" output_name_prefix: "comp4_det_test_" output_format: "VOC" label_map_file: "data/VOC0712/labelmap_voc.prototxt" name_size_file: "data/VOC0712/test_name_size.txt" num_test_image: 4952 } #deploy.prototxt的错误代码,里面是原作者个人路径,可以直接删除
  
  
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

然后重新运行检测命令,这次有结果了:examples/images/cat.jpg 8 0.999853 163 38 350 358

这个C++程序目前只能得到这样的描述结果,想要可视化的结果要么写一个程序读取里面的文本信息,然后用opencv画框;也可以修改源cpp程序重新编译,这个还没尝试,等有空了研究。

复杂一些的例子,检测视频(得到的结果也是每一帧的文本描述),改变阈值并保存检测结果:

$ build/examples/ssd/ssd_detect.bin models/VGGNet/VOC0712/SSD_300x300/deploy.prototxt models/VGGNet/VOC0712/SSD_300x300/VGG_VOC0712_SSD_300x300_iter_120000.caffemodel examples/videos/test.txt --file_type video --out_file output.txt --confidence_threshold 0.4 #检测视频,阈值为0.4并保存结果
  
  
   
  • 1

ssd_detect.cpp检测结果的可视化

之前博主说过,只用ssd_detect.bin检测图片,只能得到一些文本描述结果,大家想要的其实是可视化的带框图片。原本还想自己写一个小程序实现,结果是我想多了,作者已经在新一版的SSD中增加了这一功能,具体而言,就是examples/ssd/plot_detections.py文件。下面来说说怎么用。

首先想到这个py文件多半是读取一些参数(examples/images/cat.jpg 8 0.999853 163 38 350 358这种)才能画框,那么打开这个py文件,找一下接口部分:

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
            description = "Plot the detection results output by ssd_detect.")
    parser.add_argument("resultfile",
            help = "A file which contains all the detection results.")
    parser.add_argument("imgdir",
            help = "A directory which contains the images.")
    parser.add_argument("--labelmap-file", default="",
            help = "A file which contains the LabelMap.")
    parser.add_argument("--visualize-threshold", default=0.01, type=float,
            help = "Display detections with score higher than the threshold.")
    parser.add_argument("--save-dir", default="",
            help = "A directory which saves the image with detection results.")
    parser.add_argument("--display-classes", default=None,
            help = "If provided, only display specified class. Separate by ','")
  
  
   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15

果不其然,包含2个必选参数和4个可选参数。必选参数是检测结果文件txt、原始图片文件夹;可选参数有labelmap.prototxt、筛选阈值、保存路径、特定的类别(比如只显示汽车的检测结果)。

先前已经用ssd_detect.bin得到了自带图片的检测结果,存为result.txt:

examples/images/cat.jpg 8 0.999429 169 26 347 356
examples/images/cropped_panda.jpg 12 0.975958 0 1 95 97
examples/images/fish-bike.jpg 2 0.717551 52 81 448 307
examples/images/fish-bike.jpg 15 0.99994 204 3 344 170
  
  
   
  • 1
  • 2
  • 3
  • 4

下面开工,用一下这个py文件:

$ python examples/ssd/plot_detections.py examples/images/result.txt examples/images --labelmap-file data/VOC0712/labelmap_voc.prototxt --save-dir examples/
  
  
   
  • 1

立马报错:

examples/images/examples/images/cat.jpg does not exist
examples/images/examples/images/cropped_panda.jpg does not exist
examples/images/examples/images/fish-bike.jpg does not exist

看来图片路径没对,txt中已经有了图片路径,造成路径重复,这个参数不能这么写,但是不写肯定不行。动下脑筋,变成绝对路径不就行了吗。

$ python examples/ssd/plot_detections.py examples/images/result.txt /home/mx/caffe --labelmap-file data/VOC0712/labelmap_voc.prototxt --save-dir examples/
  
  
   
  • 1

现在好了,在examples文件夹下找到了三张图片,已经画好框,大功告成。
这里写图片描述
这里写图片描述
这里写图片描述



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

智能推荐

oracle 12c 集群安装后的检查_12c查看crs状态-程序员宅基地

文章浏览阅读1.6k次。安装配置gi、安装数据库软件、dbca建库见下:http://blog.csdn.net/kadwf123/article/details/784299611、检查集群节点及状态:[root@rac2 ~]# olsnodes -srac1 Activerac2 Activerac3 Activerac4 Active[root@rac2 ~]_12c查看crs状态

解决jupyter notebook无法找到虚拟环境的问题_jupyter没有pytorch环境-程序员宅基地

文章浏览阅读1.3w次,点赞45次,收藏99次。我个人用的是anaconda3的一个python集成环境,自带jupyter notebook,但在我打开jupyter notebook界面后,却找不到对应的虚拟环境,原来是jupyter notebook只是通用于下载anaconda时自带的环境,其他环境要想使用必须手动下载一些库:1.首先进入到自己创建的虚拟环境(pytorch是虚拟环境的名字)activate pytorch2.在该环境下下载这个库conda install ipykernelconda install nb__jupyter没有pytorch环境

国内安装scoop的保姆教程_scoop-cn-程序员宅基地

文章浏览阅读5.2k次,点赞19次,收藏28次。选择scoop纯属意外,也是无奈,因为电脑用户被锁了管理员权限,所有exe安装程序都无法安装,只可以用绿色软件,最后被我发现scoop,省去了到处下载XXX绿色版的烦恼,当然scoop里需要管理员权限的软件也跟我无缘了(譬如everything)。推荐添加dorado这个bucket镜像,里面很多中文软件,但是部分国外的软件下载地址在github,可能无法下载。以上两个是官方bucket的国内镜像,所有软件建议优先从这里下载。上面可以看到很多bucket以及软件数。如果官网登陆不了可以试一下以下方式。_scoop-cn

Element ui colorpicker在Vue中的使用_vue el-color-picker-程序员宅基地

文章浏览阅读4.5k次,点赞2次,收藏3次。首先要有一个color-picker组件 <el-color-picker v-model="headcolor"></el-color-picker>在data里面data() { return {headcolor: ’ #278add ’ //这里可以选择一个默认的颜色} }然后在你想要改变颜色的地方用v-bind绑定就好了,例如:这里的:sty..._vue el-color-picker

迅为iTOP-4412精英版之烧写内核移植后的镜像_exynos 4412 刷机-程序员宅基地

文章浏览阅读640次。基于芯片日益增长的问题,所以内核开发者们引入了新的方法,就是在内核中只保留函数,而数据则不包含,由用户(应用程序员)自己把数据按照规定的格式编写,并放在约定的地方,为了不占用过多的内存,还要求数据以根精简的方式编写。boot启动时,传参给内核,告诉内核设备树文件和kernel的位置,内核启动时根据地址去找到设备树文件,再利用专用的编译器去反编译dtb文件,将dtb还原成数据结构,以供驱动的函数去调用。firmware是三星的一个固件的设备信息,因为找不到固件,所以内核启动不成功。_exynos 4412 刷机

Linux系统配置jdk_linux配置jdk-程序员宅基地

文章浏览阅读2w次,点赞24次,收藏42次。Linux系统配置jdkLinux学习教程,Linux入门教程(超详细)_linux配置jdk

随便推点

matlab(4):特殊符号的输入_matlab微米怎么输入-程序员宅基地

文章浏览阅读3.3k次,点赞5次,收藏19次。xlabel('\delta');ylabel('AUC');具体符号的对照表参照下图:_matlab微米怎么输入

C语言程序设计-文件(打开与关闭、顺序、二进制读写)-程序员宅基地

文章浏览阅读119次。顺序读写指的是按照文件中数据的顺序进行读取或写入。对于文本文件,可以使用fgets、fputs、fscanf、fprintf等函数进行顺序读写。在C语言中,对文件的操作通常涉及文件的打开、读写以及关闭。文件的打开使用fopen函数,而关闭则使用fclose函数。在C语言中,可以使用fread和fwrite函数进行二进制读写。‍ Biaoge 于2024-03-09 23:51发布 阅读量:7 ️文章类型:【 C语言程序设计 】在C语言中,用于打开文件的函数是____,用于关闭文件的函数是____。

Touchdesigner自学笔记之三_touchdesigner怎么让一个模型跟着鼠标移动-程序员宅基地

文章浏览阅读3.4k次,点赞2次,收藏13次。跟随鼠标移动的粒子以grid(SOP)为partical(SOP)的资源模板,调整后连接【Geo组合+point spirit(MAT)】,在连接【feedback组合】适当调整。影响粒子动态的节点【metaball(SOP)+force(SOP)】添加mouse in(CHOP)鼠标位置到metaball的坐标,实现鼠标影响。..._touchdesigner怎么让一个模型跟着鼠标移动

【附源码】基于java的校园停车场管理系统的设计与实现61m0e9计算机毕设SSM_基于java技术的停车场管理系统实现与设计-程序员宅基地

文章浏览阅读178次。项目运行环境配置:Jdk1.8 + Tomcat7.0 + Mysql + HBuilderX(Webstorm也行)+ Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。项目技术:Springboot + mybatis + Maven +mysql5.7或8.0+html+css+js等等组成,B/S模式 + Maven管理等等。环境需要1.运行环境:最好是java jdk 1.8,我们在这个平台上运行的。其他版本理论上也可以。_基于java技术的停车场管理系统实现与设计

Android系统播放器MediaPlayer源码分析_android多媒体播放源码分析 时序图-程序员宅基地

文章浏览阅读3.5k次。前言对于MediaPlayer播放器的源码分析内容相对来说比较多,会从Java-&amp;amp;gt;Jni-&amp;amp;gt;C/C++慢慢分析,后面会慢慢更新。另外,博客只作为自己学习记录的一种方式,对于其他的不过多的评论。MediaPlayerDemopublic class MainActivity extends AppCompatActivity implements SurfaceHolder.Cal..._android多媒体播放源码分析 时序图

java 数据结构与算法 ——快速排序法-程序员宅基地

文章浏览阅读2.4k次,点赞41次,收藏13次。java 数据结构与算法 ——快速排序法_快速排序法