- 库依赖
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);
运行效果
原文链接: https://www.cnblogs.com/larkin-cn/p/17130343.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/318694
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!