OpenCV使用EigenFaceRecognizer来实现人脸识别
haoteby 2025-05-02 18:27 84 浏览
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 += "/";
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);
// }
// QT开发交流+赀料君羊:714620761
}
3、演示图像
预测结果:
相关推荐
- 如何为MySQL服务器和客户机启用SSL?
-
用户想要与MySQL服务器建立一条安全连接时,常常依赖VPN隧道或SSH隧道。不过,获得MySQL连接的另一个办法是,启用MySQL服务器上的SSL封装器(SSLwrapper)。这每一种方法各有其...
- k8s 证书问题排查_k8s dashboard 证书
-
从去年开始一些老项目上陆陆续续出现一些列的证书问题,(证书原理这里就不说了,官方文档一堆)多数刚开始的表现就是节点的kubelet服务起不来,节点状态NotReady表现日志如下failed...
- 企业级网络互通方案:云端OpenVPN+爱快路由器+Win11互联实战
-
企业级网络互通方案:OpenVPN搭建公有云+爱快路由器+Win11三地互联实战指南「安全高效」三地局域网秒变局域网实施环境说明...
- OpenV** Server/Client配置文件详解
-
Server配置详解...
- 接口基础认知:关键信息与合规前提
-
1.核心技术参数(必记)...
- S交换机通过SSH登录设备配置示例(RADIUS认证+本地认证独立)
-
说明:●本示例只介绍设备的认证相关配置,请同时确保已在RADIUS服务器上做了相关配置,如设备地址、共享密钥、创建用户等配置。●通过不同的管理域来实现RADIUS认证与本地认证两种方式同时使用,两...
- SSL证书如何去除私钥密码保护_ssl证书怎么取消
-
有时候我们在生成证书的时候可以加入了密码保护。然后申请到证书安装到了web服务器。但是这样可能会带来麻烦。每次重启apache或者nginx的时候,都需要输入密码。那么SSL证书如何去除私钥密码保护。...
- SSL证书基础知识与自签名证书生成指南
-
一、证书文件类型解析...
- S交换机通过SSH登录设备配置示例(RADIUS认证)
-
说明:本示例只介绍设备的认证相关配置,请同时确保已在RADIUS服务器上做了相关配置,如设备地址、共享密钥、创建用户等配置。假设已在RADIUS服务器上创建了用户名yc123,密码test#123。对...
- HTTPS是什么?加密原理和证书。SSL/TLS握手过程
-
秘钥的产生过程非对称加密...
- HTTPS TLS握手流程_进行tls握手
-
1.客户端向服务器发送`ClientHello`消息,包括支持的TLS版本、加密套件、随机数等信息。2.服务器收到`ClientHello`消息后,解析其中的信息,并根据配置选择一个加密套件。3....
- Spring Boot 单点登录(SSO)实现_spring boot 单点登录jwt
-
SpringBoot单点登录(SSO)实现全指南单点登录(SingleSign-On,SSO)是一种身份验证机制,允许用户使用一组凭证登录多个相关但独立的系统。在微服务架构和企业级系统中,SS...
- 源码分享:在pdf上加盖电子签章_pdf如何加盖电子公章
-
在pdf上加盖电子签章,并不是只是加个印章图片,。而是要使用一对密钥中的私钥对文件进行签字。为啥要用私钥呢?很简单,因为公钥是公开的,其他人才可以用公钥为你证明,这个文件是你签的。这就是我们常说的:私...
- 微信支付商户API证书到期 怎么更换
-
微信支付商户API证书到期更换是一个非常重要的操作,需要仔细按照流程进行。如果证书过期,所有通过API的支付、退款等操作都会失败,将直接影响您的业务。请按照以下详细步骤进行操作:重要前提:分清...