2016-06-22 8 views
0

현재 실시간 스트리밍에있는 사람들을 감지해야하는 프로그램을 만들고 있습니다. 따라서 OpenCV 3.1에서 C++을 사용하고 있습니다. 내 접근 방식은 SVM을 훈련시키고 HOG Detector를 사용하는 것이다.OpenCV의 SVM 교육

나는 특히 trainingmatrix를 구축하여 SVM을 교육 할 때 문제가 발생한다고 생각합니다. My Detector는 생성 된 SVM을로드하고 hog.detectMultiscale()과 함께 사용합니다. opencv 'getDefaulPeopleDetector'의 default-svm을 사용하면 쉬운 그림으로 좋은 결과를 얻을 수 있습니다.

우리가 테스트 한 설정이 매우 어려워서 기본 설정이 적용되지 않기 때문에 자체 훈련 된 SVM을 적용해야 할 필요가 있습니다. 탐지기를 실행하여 얻은 결과는 매우 나쁩니다. 덮힌 웹캠/검은 색 화면에서 '사람'을 감지하거나 전체 화면에서 무작위로 탐지합니다. 여기

내 코드입니다 : 크기가 coorect 경우

getImages의 디렉토리에서로드 모든 사진 및 검사 (64x128) 나는 SVM 사용하는 훈련 행렬을 작성이 방법

//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; 
    } 
} 

.기차(). 모든 이미지에 대해 나는 돼지 기능을 계산합니다. 하나의 특징 벡터가 학습 행렬의 한 행에 삽입됩니다. 모든 행에는 하나의 이미지 기능이 포함되어 있습니다. 나는 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); 

}