2016-06-22 160 views
0

目前我正在開發一個應用程序,該程序可以實時檢測直播中的人員。因此我使用OpenCV 3.1的C++。我的方法是訓練SVM並使用HOG檢測器。在OpenCV中訓練SVM

我認爲當我訓練SVM時,特別是通過構建訓練矩陣,會出現問題。我的探測器加載創建的SVM並將其與hog.detectMultiscale()一起使用。使用來自opencv'getDefaulPeopleDetector'的default-svm,我在簡單的圖片上獲得了一些好的結果。

我需要應用自我訓練的SVM,因爲我們的測試設置看起來相當困難,默認設置不包含它。 通過執行我的檢測器獲得的結果非常糟糕,f.e.在覆蓋的攝像頭/黑屏上檢測「人員」或在整個屏幕上隨機檢測。

這裏是我的代碼:

getImages負載每張圖片的目錄並檢查其大小爲coorect(64x128)

//Reads and checks the images from the given directory 
static void getImages(vector<string>& fileNames, const string dirName) { 
    DIR *dir; 
    dir = opendir(dirName.c_str()); 
    struct dirent *ent; 
    string imgName; 
    string imgPath; 
    Mat img; 


    if (dir != NULL) { 
     while ((ent = readdir (dir)) != NULL) { 
     imgName = ent->d_name; 
      imgPath = dirName + "/" +imgName; 
     img = imread(imgPath); 
      if(!img.data) { 
     cout << imgPath << " has no data" << endl;  
      } else { 
      if(img.rows != IMG_ROW_SIZE && img.cols != IMG_COL_SIZE) { 
      cout << imgName << " size not correct: " << img.cols << "x" << img.rows <<endl; 
      } else { 
      cout << imgPath << " loaded" << endl; 
      fileNames.push_back(imgPath); 
      } 
      } 
     } 
     closedir (dir); 
    } else { 
     cout << dirName << " not present" << endl; 
    } 
} 

在這種方法中,我創建它使用SVM訓練矩陣。培養()。 對於每個圖像我計算豬的特徵。一個特徵矢量被插入到訓練矩陣的一行中。 所以每一行都包含一個圖像的特徵。 我不知道,如果hogfeatures的計算是正確實現,或者在路上不創建矩陣在這個崗位(SVM with images

static void initTrainingMats(Mat& trainingMat, vector<string>& positiveImages, vector<string>& negativeImages, Mat& labelMat) { 
HOGDescriptor hog; 
vector<float> hogFeature; 
Mat img; 

cout << "computing hog features.. "; 
for(int i = 0; i<trainingMat.rows; i ++) { // for-loop iterating through all images 
img = (i < positiveImages.size() ? imread(positiveImages.at(i)) : imread(negativeImages.at(i-positiveImages.size()))); 
labelMat.at<float>(i,1) = (i < positiveImages.size() ? 1 : -1); 
hog.compute(img, hogFeature, Size(8,8), Size(8,8)); 
for(int j = 0; j<trainingMat.cols; j++) { 
    trainingMat.at<float>(i,j) = hogFeature.at(j);  
} 
} 

這是我的主要方法所示。初始化SVM並保存。

int main(int, char**) 
{ 
    //vectors to store file path to each correct image 
    vector<string> positiveImages; 
    vector<string> negativeImages; 
    getImages(positiveImages, posDirName); 
    getImages(negativeImages, negDirName); 
    int allImages = positiveImages.size() + negativeImages.size(); 

    //initialize training matrix and label matrix 
    Mat trainingMat(allImages, 3780 ,CV_32FC1); //matrix with column size same as size of hog_sample vector 
    Mat labelMat(allImages, 1, CV_32SC1); 
    initTrainingMats(trainingMat, positiveImages, negativeImages, labelMat); 


    Ptr<SVM> svm = SVM::create(); 
    svm->setType(SVM::C_SVC); 
    svm->setKernel(SVM::LINEAR); 
    svm->setTermCriteria(TermCriteria(TermCriteria::MAX_ITER, 100, 1e-10)); 
    svm->train(trainingMat, ROW_SAMPLE, labelMat); 
    svm->save("../../hog_video/build/svm_v2"); 

    cout<<"SVM stored successfully" << endl; 
    } 

我有點卡在這裏,我很高興你們爲我提供的每一個幫助/建議!

回答

0

首先你需要確保你瞭解它是如何工作的。這是一個2D數據集的例子:

#include <opencv2/core/core.hpp> 
#include <opencv2/highgui/highgui.hpp> 
#include <opencv2/ml/ml.hpp> 

using namespace cv; 

int main() 
{ 
    // Data for visual representation 
    int width = 512, height = 512; 
    Mat image = Mat::zeros(height, width, CV_8UC3); 

    // Set up training data 
    float labels[4] = {1.0, -1.0, -1.0, -1.0}; 
    Mat labelsMat(4, 1, CV_32FC1, labels); 

    float trainingData[4][2] = { {501, 10}, {255, 10}, {501, 255}, {10, 501} }; 
    Mat trainingDataMat(4, 2, CV_32FC1, trainingData); 

    // Set up SVM's parameters 
    CvSVMParams params; 
    params.svm_type = CvSVM::C_SVC; 
    params.kernel_type = CvSVM::LINEAR; 
    params.term_crit = cvTermCriteria(CV_TERMCRIT_ITER, 100, 1e-6); 

    // Train the SVM 
    CvSVM SVM; 
    SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params); 

    Vec3b green(0,255,0), blue (255,0,0); 
    // Show the decision regions given by the SVM 
    for (int i = 0; i < image.rows; ++i) 
     for (int j = 0; j < image.cols; ++j) 
     { 
      Mat sampleMat = (Mat_<float>(1,2) << j,i); 
      float response = SVM.predict(sampleMat); 

      if (response == 1) 
       image.at<Vec3b>(i,j) = green; 
      else if (response == -1) 
       image.at<Vec3b>(i,j) = blue; 
     } 

    // Show the training data 
    int thickness = -1; 
    int lineType = 8; 
    circle(image, Point(501, 10), 5, Scalar( 0, 0, 0), thickness, lineType); 
    circle(image, Point(255, 10), 5, Scalar(255, 255, 255), thickness, lineType); 
    circle(image, Point(501, 255), 5, Scalar(255, 255, 255), thickness, lineType); 
    circle(image, Point(10, 501), 5, Scalar(255, 255, 255), thickness, lineType); 

    // Show support vectors 
    thickness = 2; 
    lineType = 8; 
    int c  = SVM.get_support_vector_count(); 

    for (int i = 0; i < c; ++i) 
    { 
     const float* v = SVM.get_support_vector(i); 
     circle(image, Point((int) v[0], (int) v[1]), 6, Scalar(128, 128, 128), thickness, lineType); 
    } 

    imwrite("result.png", image);  // save the image 

    imshow("SVM Simple Example", image); // show it to the user 
    waitKey(0); 

}