-2

나는 얼굴 인식을 위해 SVM을 구현하려고 시도했으며 아래는 내가 훈련 및 테스트에 사용한 코드입니다. 문제는 정확한 결과를 얻지 못하고 있고 때때로 예측 값을 "0"으로 얻는 경우입니다.SVM을 사용한 얼굴 인식

올바른 SVM 매개 변수로 나를 도와 줄 수 있습니까?

교육 코드 :

static void read_csv(const string& filename, vector<Mat>& images, vector<int>& label, char separator = ';') { 
    std::ifstream file(filename.c_str(), ifstream::in); 
    if (!file) { 
     string error_message = "No valid input file was given, please check the given filename."; 
     CV_Error(CV_StsBadArg, error_message); 
    } 
    string line, path, classlabel; 
    while (getline(file, line)) { 
     stringstream liness(line); 
     getline(liness, path, separator); 
     getline(liness, classlabel); 
     if(!path.empty() && !classlabel.empty()) { 
      Mat testimage = imread(path, 0); 
      imshow("testimage", testimage); 
      waitKey(10); 
      images.push_back(testimage); 
      label.push_back(atoi(classlabel.c_str())); 
     } 
    } 
} 
int svm() 
{ 
    // Data for visual representation 

    string fn_csv = string("/home/resize.csv"); 
//  These vectors hold the images and corresponding labels. 
    vector<Mat> images; 
    vector<int> label; 
//  Read in the data. This can fail if no valid 
//  input filename is given. 
    try { 
     read_csv(fn_csv, images,label); 
    } catch (cv::Exception& e) { 
     cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl; 
//   nothing more we can do 
     exit(1); 
    } 
    // Set up SVM's parameters 
    Mat labelsMat(label.size(), 1, CV_32FC1); 
     Mat trainingDataMat(images.size(),70*70, CV_32FC1); 

       //iterating through the rows 
     int c=0;int d; 
       for (int j = 0; j <label.size(); j++) { 
        //iteration through the columns 
        d=0; 
        c++; 
        labelsMat.at<float>(j,0)=float(label[j]); 
        for (int r = 0;r<images[j].rows; r++) { 
       //iterating through the rows 
       for (int c = 0; c <images[j].cols; c++) { 
       trainingDataMat.at<float>(j,d++) = images[j].at<uchar>(r,c); 

       } 
        } 
       } 

    //imshow("first",images[7]); 
     cout<<"labels"<<labelsMat<<std::endl; 
    cout<<"labels size"<<c<<std::endl; 
    // CvSVMParams params; 

SVMParams params = SVMParams(); 
params.svm_type = SVM::C_SVC; 
params.kernel_type = SVM::LINEAR; 
params.degree = 3.43; // for poly 
params.gamma = 0.00225; // for poly/rbf/sigmoid 
params.coef0 = 19.6; // for poly/sigmoid 
params.C = 0.5; // for CV_SVM_C_SVC , CV_SVM_EPS_SVR and CV_SVM_NU_SVR 
params.nu = 0.0; // for CV_SVM_NU_SVC , CV_SVM_ONE_CLASS , and CV_SVM_NU_SVR 
params.p = 0.0; // for CV_SVM_EPS_SVR 
params.class_weights = NULL; // for CV_SVM_C_SVC 
params.term_crit.type = CV_TERMCRIT_ITER | CV_TERMCRIT_EPS; 
params.term_crit.max_iter = 1000; 
params.term_crit.epsilon = 1e-6; 

    // Train the SVM 
    CvSVM SVM; 
    SVM.train(trainingDataMat, labelsMat, Mat(), Mat(), params); 
    // cout<<"train row" <<trainingDataMat.rowRange()<<"cols"<<trainingDataMat.cols<<std::endl; 
SVM.save("/home/test.yml"); 

    return 0; 

}

예측 번호 :

int svm_test() 
{ 

    // Train the SVM 
    CvSVM SVM; 

    Mat test=imread("/home/n2.jpg",0); 
// cout<<"image size"<<(float(test.size))<<std::endl; 
Mat test_mat(1,test.cols*test.rows,CV_32FC1); 
    int ii1=0; 
for (int i1 = 0; i1<test.rows; i1++) { 
       //iterating through the rows 

       for (int j1 = 0; j1 < test.cols; j1++) { 
        //iteration through the columns 

       test_mat.at<float>(0,ii1++) = test.at<uchar>(i1,j1); 
       // labels.at<float>(filenum,1);//=float(filenum); 
       } 
      } 
    // waitKey(0); 
SVM.load("/home/smile.yml"); 

cout<<"preditction value"<<SVM.predict(test_mat)<<std::endl; 


    return 0; 

} 

답변

2

당신의 코드가 더러워 보인다는 그래서 나는 그들을 갈하지 않습니다하지만 난 것 그 과정에 대한 몇 가지 힌트를 주려고 노력하십시오.

먼저 훈련 세트가 필요하며 좋은 결과를 얻으려면 긍정적 인 것보다 부정적인 훈련 데이터가 있어야합니다. 또한 좋은 결과를 얻으려면 많은 수의 얼굴을 조용하게해야하며 평균 또는 평균 이하의 단순 분류 자에 대해서는 약 100-200 정도가 필요합니다.

두 번째로 얼굴에서 얼굴을 추출합니다. 색상, 가장자리 히스토그램 또는 이진법과 같은 이진법 등을 사용할 수 있습니다. 선택은 사용자의 선택입니다. 하지만 소수의 컨볼 루션으로 더 나은 결과를 얻을 수 있습니다.

준비된 데이터를 사용하여 SVM을 훈련시키고 예측을 수행하십시오.

다음은 Roy mit 학생이 SVM을 사용하여 음식 분류기를 훈련 한 링크입니다. 코드는 이해하기 쉽고 SVM 분류 자의 요지를 얻기 위해 코드를 따라갈 수 있습니다.

Food Classifier