OpenCV之使用EigenFaceRecognizer来实现人脸识别
一、概述
案例:使用EigenFaceRecognizer来实现人脸识别算法
实现步骤:
1.准备人脸数据(人脸和人脸对应的标签),ps:预留一个或几个样本用来测试
2.将样本数据和样本对应的标签数据从文件中读取出来并分别存入集合
3.实例化EigenFaceRecognizer
4.将准备好的人脸集合和标签集合放入EigenFaceRecognizer.train函数中进行训练
5.训练好数据后执行predict方法进行预测
6.假如预留样本的标签值与执行predict预测后的标签值是一致的就说明我们预测成功了。
ps:使用这个算法来实现人脸识别时样本图像和实际的图像大小必须要要一致,否则算法会出现不工作的情况。
二、代码示例
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 += "/"; prepareImageData(srcDirPath.toStdString().c_str(),""); out.close(); } }); QPushButton *btnShow = new QPushButton(this); 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<Mat> images; vector<int> 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<BasicFaceRecognizer> model = EigenFaceRecognizer::create(); model->train(images,labels); //2.预测 int predictedLabel = model->predict(testMatSample); //此处如果样本和预测结果是一致的就说明此次识别是算法是成功的 cout << "testLabel:"<<testLabel<<endl; cout <<"predictedLabel:"<<predictedLabel<<endl; //从训练结果中获取均值、特征向量、特征值矩阵 Mat eigenvalues = model->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); // } }
三、演示图像
预测结果:
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探