openCV实现多人脸检测,多眼部检测,完整代码和详细注释

Posted 晴堂

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了openCV实现多人脸检测,多眼部检测,完整代码和详细注释相关的知识,希望对你有一定的参考价值。

一,说明及环境

       代码是完全参考opencv中自带的源代码,将其中很多不必要的代码已经删除。环境是opencv2413,vs2013,win10。

       目录结构如图所示:

                                                                              

           其中的xml文件在opencv/sources/data中,图片在opencv/sources/samples/c/,复制到自己的项目目录下。


二,代码及注释

#include "stdafx.h"
#include "opencv2/objdetect/objdetect.hpp"
#include "opencv2/highgui/highgui.hpp"
#include "opencv2/imgproc/imgproc.hpp"
#include <cctype>
#include <iostream>
#include <iterator>
#include <stdio.h>

using namespace std;
using namespace cv;

//面部和眼睛检测并绘制矩形框,参数一次为图片数据,面部和眼部的级联分类器,检测时允许的图片缩小比例
void detectAndDraw(Mat& img, CascadeClassifier& faceCascade, CascadeClassifier& eyeCascade, double scale);
//脸部和眼部的训练数据,就是以xml文件的形式,存储了标准的用来比对的模特数据,文件放在了当前目录
string faceCascadeName = "haarcascade_frontalface_alt.xml";//面部
string eyeCascadeName = "haarcascade_eye.xml";//眼部

int main(int argc, const char** argv)

	Mat image;//opencv中存储数据的基本单位,存储帧,图片等,代替旧版本的IplImage
	string inputName("lena.jpg");//示例图片,放在当前目录
	CascadeClassifier faceCascade, eyeCascade;//定义级联分类器,由它们实现检测功能
	double scale = 1;//不缩小图片,这样可以提高准确率
	if (!faceCascade.load(faceCascadeName) || !eyeCascade.load(eyeCascadeName))//载入xml训练数据
	
		return -1;
	
	image = imread(inputName, CV_LOAD_IMAGE_COLOR);//读取图片,第二个参数说明是彩色图片
	cvNamedWindow("result", 1);//创建窗口,命名result,id为1
	if (!image.empty())
	
		detectAndDraw(image, faceCascade, eyeCascade, scale);//进行识别
	
	waitKey(0);//等待建入
	cvDestroyWindow("result");//销毁窗口
	return 0;


void detectAndDraw(Mat& img, CascadeClassifier& faceCascade,CascadeClassifier& eyeCascade,double scale)

	int i = 0;
	double t = 0;
	vector<Rect> faces,eyes;//用来存储检测出来的面部和眼部数据,我们无法确定个数,因此定义成vector
	Mat gray, smallImg(cvRound(img.rows / scale), cvRound(img.cols / scale), CV_8UC1);//smallImg已缩放

	cvtColor(img, gray, CV_BGR2GRAY);//图片颜色格式转化,CV_BGR2GRAY是从BGR到gray,彩色到灰色
	resize(gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR);//将灰色图像适应大小到smallImg中
	equalizeHist(smallImg, smallImg);//加强对比度,提高检测准确率

	t = (double)cvGetTickCount();//获取当前时间
	//使用级联分类器进行识别,参数为灰度图片,面部数组,检测单元的增长率,是否融合检测出的矩形,最小检测单元大小
	faceCascade.detectMultiScale(smallImg, faces, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));
	for (vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++)
	
		cv::rectangle(img, *r, Scalar(0,255,0), 1, 1, 0);//在img上绘制出检测到的面部矩形框,绿色框
		Mat faceROI = smallImg(*r);//设置图片感兴趣区域,也就是改变了图片原点和长宽,实际像素数据没有丢失
		eyeCascade.detectMultiScale(faceROI, eyes, 1.1, 2, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));
		for (vector<Rect>::const_iterator e = eyes.begin(); e != eyes.end(); e++)
		
			Rect eyeR;
			eyeR.x = r->x + e->x;//从感兴趣区域映射到整个图片区域
			eyeR.y = r->y + e->y;
			eyeR.height = e->height;
			eyeR.width = e->width;
			cv::rectangle(img, eyeR, Scalar(0, 255, 255), 1, 1, 0);//绘制检测到的眼睛矩形框,黄色框
		
	
	t = (double)cvGetTickCount() - t;//获取当前时间
	printf("detection time = %g ms\\n", t / ((double)cvGetTickFrequency()*1000.));//转化成毫秒打印
	cv::imshow("result", img);//将img显示到result窗口


三,程序运行结果

detectMultiScale()的第四个参数设为2时:

         

detectMultiScale()的第四个参数设为0,且只检测面部时:

        

       由程序运行结果可以看出,opencv特征检测,是对图片进行大小不等的单元分别检测,并将所有可能的结果获取,有参数决定是否融合。另外左上角出现了一个错误的识别区,但是在detectMultiScale()的第四个参数设为2,进行融合时,opencv已经去掉。



以上是关于openCV实现多人脸检测,多眼部检测,完整代码和详细注释的主要内容,如果未能解决你的问题,请参考以下文章

OpenCV检测篇——猫脸检测

运用特征脸方法的基于Opencv的猫脸检测实现

运用特征脸方法的基于Opencv的猫脸检测实现

Python实战案例,利用OpenCV,实现猫脸检测

有没有可以同时进行多人脸识别的算法?

当帧中没有人脸时,OpenCV 中的人脸检测器会变慢