2014-02-13 24 views
2

我在opencv中使用Hog + SVM來檢測視頻avi文件中的汽車。我正在使用car.xml模型文件。 當我用LatentSvmDetetction用於檢測汽車使用LatentSVMDetector從視頻中檢測對象

  • 幀錯誤檢測的大量我沒有收到良好的效果。
  • 這是非常緩慢的。從幀中檢測對象大約需要5秒鐘的時間。

請教我如何提高物體檢測時間。

我的代碼如下:

#include <iostream> 
#include "opencv2/objdetect/objdetect.hpp" 
#include "opencv2/highgui/highgui.hpp" 
#include "opencv2/contrib/contrib.hpp" 

#if defined(WIN32) || defined(_WIN32) 
#include <io.h> 
#else 
#include <dirent.h> 
#endif 

#ifdef HAVE_CVCONFIG_H 
#include <cvconfig.h> 
#endif 

#ifdef HAVE_TBB 
#include "tbb/task_scheduler_init.h" 
#endif 

using namespace std; 
using namespace cv; 

static void detectAndDrawObjects(Mat& frame, LatentSvmDetector& detector, const vector<Scalar>& colors, float overlapThreshold, int numThreads) 
{ 
    vector<LatentSvmDetector::ObjectDetection> detections; 

    TickMeter tm; 
    tm.start(); 
    detector.detect(frame, detections, overlapThreshold, numThreads); 
    tm.stop(); 

    cout << "Detection time = " << tm.getTimeSec() << " sec" << endl; 

    const vector<string> classNames = detector.getClassNames(); 
    CV_Assert(colors.size() == classNames.size()); 

    for(size_t i = 0; i < detections.size(); i++) 
    { 
     const LatentSvmDetector::ObjectDetection& od = detections[i]; 
     rectangle(frame, od.rect, colors[od.classID], 3); 
     putText(frame, classNames[od.classID], Point(od.rect.x+4,od.rect.y+13), FONT_HERSHEY_SIMPLEX, 0.55, colors[od.classID], 2); 
    } 
} 

static void readDirectory(const string& directoryName, vector<string>& filenames, bool addDirectoryName=true) 
{ 
    filenames.clear(); 

#if defined(WIN32) | defined(_WIN32) 
    struct _finddata_t s_file; 
    string str = directoryName + "\\*.*"; 

    intptr_t h_file = _findfirst(str.c_str(), &s_file); 
    if(h_file != static_cast<intptr_t>(-1.0)) 
    { 
     do 
     { 
      if(addDirectoryName) 
       filenames.push_back(directoryName + "\\" + s_file.name); 
      else 
       filenames.push_back((string)s_file.name); 
     } 
     while(_findnext(h_file, &s_file) == 0); 
    } 
    _findclose(h_file); 
#else 
    DIR* dir = opendir(directoryName.c_str()); 
    if(dir != NULL) 
    { 
     struct dirent* dent; 
     while((dent = readdir(dir)) != NULL) 
     { 
      if(addDirectoryName) 
       filenames.push_back(directoryName + "/" + string(dent->d_name)); 
      else 
       filenames.push_back(string(dent->d_name)); 
     } 

     closedir(dir); 
    } 
#endif 

    sort(filenames.begin(), filenames.end()); 
} 

int main() 
{ 
     string frames_folder, models_folder; 
     float overlapThreshold = 0.2f; 
     int numThreads = -1; 
     models_folder = "D:\\Downloads\\models_VOC2007"; 
     VideoCapture cap("D:\\images\\videos\\vid2.AVI"); // open the video file for reading 
     cvNamedWindow("MyVideo", CV_WINDOW_AUTOSIZE); 
     if (!cap.isOpened()) // if not success, exit program 
     { 
      cout << "Cannot open the video file" << endl; 
      return -1; 
     } 

     LatentSvmDetector detector(models_filenames); 
     if(detector.empty()) 
     { 
      cout << "Models cann't be loaded" << endl; 
      exit(-1); 
     } 

     vector<Scalar> colors; 
     generateColors(colors, detector.getClassNames().size()); 

     Mat frame; 
     while(1) 
     { 

      bool bSuccess = cap.read(frame); 
      if (!bSuccess) //if not success, break loop 
      { 
       cout << "Cannot read the frame from video file" << endl; 
       break; 
      } 
      detectAndDrawObjects(frame, detector, colors, overlapThreshold, numThreads); 
      imshow("MyVideo", frame); 
      //imshow("video", frame); //show the frame in "MyVideo" window 
       if(waitKey(30) == 27) //wait for 'esc' key press for 30 ms. If 'esc' key is pressed, break loop 
       { 
       cout << "esc key is pressed by user" << endl; 
       break; 
       } 
     } 
     return 0; 
} 

回答

1

我建議你

  1. 來調整幀的大小10x5像素可能是最小的汽車在幀;
  2. 先做模糊處理;有可能得到大量的誤報,因爲有噪音產生的邊緣可能與汽車相似;
  3. 我認爲探測器是用於側車(我還沒有測試過),它不會檢測到旋轉角度超過60度的汽車,並且它在某些與您的環境不相似的數據庫上搜索;所以也許最好是訓練你自己的探測器(car.xml)。

HOG基於邊緣和邊緣對光線和陰影非常敏感。嘗試在檢測汽車之前對車架進行預處理(對比度增強)。