windows下的纯c++版 Faster-Rcnn

来源:互联网 发布:手机怎样制作软件 编辑:程序博客网 时间:2024/06/08 20:06

     效果如下图:


源码已经放在github上,https://github.com/huaze555,支持训练和测试,自己下载用VS2013编译即可,编译步骤跟微软版的caffe一模一样。


******************************我是分割线*************************************

我的上一篇博客 纯C++版的Faster-Rcnn(通过caffe自定义RPN层实现) 是在windows下caffe的基础上,通过自定义RPN层取代python层,实现纯c++版的windows faster-rcnn,具体可以看上一篇博客,它的毛病是,在速度方面远不如python版,不太符合工程需要,比如我最近的项目中,需要对连续的视频帧进行目标检测,那样对效率要求就很高。

      这里介绍的版本,效率达到python版,在windows下,NVIDIA1060 6GB的显卡上,对于VGG16模型的速度是5fps左右,对于VGG_M中型网络是12-14fps,和linux下的python版接近一致。

     这个版本,参照的是D-X-Y大神github上的纯c++版的faster-rcnn,https://github.com/D-X-Y/caffe-faster-rcnn,不过是在linux平台上,我把它移植到微软的windows-caffe版本下,但是由于D-X-Y的版本,因为需要支持faster-rcnn,所以修改了caffe的源码(比如在blob.hpp里就加了点代码),同时添加了很多的代码文件以支持faster-rcnn,所以一个移植的方法,就是把D-X-Y的版本中的代码,全部替换掉微软的版本,然后按照微软的caffe版本,用vs2013进行编译,只要编译libcaffe就好了(我记得移植这个过程,花了七八个小时吧,因为两个版本的不兼容,不断地尝试,不断地改错,编译一次才知道错误在哪,改正后又会不断的出现问题),因为都是哪里有错改正继续试,所以具体编译过程我也没有记录下来,这里我就直接放出编译好的文件,大家直接在VS2013调用就行了,就像使用OpenCV一样。

    环境要求:VS2013

     库文件已经打包好了caffe和faster-rcnn以及需要的第三方库,百度云链接http://pan.baidu.com/s/1hs5tLyc 密码 sbq1

    打开后有3个文件夹和2个文件,3个文件夹分别 bin、include、lib,分别对应可执行文件,头文件,库文件

    就像vs2013配置OpenCV一样的,用vs2013创建控制台应用程序,注意这里需要选择x64 release版,然后项目属性->配置属性->VC++目录,在包含目录里添加上面的include文件夹,注意如果要用GPU,需要把cuda的头文件也添加进去,库目录里添加上面的lib文件夹,也要把你机器上的cuda的库目录添加进去,然后在链接器->输入->附加依赖项,填上

libboost_date_time-vc120-mt-1_59.liblibboost_filesystem-vc120-mt-1_59.liblibboost_system-vc120-mt-1_59.liblibglog.liblibcaffe.libgflags.libgflags_nothreads.libhdf5.libhdf5_hl.liblibprotobuf.liblibopenblas.dll.aShlwapi.libopencv_core2410.libopencv_highgui2410.libopencv_imgproc2410.libLevelDb.liblmdb.libopencv_video2410.libopencv_objdetect2410.libcublas.libcuda.libcublas_device.libcudart.libcudart_static.libcurand.libkernel32.lib
表示程序可能需要用到lib文件夹里的这些库文件,当然就是缺什么库,就需要填哪个库,要不然程序怎么知道需要用哪个呢。

最后,在计算机的系统变量path中,添加上面的bin文件夹,使得程序可以找到可执行文件,当然,也可以直接把bin文件夹的文件全部复制到vs项目中的代码目录下。

到此,环境配置好了,现在添加代码测试一下吧。

           在vs2013项目中,添加main.cpp,代码如下:

#include <caffe\frcnn_api.hpp>  //目标检测头文件#include <opencv2\opencv.hpp> #include "Register.h"           //这个文件不能少,用于注册相关caffe层using namespace std;using namespace cv;using namespace caffe::Frcnn;int main(){VideoCapture capture("3.mp4");   //打开视频文件Mat frame;//初始化目标检测器,构造函数中,四个参数分别为//1、网络配置文件//2、训练好的检测model//3、目标检测参数文件,比如目标检测阈值,NMS阈值//4、是否开启GPU模型,默认为true,表示开启GPU,false表示用CPUFRCNN_API::Detector detect("vgg_m_test.prototxt", "vgg_m.caffemodel", "default_config.json", true);while (true){capture >> frame;vector<BBox<float> > boxes;  //检测结果保存在这detect.predict(frame, boxes);    //对图片帧frame进行目标检测,保存的结果框,存在boxes中for (int i = 0; i < boxes.size(); i++)   //画框cv::rectangle(frame, cv::Point(boxes[i][0], boxes[i][1]), cv::Point(boxes[i][2], boxes[i][3]), Scalar(0, 0, 255));imshow("", frame);waitKey(1);}return 0;}
代码都添加了注释,简单易懂。需要注意的是,一定要在项目中添加头文件Register.h,这个文件在百度云网盘中,用于注册相关的layer,否则caffe不识别,会报错。
代码中用到的 FRCNN_API::Detector 类,在frcnn_api.hpp文件中定义了,定义如下
#ifndef CAFFE_FRCNN_API_HPP_#define CAFFE_FRCNN_API_HPP_#include <vector>#include <string>#include <boost/make_shared.hpp>#include <boost/shared_ptr.hpp>#include <opencv2/core/core.hpp>#include <opencv2/highgui/highgui.hpp>#include <opencv2/imgproc/imgproc.hpp>#include "caffe/blob.hpp"#include "caffe/common.hpp"#include "caffe/layer.hpp"#include "caffe/net.hpp"#include "caffe/util/frcnn_param.hpp"#include "caffe/util/frcnn_helper.hpp"namespace FRCNN_API{using std::vector;using caffe::Blob;using caffe::Net;using caffe::Frcnn::FrcnnParam;using caffe::Frcnn::Point4f;using caffe::Frcnn::BBox;class Detector {public:  Detector(const std::string &proto_file, const std::string &model_file, const std::string& config_file,bool useGPU=true);  void Set_Model(const std::string &proto_file, const std::string &model_file);  void predict(const cv::Mat &img_in, vector<BBox<float> > &results);  void predict_original(const cv::Mat &img_in, vector<BBox<float> > &results);  void predict_iterative(const cv::Mat &img_in, vector<BBox<float> > &results);private:  void preprocess(const cv::Mat &img_in, const int blob_idx);  void preprocess(const vector<float> &data, const int blob_idx);  vector<boost::shared_ptr<Blob<float> > > predict(const vector<std::string> blob_names);  boost::shared_ptr<Net<float> > net_;  float mean_[3];  int roi_pool_layer;};}#endif


第三个参数文件,也在百度云里的文件夹里,可以根据自己需要修改参数。

OK了,有需要的伙伴可以配置一下跑一下,对于有工程需要(特别是c++环境)的朋友,还是很有帮助的。