如何使用 Opencv 实现人脸检测和人脸识别?


Opencv mat资料下载

N
1.人脸检测 CascadeClassifier
加载 Opencv 自带的人脸检测 haarcascade_frontalface_alt.xml 分类器。
图像预处理 cvtColor(灰度化) equalizeHist(直方图均衡化)。
使用 detectMultiScale 函数进行识别。
使用 rectangle 函数绘制找到的目标矩形框。
在原图像上 ROI 截取彩色的人脸保存

2.人脸识别 FaceRecognizer FisherFaceRecognizer LBPHFaceRecognizer
2.1 人脸识别分类器训练

样本归一化,即图像大小一致、灰度化、直方图均衡化等。
Ptr face = EigenFaceRecognizer::create()。
创建样本和标签向量 std::vector images std::vector labels 并 push_back 加入样本和标签。
进行训练 face->train(images,labels)。
保存训练的分类器 face->save(“face.xml”)。
2.2 人脸识别分类器加载和使用

加载训练好的分类器 face->load(face.xml)。
待识别图像预处理 resize cvtColor 等。
预测输入图像获取标签值 int label = face->predict(Mat src),当然也可以获取 置信度 来调整 阈值。
根据标签值,绘制 putText 对应的角色名。
Note:

1.训练和预测的图像大小必须一样且为灰度图像。

2.使用 FisherFaceRecognizer 标签必须大于2类

Code
//人脸检测
#include “opencv2/opencv.hpp”
#include “opencv2/face.hpp”
#include < iostream>
#include < string>
using namespace cv;
using namespace cv::face;
using namespace std;

void FindFaces(cv::Mat &dst)
{
Mat src = imread(“src.jpg”);
Mat frame = src.clone();
Mat facesRIO;
//图像缩放,采用双线性插值。
//cv::resize(src,src,Size(128,128),0,0,cv::INTER_LINEAR);
//图像灰度化。
cv::cvtColor(src,src,COLOR_BGR2GRAY);
//直方图均衡化,图像增强,暗的变亮,亮的变暗。
cv::equalizeHist(src,src);
//
String face_cascade_name = “haarcascade_frontalface_alt.xml”;
String eyes_cascade_name = “haarcascade_eye_tree_eyeglasses.xml”;
CascadeClassifier face_cascade,eyes_cascade;
if(!face_cascade.load(face_cascade_name))
{
//加载脸部分类器失败!
return;
}
if(!eyes_cascade.load(eyes_cascade_name))
{
//加载眼睛分类器失败!
return;
}
//存储找到的脸部矩形。
std::vector< Rect> faces;
face_cascade.detectMultiScale(src,faces,1.1,2,0|CASCADE_SCALE_IMAGE,Size(30,30));
for(size_t i=0;i<faces.size();++i)
{
//绘制矩形 BGR。
rectangle(frame,faces[i],Scalar(0,0,255),1);
//获取矩形中心点。
//Point center( faces[i].x + faces[i].width/2, faces[i].y + faces[i].height/2 );
//绘制圆形。
//ellipse(frame, center, Size( faces[i].width/2, faces[i].height/2 ), 0, 0, 360, Scalar( 255, 0, 255 ), 4, 8, 0 );
//获取脸部矩形区域。
//Mat faceROI = src(faces[i]);
//存储找到的眼睛矩形。
//std::vector< Rect> eyes;
//eyes_cascade.detectMultiScale(faceROI,eyes,1.1,2,0 |CASCADE_SCALE_IMAGE,Size(30,30));
//for(size_t j=0;j<eyes.size();++j)
//{
//Point eye_center(faces[i].x + eyes[j].x + eyes[j].width/2,faces[i].y + eyes[j].y + eyes[j].height/2);
//int radius = cvRound((eyes[j].width + eyes[j].height)0.25);
//circle(frame,eye_center,radius,Scalar( 255, 0, 0 ),4,8,0);
//}
//截取人脸。
facesROI = frame(faces[i]);
//图像缩放。
cv::resize(facesROI,facesROI,Size(128,128),0,0,cv::INTER_LINEAR);
//保存图像。
dst = facesROI;
cv::imwrite(“dst.jpg”,facesROI);
}
return;
}
//人脸识别
void Distinguish()
{
/
******************************************************
*假定 标签1代表张三 标签2代表李四 标签3代表 王五
******************************************************/
//定义保存图片和标签的向量容器
std::vector< Mat> images;
std::vector< int> labels;
//读取样本
Mat src_1 = imread(“src_1.jpg”,CV_LOAD_IMAGE_GRAYSCALE);
Mat src_2 = imread(“src_2.jpg”,CV_LOAD_IMAGE_GRAYSCALE);
Mat src_3 = imread(“src_3.jpg”,CV_LOAD_IMAGE_GRAYSCALE);
Mat src_4 = imread(“src_4.jpg”,CV_LOAD_IMAGE_GRAYSCALE);
//预测样本
Mat src_5 = imread(“src_5.jpg”,CV_LOAD_IMAGE_GRAYSCALE);
//图像大小归一化
cv::resize(src_1,src_1,Size(128,128));
cv::resize(src_2,src_2,Size(128,128));
cv::resize(src_3,src_3,Size(128,128));
cv::resize(src_4,src_4,Size(128,128));
cv::resize(src_5,src_5,Size(128,128));
//加入图像
images.push_back(src_1);
images.push_back(src_2);
images.push_back(src_3);
images.push_back(src_4);
//加入标签
labels.push_back(1);
labels.push_back(1);
labels.push_back(2);
labels.push_back(3);

Ptr< FaceRecognizer> faceClass = EigenFaceRecognizer::create();
Ptr< FisherFaceRecognizer> fisherClass = FisherFaceRecognizer::create();
Ptr< LBPHFaceRecognizer> lpbhClass = LBPHFaceRecognizer::create();
//训练
faceClass->train(images,labels);
fisherClass->train(images,labels);
lpbhClass->train(images,labels);
//保存训练的分类器
faceClass->save(“faceClass.xml”);
fisherClass->save(“fisherClass.xml”);
lpbhClass->save(“lpbhClass.xml”);
//加载分类器
//faceClass->load(“faceClass.xml”);
//fisherClass->load(“fisherClass.xml”);
//lpbhClass->load(“lpbhClass.xml”);
//使用训练好的分类器进行预测。
int faceResult = faceClass->predict(src_5);
switch (faceResult)
{
case 1:
//张三
break;
case 2:
//李四
break;
case 3:
//王五
break;
default:
//未知
break;
}
//预测样本并获取标签和置信度
int fisherResult = -1;
double fisherConfidence = 0.0;
fisherClass->predict(src_5,fisherResult,fisherConfidence);
std::count<<String(“标签类别:”)<<fisherResult<<String(“置信度:”)<<fisherConfidence<<std::endl;
int lpbhResult = lpbhClass->predict(src_5);
std::count<<String(“标签类别:”)<<lpbhResult;
return;
}

猜你喜欢

转载自blog.csdn.net/tianli3153/article/details/84967937