OpenCV Latent SVM Discriminatively Trained Part Based Models for Object Detection

原文:http://blog.csdn.net/loadstar_kun/article/details/8686416

OpenCV 2.4版本实现了C++版本的DPM程序,和之前C版本的主要区别就是可以同时检测多种目标。使用时,可以把训练好的模型放到一个文件夹中,待检测的图像放到另一个文件夹中,即可检测。

可惜没有考虑加速的内容。

 

Latent SVM

Discriminatively Trained Part Based Models for Object Detection

The object detector described below has been initially proposed by P.F. Felzenszwalb in[Felzenszwalb2010].  It is based on a Dalal-Triggs detector that uses a single filter on histogram of oriented gradients (HOG) features to represent an object category. This detector uses a sliding window approach, where a filter is applied at all positions and scales of an image. The first innovation is enriching the Dalal-Triggs model using a star-structured part-based model defined by a “root” filter (analogous to the Dalal-Triggs filter) plus a set of parts filters and associated deformation models. The score of one of star models at a particular position and scale within an image is the score of the root filter at the given location plus the sum over parts of the maximum, over placements of that part, of the part filter score on its location minus a deformation cost easuring the deviation of the part from its ideal location relative to the root. Both root and part filter scores are defined by the dot product between a filter (a set of weights) and a subwindow of a feature pyramid computed from the input image. Another improvement is a representation of the class of models by a mixture of star models. The score of a mixture model at a particular position and scale is the maximum over components, of the score of that component model at the given location.

In OpenCV there are C implementation of Latent SVM and C++ wrapper of it. C version is the structureCvObjectDetection and a set of functions working with this structure (seecvLoadLatentSvmDetector(),cvReleaseLatentSvmDetector(),cvLatentSvmDetectObjects()). C++ version is the classLatentSvmDetector and has slightly different functionality in contrast with C version - it supports loading and detection of several models.

There are two examples of Latent SVM usage:samples/c/latentsvmdetect.cppandsamples/cpp/latentsvm_multidetect.cpp.

 

代码如下:

[html]  view plain copy
  1. #include <iostream>  
  2. #include "opencv2/objdetect/objdetect.hpp"  
  3. #include "opencv2/highgui/highgui.hpp"  
  4. #include "opencv2/contrib/contrib.hpp"  
  5.   
  6. #ifdef WIN32  
  7. #include <io.h>  
  8. #else  
  9. #include <dirent.h>  
  10. #endif  
  11.   
  12. #ifdef HAVE_CVCONFIG_H  
  13. #include <cvconfig.h>  
  14. #endif  
  15.   
  16. #ifdef HAVE_TBB  
  17. #include "tbb/task_scheduler_init.h"  
  18. #endif  
  19.   
  20. using namespace std;  
  21. using namespace cv;  
  22.   
  23. static void help()  
  24. {  
  25.     cout << "This program demonstrated the use of the latentSVM detector." << endl <<  
  26.             "It reads in a trained object models and then uses them to detect the objects in an images." << endl <<  
  27.              endl <<  
  28.             "Call:" << endl <<  
  29.             "./latentsvm_multidetect <imagesFolder> <modelsFolder> [<overlapThreshold>][<threadsNumber>]" << endl <<  
  30.             "<overlapThreshold> - threshold for the non-maximum suppression algorithm." << endl <<  
  31.             "Example of <modelsFolder> is opencv_extra/testdata/cv/latentsvmdetector/models_VOC2007" << endl <<  
  32.              endl <<  
  33.             "Keys:" << endl <<  
  34.             "'n' - to go to the next image;" << endl <<  
  35.             "'esc' - to quit." << endl <<  
  36.             endl;  
  37. }  
  38.   
  39. static void detectAndDrawObjects( Mat& image, LatentSvmDetector& detector, const vector<Scalar>& colors, float overlapThreshold, int numThreads )  
  40. {  
  41.     vector<LatentSvmDetector::ObjectDetection> detections;  
  42.   
  43.     TickMeter tm;  
  44.     tm.start();  
  45.     detector.detect( image, detections, overlapThreshold, numThreads);  
  46.     tm.stop();  
  47.   
  48.     cout << "Detection time = " << tm.getTimeSec() << " sec" << endl;  
  49.   
  50.     const vector<string> classNames = detector.getClassNames();  
  51.     CV_Assert( colors.size() == classNames.size() );  
  52.   
  53.     for( size_t i = 0; i < detections.size(); i++ )  
  54.     {  
  55.         const LatentSvmDetector::ObjectDetection& od = detections[i];  
  56.         rectangle( image, od.rect, colors[od.classID], 3 );  
  57.     }  
  58.     // put text over the all rectangles  
  59.     for( size_t i = 0; i < detections.size(); i++ )  
  60.     {  
  61.         const LatentSvmDetector::ObjectDetection& od = detections[i];  
  62.         putText( image, classNames[od.classID], Point(od.rect.x+4,od.rect.y+13), FONT_HERSHEY_SIMPLEX, 0.55, colors[od.classID], 2 );  
  63.     }  
  64. }  
  65.   
  66. static void readDirectory( const string& directoryName, vector<string>& filenames, bool addDirectoryName=true )  
  67. {  
  68.     filenames.clear();  
  69.   
  70. #ifdef WIN32  
  71.     struct _finddata_t s_file;  
  72.     string str = directoryName + "\\*.*";  
  73.   
  74.     intptr_t h_file = _findfirst( str.c_str(), &s_file );  
  75.     if( h_file != static_cast<intptr_t>(-1.0) )  
  76.     {  
  77.         do  
  78.         {  
  79.             if( addDirectoryName )  
  80.                 filenames.push_back(directoryName + "\\" + s_file.name);  
  81.             else  
  82.                 filenames.push_back((string)s_file.name);  
  83.         }  
  84.         while( _findnext( h_file, &s_file ) == 0 );  
  85.     }  
  86.     _findclose( h_file );  
  87. #else  
  88.     DIR* dir = opendir( directoryName.c_str() );  
  89.     if( dir != NULL )  
  90.     {  
  91.         struct dirent* dent;  
  92.         while( (dent = readdir(dir)) != NULL )  
  93.         {  
  94.             if( addDirectoryName )  
  95.                 filenames.push_back( directoryName + "/" + string(dent->d_name) );  
  96.             else  
  97.                 filenames.push_back( string(dent->d_name) );  
  98.         }  
  99.     }  
  100. #endif  
  101.   
  102.     sort( filenames.begin(), filenames.end() );  
  103. }  
  104.   
  105. int main(int argc, char* argv[])  
  106. {  
  107.     help();  
  108.   
  109.     string images_folder, models_folder;  
  110.     float overlapThreshold = 0.2f;  
  111.     int numThreads = -1;  
  112.     if( argc > 2 )  
  113.     {  
  114.         images_folder = argv[1];  
  115.         models_folder = argv[2];  
  116.         if( argc > 3 ) overlapThreshold = (float)atof(argv[3]);  
  117.         if( overlapThreshold < 0 || overlapThreshold > 1)  
  118.         {  
  119.             cout << "overlapThreshold must be in interval (0,1)." << endl;  
  120.             exit(-1);  
  121.         }  
  122.   
  123.         if( argc > 4 ) numThreads = atoi(argv[4]);  
  124.     }  
  125.   
  126.     vector<string> images_filenames, models_filenames;  
  127.     readDirectory( images_folder, images_filenames );  
  128.     readDirectory( models_folder, models_filenames );  
  129.   
  130.     LatentSvmDetector detector( models_filenames );  
  131.     if( detector.empty() )  
  132.     {  
  133.         cout << "Models cann't be loaded" << endl;  
  134.         exit(-1);  
  135.     }  
  136.   
  137.     const vector<string>classNames = detector.getClassNames();  
  138.     cout << "Loaded " << classNames.size() << " models:" << endl;  
  139.     for( size_t i = 0; i < classNames.size(); i++ )  
  140.     {  
  141.         cout << i << ") " << classNames[i] << "; ";  
  142.     }  
  143.     cout << endl;  
  144.   
  145.     cout << "overlapThreshold = " << overlapThreshold << endl;  
  146.   
  147.     vector<Scalar> colors;  
  148.     generateColors( colors, detector.getClassNames().size() );  
  149.   
  150.     for( size_t i = 0; i < images_filenames.size(); i++ )  
  151.     {  
  152.         Mat image = imread( images_filenames[i] );  
  153.         if( image.empty() )  continue;  
  154.   
  155.         cout << "Process image " << images_filenames[i] << endl;  
  156.         detectAndDrawObjects( image, detector, colors, overlapThreshold, numThreads );  
  157.   
  158.         imshow( "result", image );  
  159.   
  160.         for(;;)  
  161.         {  
  162.             int c = waitKey();  
  163.             if( (char)c == 'n')  
  164.                 break;  
  165.             else if( (char)c == '\x1b' )  
  166.                 exit(0);  
  167.         }  
  168.     }  
  169.   
  170.     return 0;  
  171. }  

 上传个结果吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值