1、概述
案例:使用EigenFaceRecognizer来实现人脸识别算法
实现步骤:
1.准备人脸数据(人脸和人脸对应的标签),ps:预留一个或几个样本用来测试
2.将样本数据和样本对应的标签数据从文件中读取出来并分别存入集合
3.实例化EigenFaceRecognizer
4.将准备好的人脸集合和标签集合放入EigenFaceRecognizer.train函数中进行训练
5.训练好数据后执行predict方法进行预测
6.假如预留样本的标签值与执行predict预测后的标签值是一致的就说明我们预测成功了。
ps:使用这个算法来实现人脸识别时样本图像和实际的图像大小必须要要一致,否则算法会出现不工作的情况。
2、代码示例
Face_Eigen_Face_Recognizer::Face_Eigen_Face_Recognizer(QWidget *parent)
: MyGraphicsView{parent}
{
this->setWindowTitle("特征脸识别器");
QPushButton * btn = new QPushButton(this);
btn->setText("读取数据");
connect(btn,&QPushButton::clicked,[=](){
QString srcDirPath = QFileDialog::getExistingDirectory(
this, "choose src Directory",
"/Users/yangwei/Documents/tony/opencv/orl_faces");
if (srcDirPath.isEmpty())
{
return;
}
else
{
string filename = string("/Users/yangwei/Documents/tony/opencv/orl_faces/targetData.txt");
out.open(filename,ios::out);
qDebug() << srcdirpath='<< srcDirPath;
srcDirPath +=' prepareimagedatasrcdirpath.tostdstring.c_str out.close qpushbutton btnshow='new' qpushbuttonthis btnshow->move(0,btn->y()+btn->height()+5);
btnShow->setText("开始检测特征脸");
connect(btnShow,&QPushButton::clicked,[=](){
showEgenFaceRecoginzer("");
});
}
void Face_Eigen_Face_Recognizer::dropEvent(QDropEvent *event){
path = event->mimeData()->urls().at(0).toLocalFile();
showEgenFaceRecoginzer(path.toStdString().c_str());
}
void Face_Eigen_Face_Recognizer::showEgenFaceRecoginzer(const char * filePath){
string filename = string("/Users/yangwei/Documents/tony/opencv/orl_faces/targetData.txt");
ifstream file(filename,ifstream::in);
string line,path,classLabel;//行、路径、标签
vector images;
vector labels;
while(getline(file,line)){
stringstream liness(line);
getline(liness,path,' ');
getline(liness,classLabel);
// if (!path.empty() && !labels.empty()) {
cout << "path :"<< classLabel.c_str()<<endl;;
images.push_back(imread(path, 0));
labels.push_back(atoi(classLabel.c_str()));
// }
}
file.close();
if (images.size() < 1 || labels.size() < 1) {
qDebug()<<"invalid image path...\n";
return;
}
int width = images[0].cols;
int height = images[0].rows;
cout << "width:"<<width<<"|"<<"height:"<<height<<endl;
//准备测试数据和测试label
Mat testMatSample = images[images.size()-1];
int testLabel = labels[labels.size()-1];
imshow("testMatSample",testMatSample);
images.pop_back();
labels.pop_back();
//接下来就是最重要的步骤
//1.训练
Ptr model = EigenFaceRecognizer::create();
model->train(images,labels);
//2.预测
int predictedLabel = model->predict(testMatSample);
//此处如果样本和预测结果是一致的就说明此次识别是算法是成功的
cout << "testLabel:"<<testLabel<<endl;
cout <<"predictedLabel:"<<predictedLabel<getEigenValues();
Mat eigenvectors = model->getEigenVectors();
Mat mean = model->getMean();
//得到均值脸
Mat meanFace = mean.reshape(1,height);
Mat dst;
//归一化0~255并输出
if(meanFace.channels()==1){//单通道图像
normalize(meanFace,dst,0,255,NORM_MINMAX,CV_8UC1);
}else{//多通道图像
normalize(meanFace,dst,0,255,NORM_MINMAX,CV_8UC3);
}
imshow("dist",dst);
// //输出特征脸
// for (int i = 0; i < min(16, eigenvectors.cols); i++) {
// Mat ev = eigenvectors.col(i).clone();
// Mat grayscale;
// Mat eigenFace = ev.reshape(1, height);
// if (eigenFace.channels() == 1) {
// normalize(eigenFace, grayscale, 0, 255, NORM_MINMAX, CV_8UC1);
// }
// else if (eigenFace.channels() == 3) {
// normalize(eigenFace, grayscale, 0, 255, NORM_MINMAX, CV_8UC3);
// }
// Mat colorface;
// applyColorMap(grayscale, colorface, COLORMAP_BONE);
// char* winTitle = new char[128];
// sprintf(winTitle, "eigenface_%d", i);
// imshow(winTitle, colorface);
// }
// for (int num = 0; num < min(eigenvectors.cols, 16); num++) {
// Mat evs = eigenvectors.col(num);
// Mat projection = LDA::subspaceProject(evs, mean, images[0].reshape(1, 1));
// Mat reconstruction = LDA::subspaceReconstruct(evs, mean, projection);
// Mat result = reconstruction.reshape(1, height);
// if (result.channels() == 1) {
// normalize(result, reconstruction, 0, 255, NORM_MINMAX, CV_8UC1);
// }
// else if (result.channels() == 3) {
// normalize(result, reconstruction, 0, 255, NORM_MINMAX, CV_8UC3);
// }
// char* winTitle = new char[128];
// sprintf(winTitle, "recon_face_%d", num);
// imshow(winTitle, reconstruction);
// }
// QT开发交流+赀料君羊:714620761
}
3、演示图像
预测结果: