openCV学习笔记(九) —— 人脸检测

一、OpenCV人脸检测

 

要实现人脸识别功能,首先要进行人脸检测,判断出图片中人脸的位置,才能进行下一步的操作。

 

1、OpenCV人脸检测的方法

 

在OpenCV中主要使用了两种特征(即两种方法)进行人脸检测,Haar特征和LBP特征。

在OpenCV中,使用已经训练好的XML格式的分类器进行人脸检测。在OpenCV的安装目录下的sources文件夹里的data文件夹里可以看到下图所示的内容:

openCV学习笔记(九) —— 人脸检测_第1张图片

上图中文件夹的名字“haarcascades”、“hogcascades”和“lbpcascades”分别表示通过“haar”、“hog”和“lbp”三种不同的特征而训练出的分类器:即各文件夹里的文件。"haar"特征主要用于人脸检测,“hog”特征主要用于行人检测,“lbp”特征主要用于人脸识别。打开“haarcascades”文件夹,如下图所示

openCV学习笔记(九) —— 人脸检测_第2张图片

图中的XML文件即是我们人脸检测所需要的分类器文件。在实际使用中,推荐使用上图中被标记的“haarcascade_frontalface_alt2.xml”分类器文件,准确率和速度都比较好。

 

2、OpenCV中的人脸检测的类

在opencv中,人脸检测用的是harr或LBP特征,分类算法用的是adaboost算法。这种算法需要提前训练大量的图片,非常耗时,因此opencv已经训练好了,把训练结果存放在一些xml文件里面。在opencv3.0版本中,训练好的文件放在 \build\etc\文件夹下,有两个文件夹haarcascades和lbpcascades,前者存放的是harr特征训练出来的文件,后者存放的是lbp特征训练出来的文件。

在OpenCV中,使用类“CascadeClassifier”进行人脸检测

 

CascadeClassifier faceCascade;   //实例化对象


所需要使用的函数:

faceCascade.load("../data/haarcascade_frontalface_alt2");  //加载分类器
faceCascade.detectMultiScale(imgGray, faces, 1.2, 6, 0, Size(0, 0));  //多尺寸检测人脸
 

实现人脸检测主要依赖于detectMultiScale()函数,下面简单说一下函数参数的含义,先看函数原型:

CV_WRAP virtual void detectMultiScale( const Mat& image,
                                   CV_OUT vector& objects,
                                   double scaleFactor=1.1,
                                   int minNeighbors=3, int flags=0,
                                   Size minSize=Size(),
                                   Size maxSize=Size() );

总共有7个参数,分别是

第一个参数image:  要检测的图片,一般为灰度图

第二个参数objects:  Rect型的容器,存放所有检测出的人脸,每个人脸是一个矩形

第三个参数scaleFactor:  缩放因子,对图片进行缩放,默认为1.1

第四个参数minNeighbors: 最小邻居数,默认为3

第五个参数flags:  兼容老版本的一个参数,在3.0版本中没用处。默认为0

  • CV_HAAR_DO_CANNY_PRUNING:利用Canny边缘检测时会排除一些边缘很少或者很多的图像区域;
  • CV_HAAR_SCALE_IMAGE:按正常比例监测;
  • CV_HAAR_FIND_BIGGEST_OBJECT:只检测最大的物体;
  • CV_HAAR_DO_ROUGH_SEARCH:只做粗略检测;

第六个参数minSize: 最小尺寸,检测出的人脸最小尺寸

第七个参数maxSize: 最大尺寸,检测出的人脸最大尺寸 

 

人脸检测的过程其实也就是一个分类的过程,CascadeClassifier是opencv中人脸检测的一个级联分类器。opencv中目标检测是使用Haar分类器来实现的(后面也使用了LBP特征),这是一种监督学习分类器,使用的是AdaBoost算法。AdaBoost算法的基本过程是对给定的训练样本进行训练得到弱分类器,然后通过多个弱分类器进行加权叠加得到强分类器。弱分类器和强分类器与若学习和强学习对应,弱学习是指学习算法的识别率只是比随机识别稍好;强学习是指学习算法识别概率很高。

3、流程

opencv为我们提供了方便API,我们只要调用就可以快速实现人脸检测,过程主要是:

读取图片 -> 转化成灰度图 -> 对灰度图进行直方图均衡化 -> 调用detectMultiScale进行人脸检测 -> 将结果转化成人脸识别需要的训练集格式

二、代码实现

1、检测图片中的人脸

//头文件
#include
#include
#include
 
using namespace cv;
 
//人脸检测的类
CascadeClassifier faceCascade;
 
int main()
{
	faceCascade.load("../data/haarcascade_frontalface_alt2.xml");   //加载分类器,注意文件路径
 
	Mat img = imread("../data/PrettyGirl.jpg");
	Mat imgGray;
	vector faces;
 
	if(img.empty())
	{
	  return 1;
	}
 
	if(img.channels() ==3)
	{
	   cvtColor(img, imgGray, CV_RGB2GRAY);
	}
	else
	{
	   imgGray = img;
	}
 
	faceCascade.detectMultiScale(imgGray, faces, 1.2, 6, 0, Size(0, 0));   //检测人脸
 
	if(faces.size()>0)
	{
	   for(int i =0; i

结果如下图:

openCV学习笔记(九) —— 人脸检测_第3张图片

2、检测视频中的人脸

#include 
#include 
#include 
#include 

using namespace std;
using namespace cv;

int main()
{
	CascadeClassifier faceCascade;

	faceCascade.load("haarcascade_frontalface_alt2.xml");
	if (faceCascade.empty())
	{
		printf("can't load classifier\n");
		return -1;
	}

	VideoCapture capture;
	capture.open(0);
	if (!capture.isOpened())
	{
		printf("can't open video\n");
		return -1;
	}

	Mat img, imgGray;
	vector faces;

	while (true)
	{
		capture.read(img);

		if (img.channels() == 3)
		{
			cvtColor(img, imgGray, CV_RGB2GRAY);
		}
		else
		{
			imgGray = img;
		}

		faceCascade.detectMultiScale(imgGray, faces, 1.2, 6, 0, Size(0, 0));

		if (faces.size() > 0)
		{
			for (int i = 0; i < faces.size(); i++)
			{
				rectangle(img, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height), Scalar(0, 255, 0), 5, 8);
			}
		}

		imshow("videoCapture", img);

		if (waitKey(1) == 27)
		{
			break;
		}
	}

	destroyAllWindows();

	return 0;
}

在视频实时检测时,可能会出现卡顿,是因为检测人脸花费了过多的时间,这里代码只实现基本功能,并未优化。

本文完。

你可能感兴趣的:(openCV)