人脸识别之三检测视频流(摄像头)中的人脸

完整人脸识别系统(源码+教程+环境):

开源毕业设计:基于嵌入式ARM-Linux的应用OpenCV和QT实现的人脸识别系统(源码+论文)

完全毕设教程:Linux上Opencv与Qt实现的人脸识别的考勤点名/门禁系统(PC与嵌入式ARM版本)

 

前面两篇讲了人脸库的建立及模型训练,为本篇识别人脸做好准备。

本篇将在前两篇所做的工作的基础上展开。

 

首先,将上篇得到的三个训练模型文件(MyFaceFisherModel.xml、MyFaceLBPHModel.xml、MyFacePCAModel.xml)复制至当前目录,因为人脸识别时以这三个文件作为依据。

本篇亦以三种方法进行识别。

大概流程如下:

1、打开摄像头;

2、加载人脸检测器、人脸模型;

3、对图像缩放处理(提高效率),检测人脸并框出;

4、识别人脸(以人脸模型中的作对比)。

 

代码【opencv-3.2.0版本】:

#include <opencv2/opencv.hpp>  
#include "opencv2/core.hpp"
#include "opencv2/face.hpp"
#include "opencv2/highgui.hpp"
#include "opencv2/imgproc.hpp"
#include <iostream>
#include <fstream>
#include <sstream>

using namespace cv;
using namespace cv::face;
using namespace std;

#define ROW_MIN		45

int exitFlag = 0;

int DetectAndDraw(Mat& img, CascadeClassifier& cascade, 
							double scale, Mat& facesImg);

int main()
{  
	int ret = 0;
	double scale = 4;

    VideoCapture cap(0);    //打开摄像头  
    if (!cap.isOpened())  
    {  
    	printf("open camera failed.\n");
        return -1;  
    }  

  	// 加载级联分类器
    CascadeClassifier cascade;
    ret = cascade.load("/root/library/opencv/opencv-3.2.0/data/haarcascades/haarcascade_frontalface_alt.xml");  
	if( !ret )
	{
		printf("load xml failed[ret=%d].\n", ret);
		return -1;
	}
	cout << "load xml succeed. " << endl;

	//	加载训练好的人脸模型
    Ptr<BasicFaceRecognizer> modelPCA = createEigenFaceRecognizer();  
    modelPCA->load("MyFacePCAModel.xml");  
    Ptr<BasicFaceRecognizer> modelFisher = createFisherFaceRecognizer();  
    modelFisher->load("MyFaceFisherModel.xml");  
    Ptr<LBPHFaceRecognizer> modelLBPH = createLBPHFaceRecognizer();  
    modelLBPH->load("MyFaceLBPHModel.xml");  
      
	Mat frame;  
    while (!exitFlag)  
    {  
        cap >> frame;  
		if(frame.empty()) 
		{
			continue;
		}
        //建立用于存放人脸的向量容器  
        Mat faces;  

		ret = DetectAndDraw(frame, cascade, scale, faces);
		if(ret <= 0)	// 没有人脸
		{
			cout << "faces.size <= 0" << endl;
			continue;
		}

        Mat face_resize;  
        int predictPCA = 0;  
        int predictFisher = 0;  
        int predictLBPH = 0;  
        if (faces.rows >= ROW_MIN)  // 控制人脸不能太小(远)
        {  
            resize(faces, face_resize, Size(92, 112));  
        }  
		else
		{
			printf("face.rows[%d] < %d\n", faces.rows, ROW_MIN);
			continue;
		}
		
        if (!face_resize.empty())
        {  
            //测试图像应该是灰度图  
            predictPCA = modelPCA->predict(face_resize);  
            predictFisher = modelFisher->predict(face_resize);  
            predictLBPH = modelLBPH->predict(face_resize);  
        }  
  
        cout << "predictPCA   : " << predictPCA    << endl;  
        cout << "predictFisher: " << predictFisher << endl;  
        cout << "predictLBPH  : " << predictLBPH   << endl;  
  
        if (waitKey(1) == 27)  	// Esc
        {
			exitFlag = 1;
			cout << "Esc..." << endl;
			break;
        }
	}  
  
    return 0;  
}  

/* 参数 : 输入图像、级联分类器、缩放倍数、输出人脸 */
int DetectAndDraw(Mat& img, CascadeClassifier& cascade, double scale, 
							Mat& facesImg)
{
    double t = 0;
    Mat gray;
    Mat GrayImg;  
	vector<Rect> faces;
    double fx = 1 / scale;
	
    cvtColor( img, gray, COLOR_BGR2GRAY );	// 将源图像转为灰度图

	/* 缩放图像 */
	resize( gray, GrayImg, Size(), fx, fx, INTER_LINEAR);

    equalizeHist( GrayImg, GrayImg );	// 直方图均衡化,提高图像质量

	/* 检测目标 */
    t = (double)getTickCount();
    cascade.detectMultiScale( GrayImg, faces,
        1.1, 2, 0
        //|CASCADE_FIND_BIGGEST_OBJECT
        //|CASCADE_DO_ROUGH_SEARCH
        |CASCADE_SCALE_IMAGE,
        Size(30, 30) );
    t = (double)getTickCount() - t;
    printf( "detection time = %g ms faces.size = %ld\n", t*1000/getTickFrequency(), faces.size());

	/* 画矩形框出目标 */
    for ( size_t i = 0; i < faces.size(); i++ ) // faces.size():检测到的目标数量
    {
        Rect rectFace = faces[i];
		facesImg = GrayImg(faces[i]);
		
		rectangle(img, faces[i], Scalar(255, 0, 0), 1, 8, 0);  // 缩放后的人脸

		rectangle(	img, Point(rectFace.x, rectFace.y) * scale, 
					Point(rectFace.x + rectFace.width, rectFace.y + rectFace.height) * scale,
					Scalar(0, 255, 0), 2, 8);	  // 还原后的人脸
    }
	
    imshow( "FaceDetect", img );	// 显示
	if(waitKey(1) == 27)  	// 显示后要添加延时
	{
		exitFlag = 1;
	}

	return faces.size();
}

 

编译、运行结果:

 

detection time = 23.5059 ms faces.size = 1
predictPCA   : 1
predictFisher: 1
predictLBPH  : 1
Esc...

 

注:蓝色框为缩放后的人脸位置,绿色框为还原后的人脸位置。

 

 

 

  • 3
    点赞
  • 40
    收藏
    觉得还不错? 一键收藏
  • 4
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值