百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术文章 > 正文

OpenCV使用EigenFaceRecognizer来实现人脸识别

haoteby 2025-05-02 18:27 70 浏览

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、演示图像

  预测结果:

相关推荐

一日一技:用Python程序将十进制转换为二进制

用Python程序将十进制转换为二进制通过将数字连续除以2并以相反顺序打印其余部分,将十进制数转换为二进制。在下面的程序中,我们将学习使用递归函数将十进制数转换为二进制数,代码如下:...

十进制转化成二进制你会吗?#数学思维

六年级奥赛起跑线:抽屉原理揭秘。同学们好,我是你们的奥耀老师。今天一起来学习奥赛起跑线第三讲二进制计数法。例一:把十进制五十三化成二进制数是多少?首先十进制就是满十进一,二进制就是满二进一。二进制每个...

二进制、十进制、八进制和十六进制,它们之间是如何转换的?

在学习进制时总会遇到多种进制转换的时候,学会它们之间的转换方法也是必须的,这里分享一下几种进制之间转换的方法,也分享两个好用的转换工具,使用它们能够大幅度的提升你的办公和学习效率,感兴趣的小伙伴记得点...

c语言-2进制转10进制_c语言 二进制转十进制

#include<stdio.h>intmain(){charch;inta=0;...

二进制、八进制、十进制和十六进制数制转换

一、数制1、什么是数制数制是计数进位的简称。也就是由低位向高位进位计数的方法。2、常用数制计算机中常用的数制有二进制、八进制、十进制和十六进制。...

二进制、十进制、八进制、十六进制间的相互转换函数

二进制、十进制、八进制、十六进制间的相互转换函数1、输入任意一个十进制的整数,将其分别转换为二进制、八进制、十六进制。2、程序代码如下:#include<iostream>usingna...

二进制、八进制、十进制和十六进制等常用数制及其相互转换

从大学开始系统的接触计算机专业,到现在已经过去十几年了,今天整理一下基础的进制转换,希望给还在上高中的表妹一个入门的引导,早日熟悉这个行业。一、二进制、八进制、十进制和十六进制是如何定义的?二进制是B...

二进制如何转换成十进制?_二进制如何转换成十进制例子图解

随着社会的发展,电器维修由继电器时代逐渐被PLC,变频器,触摸屏等工控时代所替代,特别是plc编程,其数据逻辑往往涉及到数制二进制,那么二进制到底是什么呢?它和十进制又有什么区别和联系呢?下面和朋友们...

二进制与十进制的相互转换_二进制和十进制之间转换

很多同学在刚开始接触计算机语言的时候,都会了解计算机的世界里面大多都是二进制来表达现实世界的任何事物的。当然现实世界的事务有很多很多,就拿最简单的数字,我们经常看到的数字大多都是十进制的形式,例如:我...

十进制如何转换为二进制,二进制如何转换为十进制

用十进制除以2,除的断的,商用0表示;除不断的,商用1表示余0时结束假如十进制用X表示,用十进制除以2,即x/2除以2后为整数的(除的断的),商用0表示;除以2除不断的,商用1表示除完后的商0或1...

十进制数如何转换为二进制数_十进制数如何转换为二进制数举例说明

我们经常听到十进制数和二进制数,电脑中也经常使用二进制数来进行计算,但是很多人却不清楚十进制数和二进制数是怎样进行转换的,下面就来看看,十进制数转换为二进制数的方法。正整数转二进制...

二进制转化为十进制,你会做吗?一起来试试吧

今天孩子问把二进制表示的110101改写成十进制数怎么做呀?,“二进制”简单来说就是“满二进一”,只用0和1共两个数字表示,同理我们平常接触到的“十进制”是“满十进一”,只用0-9共十个数字表示。如果...

Mac终于能正常打游戏了!苹果正逐渐淘汰Rosetta转译

Mac玩家苦转译久矣!WWDC2025苹果正式宣判Rosetta死刑,原生游戏时代终于杀到。Metal4光追和AI插帧技术直接掀桌,连Steam都连夜扛着ARM架构投诚了。看到《赛博朋克2077》...

怎么把视频的声音提出来转为音频?音频提取,11款工具实测搞定

想把视频里的声音单独保存为音频文件(MP3/AAC/WAV/FLAC)用于配音、播客、听课或二次剪辑?本文挑出10款常用工具,给出实测可复现的操作步骤、优缺点和场景推荐。1)转换猫mp3转换器(操作门...

6个mp4格式转换器测评:转换速度与质量并存!

MP4视频格式具有兼容性强、视频画质高清、文件体积较小、支持多种编码等特点,适用于网络媒体传播。如果大家想要将非MP4格式的视频转换成MP4的视频格式的话,可以使用MP4格式转换器更换格式。本文分别从...