OpenCV使用EigenFaceRecognizer来实现人脸识别

1、概述

  案例:使用EigenFaceRecognizer来实现人脸识别算法

  实现步骤:

    1.准备人脸数据(人脸和人脸对应的标签),ps:预留一个或几个样本用来测试

    2.将样本数据和样本对应的标签数据从文件中读取出来并分别存入集合

    3.实例化EigenFaceRecognizer

    4.将准备好的人脸集合和标签集合放入EigenFaceRecognizer.train函数中进行训练

    5.训练好数据后执行predict方法进行预测

    6.假如预留样本的标签值与执行predict预测后的标签值是一致的就说明我们预测成功了。

  ps:使用这个算法来实现人脸识别时样本图像和实际的图像大小必须要要一致,否则算法会出现不工作的情况。

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

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);
//        }




}

3、演示图像

  预测结果:

 本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QSS,OpenCV,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值