2013-10-30 45 views
0

我有一个小白的问题.. 我试图用opencCV 2.4.6进行人脸检测/识别程序在Visual Studio 2010。 我遇到了openCV文档中的人脸识别算法问题。 算法本身对我的作品没有任何错误,但是我是一个不知道,我知道这是输出或者它是不是真的正确的..我用AT &牛逼数据库进行训练和识别.. 我的csv文件(at.txt)看起来是这样的:人脸识别OpenCV的视觉工作室了解

C:\face\s1/1.pgm;0 
C:\face\s1/2.pgm;0 
C:\face\s1/3.pgm;0 
C:\face\s1/4.pgm;0 
C:\face\s1/5.pgm;0 
C:\face\s1/6.pgm;0 
C:\face\s1/7.pgm;0 
C:\face\s1/8.pgm;0 
C:\face\s1/9.pgm;0 
C:\face\s1/10.pgm;0 
C:\face\s2/1.pgm;1 
C:\face\s2/2.pgm;1 
C:\face\s2/3.pgm;1 
C:\face\s2/4.pgm;1 
C:\face\s2/5.pgm;1 
C:\face\s2/6.pgm;1 
C:\face\s2/7.pgm;1 
C:\face\s2/8.pgm;1 
C:\face\s2/9.pgm;1 
C:\face\s2/10.pgm;1 
C:\face\s3/1.pgm;2 
C:\face\s3/2.pgm;2 
C:\face\s3/3.pgm;2 
C:\face\s3/4.pgm;2 
C:\face\s3/5.pgm;2 
C:\face\s3/6.pgm;2 
C:\face\s3/7.pgm;2 
C:\face\s3/8.pgm;2 
C:\face\s3/9.pgm;2 
C:\face\s3/10.pgm;2 
C:\face\s4/1.pgm;3 
C:\face\s4/2.pgm;3 
C:\face\s4/3.pgm;3 
C:\face\s4/4.pgm;3 
C:\face\s4/5.pgm;3 
C:\face\s4/6.pgm;3 
C:\face\s4/7.pgm;3 
C:\face\s4/8.pgm;3 
C:\face\s4/9.pgm;3 
C:\face\s4/10.pgm;3 
C:\face\s5/1.pgm;4 
C:\face\s5/2.pgm;4 
C:\face\s5/3.pgm;4 
C:\face\s5/4.pgm;4 
C:\face\s5/5.pgm;4 
C:\face\s5/6.pgm;4 
C:\face\s5/7.pgm;4 
C:\face\s5/8.pgm;4 
C:\face\s5/9.pgm;4 
C:\face\s5/10.pgm;4 
C:\face\s6/1.pgm;5 
C:\face\s6/2.pgm;5 
C:\face\s6/3.pgm;5 
C:\face\s6/4.pgm;5 
C:\face\s6/5.pgm;5 
C:\face\s6/6.pgm;5 
C:\face\s6/7.pgm;5 
C:\face\s6/8.pgm;5 
C:\face\s6/9.pgm;5 
C:\face\s6/10.pgm;5 
C:\face\s7/1.pgm;6 
C:\face\s7/2.pgm;6 
C:\face\s7/3.pgm;6 
C:\face\s7/4.pgm;6 
C:\face\s7/5.pgm;6 
C:\face\s7/6.pgm;6 
C:\face\s7/7.pgm;6 
C:\face\s7/8.pgm;6 
C:\face\s7/9.pgm;6 
C:\face\s7/10.pgm;6 
C:\face\s8/1.pgm;7 
C:\face\s8/2.pgm;7 
C:\face\s8/3.pgm;7 
C:\face\s8/4.pgm;7 
C:\face\s8/5.pgm;7 
C:\face\s8/6.pgm;7 
C:\face\s8/7.pgm;7 
C:\face\s8/8.pgm;7 
C:\face\s8/9.pgm;7 
C:\face\s8/10.pgm;7 
C:\face\s9/1.pgm;8 
C:\face\s9/2.pgm;8 
C:\face\s9/3.pgm;8 
C:\face\s9/4.pgm;8 
C:\face\s9/5.pgm;8 
C:\face\s9/6.pgm;8 
C:\face\s9/7.pgm;8 
C:\face\s9/8.pgm;8 
C:\face\s9/9.pgm;8 
C:\face\s9/10.pgm;8 
C:\face\s10/1.pgm;9 
C:\face\s10/2.pgm;9 
C:\face\s10/3.pgm;9 
C:\face\s10/4.pgm;9 
C:\face\s10/5.pgm;9 
C:\face\s10/6.pgm;9 
C:\face\s10/7.pgm;9 
C:\face\s10/8.pgm;9 
C:\face\s10/9.pgm;9 
C:\face\s10/10.pgm;9 

我的面部识别代码如下所示:

#include "stdafx.h" 

#include "opencv2/core/core.hpp" 
#include "opencv2/contrib/contrib.hpp" 
#include "opencv2/highgui/highgui.hpp" 

#include <iostream> 
#include <fstream> 
#include <sstream> 

using namespace cv; 
using namespace std; 

static Mat norm_0_255(InputArray _src) { 
    Mat src = _src.getMat(); 
    // Create and return normalized image: 
    Mat dst; 
    switch(src.channels()) { 
    case 1: 
     cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC1); 
     break; 
    case 3: 
     cv::normalize(_src, dst, 0, 255, NORM_MINMAX, CV_8UC3); 
     break; 
    default: 
     src.copyTo(dst); 
     break; 
    } 
    return dst; 
} 

static void read_csv(const string& filename, vector<Mat>& images, vector<int>& labels, 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()) { 
      images.push_back(imread(path, 0)); 
      labels.push_back(atoi(classlabel.c_str())); 
     } 
    } 
} 

int main(int argc, const char *argv[]) { 
    // Check for valid command line arguments, print usage 
    // if no arguments were given. 
    if (argc < 2) { 
     cout << "usage: " << argv[0] << " <csv.ext> <output_folder> " << endl; 
     exit(1); 
    } 
    string output_folder; 
    if (argc == 3) { 
     output_folder = string(argv[2]); 
    } 
    // Get the path to your CSV. 
    string fn_csv = string(argv[1]); 
    // These vectors hold the images and corresponding labels. 
    vector<Mat> images; 
    vector<int> labels; 
    // Read in the data. This can fail if no valid 
    // input filename is given. 
    try { 
     read_csv(fn_csv, images, labels); 
    } catch (cv::Exception& e) { 
     cerr << "Error opening file \"" << fn_csv << "\". Reason: " << e.msg << endl; 
     // nothing more we can do 
     exit(1); 
    } 
    // Quit if there are not enough images for this demo. 
    if(images.size() <= 1) { 
     string error_message = "This demo needs at least 2 images to work. Please add more images to your data set!"; 
     CV_Error(CV_StsError, error_message); 
    } 
    // Get the height from the first image. We'll need this 
    // later in code to reshape the images to their original 
    // size: 
    int height = images[0].rows; 
    // The following lines simply get the last images from 
    // your dataset and remove it from the vector. This is 
    // done, so that the training data (which we learn the 
    // cv::FaceRecognizer on) and the test data we test 
    // the model with, do not overlap. 
    Mat testSample = images[images.size() - 1]; 
    int testLabel = labels[labels.size() - 1]; 
    images.pop_back(); 
    labels.pop_back(); 
    // The following lines create an Eigenfaces model for 
    // face recognition and train it with the images and 
    // labels read from the given CSV file. 
    // This here is a full PCA, if you just want to keep 
    // 10 principal components (read Eigenfaces), then call 
    // the factory method like this: 
    // 
    //  cv::createEigenFaceRecognizer(10); 
    // 
    // If you want to create a FaceRecognizer with a 
    // confidence threshold (e.g. 123.0), call it with: 
    // 
    //  cv::createEigenFaceRecognizer(10, 123.0); 
    // 
    // If you want to use _all_ Eigenfaces and have a threshold, 
    // then call the method like this: 
    // 
    //  cv::createEigenFaceRecognizer(0, 123.0); 
    // 
    Ptr<FaceRecognizer> model = createEigenFaceRecognizer(); 
    model->train(images, labels); 
    // The following line predicts the label of a given 
    // test image: 
    int predictedLabel = model->predict(testSample); 
    // 
    // To get the confidence of a prediction call the model with: 
    // 
    //  int predictedLabel = -1; 
    //  double confidence = 0.0; 
    //  model->predict(testSample, predictedLabel, confidence); 
    // 
    string result_message = format("Predicted class = %d/Actual class = %d.", predictedLabel, testLabel); 
    cout << result_message << endl; 
    // Here is how to get the eigenvalues of this Eigenfaces model: 
    Mat eigenvalues = model->getMat("eigenvalues"); 
    // And we can do the same to display the Eigenvectors (read Eigenfaces): 
    Mat W = model->getMat("eigenvectors"); 
    // Get the sample mean from the training data 
    Mat mean = model->getMat("mean"); 
    // Display or save: 
    if(argc == 2) { 
     imshow("mean", norm_0_255(mean.reshape(1, images[0].rows))); 
    } else { 
     imwrite(format("%s/mean.png", output_folder.c_str()), norm_0_255(mean.reshape(1, images[0].rows))); 
    } 
    // Display or save the Eigenfaces: 
    for (int i = 0; i < min(10, W.cols); i++) { 
     string msg = format("Eigenvalue #%d = %.5f", i, eigenvalues.at<double>(i)); 
     cout << msg << endl; 
     // get eigenvector #i 
     Mat ev = W.col(i).clone(); 
     // Reshape to original size & normalize to [0...255] for imshow. 
     Mat grayscale = norm_0_255(ev.reshape(1, height)); 
     // Show the image & apply a Jet colormap for better sensing. 
     Mat cgrayscale; 
     applyColorMap(grayscale, cgrayscale, COLORMAP_JET); 
     // Display or save: 
     if(argc == 2) { 
      imshow(format("eigenface_%d", i), cgrayscale); 
     } else { 
      imwrite(format("%s/eigenface_%d.png", output_folder.c_str(), i), norm_0_255(cgrayscale)); 
     } 
    } 

    // Display or save the image reconstruction at some predefined steps: 
    for(int num_components = min(W.cols, 10); num_components < min(W.cols, 300); num_components+=15) { 
     // slice the eigenvectors from the model 
     Mat evs = Mat(W, Range::all(), Range(0, num_components)); 
     Mat projection = subspaceProject(evs, mean, images[0].reshape(1,1)); 
     Mat reconstruction = subspaceReconstruct(evs, mean, projection); 
     // Normalize the result: 
     reconstruction = norm_0_255(reconstruction.reshape(1, images[0].rows)); 
     // Display or save: 
     if(argc == 2) { 
      imshow(format("eigenface_reconstruction_%d", num_components), reconstruction); 
     } else { 
      imwrite(format("%s/eigenface_reconstruction_%d.png", output_folder.c_str(), num_components), reconstruction); 
     } 
    } 
    // Display if we are not writing to an output folder: 
    if(argc == 2) { 
     waitKey(0); 
    } 
    return 0; 
} 

而且我的输出是这样的:

http://s15.postimg.org/xq76erurf/image.png

算法还输出图像:这是平均图像,图像eigneface和重建图像。最重要的图像,据我所知道的重建images..and输出我得到几个重建图像,但几乎所有的看起来像鬼除了最后一个是正确重建的第一张人脸/图片之外。算法是否正常工作? 为什么我还没有得到其他重建的面孔? 这是什么意思预测class = 7,实际class = 9?

+0

嗨安德里亚。听起来你对机器学习有很多了解。我不是专家,但脸部识别是一项分类任务。在这些任务中,“谁的脸是这个?”这个问题有一个正确的答案。这个正确的答案是实际的课程。你的电脑猜测是预计的课程。正如你所看到的,您的计算机预测错:( – AndyG

+0

“一切看起来像鬼”; - 这是确定想每一个“鬼”为基本载体的,重建是所有这些“特征向量”的组合悲伤而已,这一点。预测是错误的,不知道为什么。 – berak

回答

0

好像你所需要的算法的一个基本的了解。

我建议你阅读Wikipedia Article about Eigenfaces和纸张:用特征脸从土耳其人&彭特兰可以发现here人脸识别。

这也将有助于如果你能告诉我们你的目标是什么。也许你正在通过使用这种算法走错了方向。

+0

是的,我确实,我正在研究它..我试图制定一个程序,将识别已学习的脸并显示给予该脸的名称作为输出我是否正在朝好的方向发展? –

+0

是的,你是可以表达的。特征脸的问题在于,如果数据库中的图像(训练图像)与要识别的图像之间存在差异样本图像)相当小,因此可以归结为你真正想做的事情,但是如果你刚开始搞乱面部识别,那么Eigenfaces和OpenCV使用的其他方法是一个很好的起点。 – Mailerdaimon