opencv c++人脸检测与识别

  • 库依赖

opencv的人脸检测用到扩展库,需要自己源码编译。

  • 流程

采集人脸图片 -->  训练数据集  --> 模型保存。

采集人脸图片 --> 检测人脸区域 --> 放入模型预测

  • 代码

头文件:

#include "face/facerec.hpp"
#include "opencv.hpp"
#include <vector>
using namespace cv;
using namespace std;

  

分类器

cv::CascadeClassifier faceCascade;
cv::Ptr<cv::face::LBPHFaceRecognizer> faceReco;
QString str = "C:/msvc2017_64/opencv454/etc/haarcascades/haarcascade_frontalface_alt.xml";
if(!faceCascade.load(str.toStdString())){
    qWarning() << "load failed:" << str;
    return ;
}
faceReco = cv::face::LBPHFaceRecognizer::create();

  

训练样本

vector<Mat> images;
    vector<int> labels;

    for(int i = 1; i < 7; i++){
        QString strfile = QString("%2/3/%1.png").arg(i)
                .arg(qApp->applicationDirPath());
        cv::Mat mat = imread(strfile.toStdString(), IMREAD_GRAYSCALE);
        if(mat.empty()){
            continue;
        }
        vector<Rect> faceRect;
        faceCascade.detectMultiScale(mat, faceRect);
        if(faceRect.empty()){
            continue;
        }
        Mat matface = mat(faceRect.front());
        images.push_back(matface);
        labels.push_back(3);
    }
    for(int i = 1; i < 7; i++){
        QString strfile = QString("%2/2/%1.png").arg(i)
                .arg(qApp->applicationDirPath());
        cv::Mat mat = imread(strfile.toStdString(), IMREAD_GRAYSCALE);
        if(mat.empty()){
            continue;
        }
        vector<Rect> faceRect;
        faceCascade.detectMultiScale(mat, faceRect);
        if(faceRect.empty()){
            continue;
        }
        Mat matface = mat(faceRect.front());
        images.push_back(matface);
        labels.push_back(2);
    }
    for(int i = 1; i < 9; i++){
        QString strfile = QString("%2/1/%1.png").arg(i)
                .arg(qApp->applicationDirPath());
        cv::Mat mat = imread(strfile.toStdString(), IMREAD_GRAYSCALE);
        if(mat.empty()){
            continue;
        }
        vector<Rect> faceRect;
        faceCascade.detectMultiScale(mat, faceRect);
        if(faceRect.empty()){
            continue;
        }
        Mat matface = mat(faceRect.front());
        images.push_back(matface);
        labels.push_back(1);
    }
    if(!images.empty()){
        faceReco->train(images, labels);
        faceReco->setLabelInfo(1, "A");
        faceReco->setLabelInfo(2, "B");
        faceReco->setLabelInfo(3, "C");
    }

 

保存与加载

QString strresult = QString("%1/facedata.yml").arg(qApp->applicationDirPath());

faceReco->save(strresult.toStdString());

faceReco->read(strresult.toStdString());

 

识别与预测

cv::Mat matclr = listMats.takeLast().clone();

 
    cv::Mat mat;
    cv::cvtColor(matclr, mat, cv::COLOR_BGR2GRAY);
    QTime timecost;
    timecost.restart();
    vector<Rect> faceRect;
    faceCascade.detectMultiScale(mat, faceRect);
    for(int i = 0; i < faceRect.size(); i++){
        rectangle(matclr, faceRect[i], CV_RGB(255, 0, 0));
    }
//    qDebug() << "detect cost:" << timecost.elapsed();
    if(faceRect.empty()){
        emit sigMatResult(matclr);
        return;
    }
    timecost.restart();
    int label = -1;
    double dvalue = 0;
    Mat matface = mat(faceRect.front());
    faceReco->predict(matface, label, dvalue);
    string name = faceReco->getLabelInfo(label);
    if(dvalue < 60){
        QString str = QString("%1(%2)").arg(QString::fromStdString(name)).arg((int)dvalue);
        putText(matclr, str.toStdString(), faceRect.front().tl(), FONT_HERSHEY_SIMPLEX, 1.0, CV_RGB(0,255,0));
    }else{
        qDebug() << "predict:" << QString::fromStdString(name) << dvalue;
    }
    emit sigMatResult(matclr);

 

 

运行效果

 

posted @ 2023-02-17 15:40  larkin-cn  阅读(381)  评论(0编辑  收藏  举报