2015-12-08 79 views
1

我是SVM的新手。我曾經使用HAAR Cascading進行對象檢測。現在我正在嘗試實施SVM以進行對象檢測。我在網上搜索瞭解基礎知識。 我想在編碼C++時使用libsvm。我遇到了很多問題。 任何人都可以請解釋一步一步使用它進行對象檢測的過程。 順便說一下,我看着opencv documentation of svm。但我無法做進一步的工作。使用SVM進行對象檢測

另外我得到了用於培訓我的SVM並將其保存到xml文件中的代碼。 現在我想要一個可以接受這個xml並在測試用例中檢測對象的代碼。

#include <opencv2/core/core.hpp> 
#include <opencv2/imgproc/imgproc.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <cv.h> 
#include <highgui.h> 
#include <cvaux.h> 
#include <iostream> 
#include <vector> 
#include<string.h> 
using namespace std; 
using namespace cv; 

int main (int argc, char** argv) 
{ 
    cout << "OpenCV Training SVM Automatic Number Plate Recognition\n"; 
    cout << "\n"; 

    char* path_Plates; 
    char* path_NoPlates; 
    int numPlates; 
    int numNoPlates; 
    int imageWidth=150; 
    int imageHeight=150; 

    //Check if user specify image to process 
    if(1) 
    { 
     numPlates= 11; 
     numNoPlates= 90 ; 
     path_Plates= "/home/kaushik/opencv_work/Manas6/Pics/Positive_Images/"; 
     path_NoPlates= "/home/kaushik/opencv_work/Manas6/Pics/Negative_Images/i"; 

    }else{ 
     cout << "Usage:\n" << argv[0] << " <num Plate Files> <num Non Plate Files> <path to plate folder files> <path to non plate files> \n"; 
     return 0; 
    } 

    Mat classes;//(numPlates+numNoPlates, 1, CV_32FC1); 
    Mat trainingData;//(numPlates+numNoPlates, imageWidth*imageHeight, CV_32FC1); 

    Mat trainingImages; 
    vector<int> trainingLabels; 

    for(int i=1; i<= numPlates; i++) 
    { 

     stringstream ss(stringstream::in | stringstream::out); 
     ss<<path_Plates<<i<<".jpg"; 
     try{ 

      const char* a = ss.str().c_str(); 
      printf("\n%s\n",a); 
      Mat img = imread(ss.str(), CV_LOAD_IMAGE_UNCHANGED); 
      img= img.clone().reshape(1, 1); 
      //imshow("Window",img); 
      //cout<<ss.str(); 
      trainingImages.push_back(img); 
      trainingLabels.push_back(1); 
     } 
     catch(Exception e){;} 
    } 

    for(int i=0; i< numNoPlates; i++) 
    { 
     stringstream ss(stringstream::in | stringstream::out); 
     ss << path_NoPlates<<i << ".jpg"; 
     try 
     { 
      const char* a = ss.str().c_str(); 
      printf("\n%s\n",a); 
      Mat img=imread(ss.str(), 0); 
      //imshow("Win",img); 
      img= img.clone().reshape(1, 1); 
      trainingImages.push_back(img); 
      trainingLabels.push_back(0); 
      //cout<<ss.str(); 
     } 
     catch(Exception e){;} 
    } 

    Mat(trainingImages).copyTo(trainingData); 
    //trainingData = trainingData.reshape(1,trainingData.rows); 
    trainingData.convertTo(trainingData, CV_32FC1); 
    Mat(trainingLabels).copyTo(classes); 

    FileStorage fs("SVM.xml", FileStorage::WRITE); 
    fs << "TrainingData" << trainingData; 
    fs << "classes" << classes; 
    fs.release(); 

    return 0; 
} 

任何幫助將不勝感激。

此外,我很想就如何實現對象檢測libsvm建議。

回答

1

這是一個簡單的代碼,你可以採取一個測試你的XML文件:

#include "highgui.h" 
#include "opencv2/imgproc/imgproc.hpp" 
#include "cv.h" 
#include <vector> 
#include <string.h> 
#include <ml.h> 
#include <iostream> 

#include <io.h> 
using namespace cv; 
using namespace std; 

int main() 
{ 
    FileStorage fs; 
    fs.open("SVM.xml", FileStorage::READ); 
    Mat trainingData; 
    Mat classes; 
    fs["TrainingData"] >> trainingData; 
    fs["classes"] >> classes; 

    CvSVMParams SVM_params; 
    SVM_params.svm_type = CvSVM::C_SVC; 
    SVM_params.kernel_type = CvSVM::LINEAR; //CvSVM::LINEAR; 
    SVM_params.degree = 1; 
    SVM_params.gamma = 1; 
    SVM_params.coef0 = 0; 
    SVM_params.C = 1; 
    SVM_params.nu = 0; 
    SVM_params.p = 0; 
    SVM_params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 1000, 0.01); 

    CvSVM svm(trainingData, classes, Mat(), Mat(), SVM_params); 


    Mat src = imread("D:\\SVM\\samples\\\pos\\10.jpg"); 
    Mat gray; 
    cvtColor(src, gray, CV_BGR2GRAY); 
    Mat p = gray.reshape(1, 1); 
    p.convertTo(p, CV_32FC1); 

    int response = (int)svm.predict(p); 
    if(response ==1) 
    { 
     cout<<"this is a object!"<<endl; 
     cout<<endl; 
    } 
    else 
    { 
     cout<<"no object detected!"<<endl; 
     cout<<endl; 
    } 

    return 0; 
} 

順便說一下,似乎乳寧你提供的代碼時沒有什麼問題,結果表明:」 opencv errror,圖像步驟錯誤cv :: Mat :: reshape「。你遇到過這種情況嗎?謝謝。