先来说说训练的过程,train函数的两个参数也很简单,训练的图像组vector<Mat>和对应的标签组vector<int>,这个label标签只需保证同一个人的标签相同即可,不需要保证图像的按标签顺序输入,方便极了。对于预测,有两种调用,其中的参数有测试图像、返回的标签值和测试样本和标签样本的相似性。返回的标签值为-1,说明测试样本在训练集中无对应或距离较远。这里用个FisherFace作为示例说明一下如何训练和预测:
vector<Mat> images; vector<int> labels; // images for first person images.push_back(imread("person0/0.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(0); images.push_back(imread("person0/1.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(0); // images for second person images.push_back(imread("person1/0.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1); images.push_back(imread("person1/1.jpg", CV_LOAD_IMAGE_GRAYSCALE)); labels.push_back(1); Ptr<FaceRecognizer> model = createFisherFaceRecognizer(); model->train(images, labels); Mat img = imread("person1/2.jpg", CV_LOAD_IMAGE_GRAYSCALE); int predicted = model->predict(img);
目前支持的3种人脸识别的方案:特征脸EigenFace、Fisher脸FisherFace、LBP直方图LBPHFace。分别调用函数createEigenFaceRecognizer、createFisherFaceRecognizer、createLBPHFaceRecognizer建立模型。
对于EigenFace两个输入参数,分别为PCA主成分的维数num_components和预测时的阈值threshold,主成分这里没有一个选取的准则,要根据输入数据的大小而决定,通常认为80维主成分是足够的。除了这两个输入参数外,还有eigenvalues和eigenvectors分别代表特征值和特征向量,mean参数为训练样本的平均值,projections为训练数据的预测值,labels为预测时的阈值。
对于FisherFace,和EigenFace非常相似,也有num_components和threshold两个参数和其他5个参数,FisherFace的降维是LDA得到的。默认值为c-1,如果设置的初始值不在(0,c-1]的范围内,会自动设定为c-1。
特别需要强调的是,EigenFace和FisherFace的训练图像和测试图像都必须是灰度图,而且是经过归一化裁剪过的。
对于LBPHFace,我想不用过多介绍,LBP简单和效果是大家都很喜欢的,参数包括半径radius,邻域大小即采样点个数neighbors,x和y方向的单元格数目grid_x,grid_y,还有两个参数histograms为训练数据得到的直方图,labels为直方图对应的标签。这个方法也要求训练和测试的图像是灰度图