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);
运行效果


浙公网安备 33010602011771号