使用SVM进行人脸识别

时间:2014-03-26 12:47:31

标签: opencv image-processing machine-learning computer-vision face-recognition

我已尝试将SVM用于面部识别,下面是我用于训练和测试的代码。问题是我没有得到准确的结果,有时我总是将预测值设为“0”。

有人可以用正确的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;

}

1 个答案:

答案 0 :(得分:2)

你的代码看起来很脏,所以我不会过去,但我会尝试给你一些提示。

首先,您需要训练集,并确保您有更多的负面训练数据,而不是积极的,以获得良好的结果。另请注意,您需要安静的大量面孔以获得良好的效果,平均或低于平均水平的分类器可能需要大约100-200。

脸部的第二个提取功能,你可以使用颜色,边缘直方图或二进制像Patters等。选择是你的。但少数人的卷积会带来更好的结果。

使用准备好的数据训练SVM并进行预测。

以下是罗伊麻省理工学院学生的链接,他使用SVM训练食物分类器。代码很容易理解,你可以按照它们来获得SVM分类器的要点。

Food Classifier