opencv学习-建立人脸识别分类器

来源:互联网 发布:决战萨斯城 知乎 编辑:程序博客网 时间:2024/05/21 22:42

在sample/cpp下面有一个文件叫做facerec_demo.cpp,还有一个文件叫做facerec_at_t.txt


首先我们要去 AT&T人脸库下载400张图片,分别时40个人,每个人有10张照片

下载完成后,随便放在哪里,但是注意要修改facerec_at_t.txt文件里面的路径,下面是我的文件路径

/home/myname/Desktop/opencv-2.4.7/orl_faces/s13/2.pgm;12
/home/myname/Desktop/opencv-2.4.7/orl_faces/s13/7.pgm;12
/home/myname/Desktop/opencv-2.4.7/orl_faces/s13/6.pgm;12

;后面的12代表类别,如果你要创建自己和同学的人脸库,记住要给不同的人赋予不同的label


然后我们看看facerec_demo.cpp,先贴上源代码

[cpp] view plaincopy在CODE上查看代码片派生到我的代码片
  1. #include "opencv2/core/core.hpp"  
  2. #include "opencv2/highgui/highgui.hpp"  
  3. #include "opencv2/contrib/contrib.hpp"  
  4.   
  5. #include <iostream>  
  6. #include <fstream>  
  7. #include <sstream>  
  8.   
  9. using namespace cv;  
  10. using namespace std;  
  11.   
  12. static void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, char separator = ';') {  
  13.     std::ifstream file(filename.c_str(), ifstream::in);  
  14.     if (!file) {  
  15.         string error_message = "No valid input file was given, please check the given filename.";  
  16.         CV_Error(CV_StsBadArg, error_message);  
  17.     }  
  18.     string line, path, classlabel;  
  19.     while (getline(file, line)) {  
  20.         stringstream liness(line);  
  21.         getline(liness, path, separator);  
  22.         getline(liness, classlabel);  
  23.         if(!path.empty() && !classlabel.empty()) {  
  24.             images.push_back(imread(path, 0));  
  25.             labels.push_back(atoi(classlabel.c_str()));  
  26.         }  
  27.     }  
  28. }  
  29.   
  30. int main(int argc, const char *argv[]) {  
  31.     // Check for valid command line arguments, print usage  
  32.     // if no arguments were given.  
  33.     if (argc != 2) {  
  34.         cout << "usage: " << argv[0] << " <csv.ext>" << endl;  
  35.         exit(1);  
  36.     }  
  37.     // Get the path to your CSV.  
  38.     string fn_csv = string(argv[1]);  
  39.     // These vectors hold the images and corresponding labels.  
  40.     vector<Mat> images;  
  41.     vector<int> labels;  
  42.     // Read in the data. This can fail if no valid  
  43.     // input filename is given.  
  44.     try {  
  45.         read_csv(fn_csv, images, labels);  
  46.     } catch (cv::Exception& e) {  
  47.         cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl;  
  48.         // nothing more we can do  
  49.         exit(1);  
  50.     }  
  51.     // Quit if there are not enough images for this demo.  
  52.     if(images.size() <= 1) {  
  53.         string error_message = "This demo needs at least 2 images to work. Please add more images to your data set!";  
  54.         CV_Error(CV_StsError, error_message);  
  55.     }  
  56.     // Get the height from the first image. We'll need this  
  57.     // later in code to reshape the images to their original  
  58.     // size:  
  59.     int height = images[0].rows;  
  60.     //作为我的唯一test图片  
  61.     Mat testSample = images[images.size() - 1];  
  62.     int testLabel = labels[labels.size() - 1];  
  63.     images.pop_back();  
  64.     labels.pop_back();  
  65.   
  66.     Ptr<FaceRecognizer> model = createEigenFaceRecognizer();  
  67.     model->train(images, labels);  
  68.     // The following line predicts the label of a given  
  69.     // test image:  
  70.     int predictedLabel = model->predict(testSample);  
  71.     //  
  72.     // To get the confidence of a prediction call the model with:  
  73.     //  
  74.     //      int predictedLabel = -1;  
  75.     //      double confidence = 0.0;  
  76.     //      model->predict(testSample, predictedLabel, confidence);  
  77.     //  
  78.     string result_message = format("Predicted class = %d / Actual class = %d.", predictedLabel, testLabel);  
  79.     cout << result_message << endl;  
  80.     waitKey(0);  
  81.   
  82.     return 0;  
  83. }  

这段代码做的事情是这样的,读取400张图片,将399张用于训练,再用最后一张去做识别

代码很短,也很容易看懂

下面是我的输出

Predicted class = 37 / Actual class = 37.


输出表示识别正确

注释中说了这是用PCA实现的,下次得好好看看论文仔细研究算法了!

有了这个,你也可以快速建立你的人脸识别分类器了!

0 0
原创粉丝点击