zoukankan      html  css  js  c++  java
  • opencv 3.0 DPM Cascade 检测 (附带TBB和openMP加速)

    opencv 3.0 DPM cascade contrib模块

    转载请注明出处,楼燚(yì)航的blog,http://www.cnblogs.com/louyihang-loves-baiyan/

    在opencv3.0 中 加入DPM检测的C++代码,目前开源的DPMC++代码不多,在2.4的opencv 版本中,DPM模块中在检测时用的是latentSVM,这个是标准的DPM matlab源码中使用的分类器,不过在在voc_release 5.01版本中已经也加入了cascade。这一版本的C++ DPM也加入了级联分类器,并做了TBB和openMP加速,先晒一张TBB加速后的图
    x64, release 开启TBB加速,TBB加速的效果比较明显,在0.5S左右

    目前工程化的代码比较少,在这之前我还试了yuxiaoguo 的DPM代码,这里我放一个链接yuxiaoguo,作者的硕士毕设完成的是将DPM源码实现了C++的版本,并做了不少优化。
    首先感谢这么有奉献精神的人士,让大家在学习应用DPM的时候有了更多的资源,他已经开源了,相关的代码可以在其博客上下到,首先的性能还不错。

    今天我主要说一下怎么跑opencv 3.0 中的DPM代码,需要说明的是在3.0模块中,DPm的相关部分已经被剥离了,在opencv_contrib这个模块中,这里给出模块的github链接,必须到上面去下,原始的3.0SDK中已经没有了
    下面是链接
    https://github.com/Itseez/opencv_contrib

    你可以直接把代码建工程,链接到相应的另外的opencv库,也可以直接把模块编译进去,生成库文件
    生成库文件的具体步骤如下:
    http://segmentfault.com/a/1190000003496009
    但是我跟着步骤,用cmake做了configure,去除了部分没有的选项,添加了额外的contrib module,configure generate没有任何报错,在用visual studio 2013 打开工程,在cmake targets 中直接Build install,生成的时候报了不少错,因为着急看效果,因此也懒得折腾了,如果谁有碰到opencv编译报错,可以把相关的处理过程贴一下。

    DPM +TBB and openMP

    这一版本的opencv DPM检测代码加入了TBB并行加速和openMP并行加速,有个开关可以控制

    开启TBB加速

    需要定义HAVE_TBB这个宏,不想在文件里加的话,直接全局生效,右键点击工程-->属性-->c/c++-->预处理器-->预处理器定义,点击下拉框中的编辑里天机即可

    接着还需要下载tbb这个库,TBB是英特尔推出的并行库
    这里是官网链接https://www.threadingbuildingblocks.org
    具体的配置我就不再详述了,跟opencv 配置一样,添加path变量,在工程属性页中添加include头文件路径和相应的库目录和链接的库名字


    开启openMP加速

    直接在工程的属性页中C++页卡,语言下面选择openMP支持即可

    因此我这里选择了直接建立工程,直接把项目clone 到本地,打开DPM的文件夹,
    建立工程列表如下:

    主函数:

    #include "dpm.hpp"
    #include <opencv2/core.hpp>
    #include <opencv2/imgproc.hpp>
    #include <opencv2/highgui.hpp>
    
    #include <stdio.h>
    #include <iostream>
    #include <fstream>
    
    using namespace cv;
    using namespace cv::dpm;
    using namespace std;
    
    int save_results(const string id, const vector<DPMDetector::ObjectDetection> ds, ofstream &out);
    
    static void help()
    {
        cout << "
    This example shows object detection on image sequences using "Deformable Part-based Model (DPM) cascade detection API
    "
           "Call:
    "
           "./example_dpm_cascade_detect_sequence <model_path> <image_dir>
    "
           "The image names has to be provided in "files.txt" under <image_dir>.
    "
           << endl;
    }
    
    static bool readImageLists( const string &file, vector<string> &imgFileList)
    {
        ifstream in(file.c_str(), ios::binary);
    
        if (in.is_open())
        {
            while (in)
            {
                string line;
                getline(in, line);
                imgFileList.push_back(line);
            }
            return true;
        }
        else
        {
            cerr << "Invalid image index file: " << file  << endl;
            return false;
        }
    }
    
    void drawBoxes(Mat &frame,
            vector<DPMDetector::ObjectDetection> ds,
            Scalar color,
            string text);
    
    int main( int argc, char** argv )
    {
        const char* keys =
        {
            "{@model_path    | | Path of the DPM cascade model}"
            "{@image_dir     | | Directory of the images      }"
        };
    
        CommandLineParser parser(argc, argv, keys);
        //string model_path(parser.get<string>(0));
        //string image_dir(parser.get<string>(1));
        //string image_list = image_dir + "/files.txt";
    	
    	string model_path ="D:\WorkSpace\VS_Projects\opencv_dpm\opencv_dpm\inriaperson.xml";
    	string image_dir = "D:\DataSet\INRIAPerson";
    	string image_list = "D:\DataSet\INRIAPerson\Test\pos1.lst";
    
        if( model_path.empty() || image_dir.empty() )
        {
            help();
            return -1;
        }
    
        vector<string> imgFileList;
        if ( !readImageLists(image_list, imgFileList) )
            return -1;
    
    #ifdef HAVE_TBB
        cout << "Running with TBB" << endl;
    #else
    #ifdef _OPENMP
        cout << "Running with OpenMP" << endl;
    #else
        cout << "Running without OpenMP and without TBB" << endl;
    #endif
    #endif
    
        cv::Ptr<DPMDetector> detector = 
        DPMDetector::create(vector<string>(1, model_path));
    
        namedWindow("DPM Cascade Detection", 1);
        // the color of the rectangle
        Scalar color(0, 255, 255); // yellow
        Mat frame;
    
        for (size_t i = 0; i < imgFileList.size(); i++)
        {
            double t = (double) getTickCount();
            vector<DPMDetector::ObjectDetection> ds;
    		
    		string imageFile = image_dir + "\" + imgFileList[i];
    		Mat image = imread(imageFile);
    		
            frame = image.clone();
    
            if (image.empty()) {
                cerr << "
    Invalid image:
    " << imgFileList[i] << endl;
                return -1;
            }
    
            // detection
            detector->detect(image, ds);
            // compute frame per second (fps)
            t = ((double) getTickCount() - t)/getTickFrequency();//elapsed time
    		cout << t << endl;
            // draw boxes
            string text = format("%0.1f fps", 1.0/t);
            drawBoxes(frame, ds, color, text);
    
            // show detections
            imshow("DPM Cascade Detection", frame);
    
    		waitKey(0);
            //if ( waitKey(30) >= 0)
            //    break;
        }
    
        return 0;
    }
    
    void drawBoxes(Mat &frame, 
            vector<DPMDetector::ObjectDetection> ds, Scalar color, string text)
    {
        for (unsigned int i = 0; i < ds.size(); i++)
        {
            rectangle(frame, ds[i].rect, color, 2);
        }
    
        // draw text on image
        Scalar textColor(0,0,250);
        putText(frame, text, Point(10,50), FONT_HERSHEY_PLAIN, 2, textColor, 2);
    }
    
    

    在x64 release 模式下,图像的分辨率480*360,测试的是Inria行人数据集
    不开加速的检测时间如下:大约在0.6~0.7秒之间

    x64, release 开启TBB加速,TBB加速的效果比较明显,在0.5S左右

    x64, release 开启openMP加速,openMP加速不如TBB加速明显,在0.5S~0.6S之间

    代码写的非常规整,有较高的参考价值

  • 相关阅读:
    分布式文件系统--->fastDFS
    varnish4.0缓存代理配置
    varnish4.0缓存代理配置
    varnish4.0缓存代理配置
    SDN 是什么
    SDN 是什么
    SDN 是什么
    Solidworks如何保存为网页可以浏览的3D格式
    github 的 配置SSH
    当一个实例被创建,__init__()就会被自动调用
  • 原文地址:https://www.cnblogs.com/louyihang-loves-baiyan/p/4913164.html
Copyright © 2011-2022 走看看