OpenCV 人脸检测

本篇文章主要介绍了如何使用OpenCV实现人脸检测。本文不具体讲解人脸检测的原理,直接使用OpenCV实现。

OpenCV版本:2.4.10;VS开发版本:VS2012。


一、OpenCV人脸检测


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


1、OpenCV人脸检测的方法


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

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


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


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


2、OpenCV中的人脸检测的类


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


  1. CascadeClassifier faceCascade;   //实例化对象  
CascadeClassifier faceCascade;   //实例化对象

所需要使用的函数:

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

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

  1. CV_WRAP virtual void detectMultiScale( const Mat& image,  
  2.                                    CV_OUT vector<Rect>& objects,  
  3.                                    double scaleFactor=1.1,  
  4.                                    int minNeighbors=3, int flags=0,  
  5.                                    Size minSize=Size(),  
  6.                                    Size maxSize=Size() );  
CV_WRAP virtual void detectMultiScale( const Mat& image,
                                   CV_OUT vector<Rect>& objects,
                                   double scaleFactor=1.1,
                                   int minNeighbors=3, int flags=0,
                                   Size minSize=Size(),
                                   Size maxSize=Size() );

各参数含义:

  • const Mat& image: 需要被检测的图像(灰度图)
  • vector<Rect>& objects: 保存被检测出的人脸位置坐标序列
  • double scaleFactor: 每次图片缩放的比例
  • int minNeighbors: 每一个人脸至少要检测到多少次才算是真的人脸
  • int flags: 决定是缩放分类器来检测,还是缩放图像
  • Size(): 表示人脸的最大最小尺寸

二、代码实现


1、检测图片中的人脸


  1. //头文件  
  2. #include<opencv2/objdetect/objdetect.hpp>  
  3. #include<opencv2/highgui/highgui.hpp>  
  4. #include<opencv2/imgproc/imgproc.hpp>  
  5.   
  6. using namespace cv;  
  7.   
  8. //人脸检测的类  
  9. CascadeClassifier faceCascade;  
  10.   
  11. int main()  
  12. {  
  13.     faceCascade.load("../data/haarcascade_frontalface_alt2.xml");   //加载分类器,注意文件路径  
  14.   
  15.     Mat img = imread("../data/PrettyGirl.jpg");  
  16.     Mat imgGray;  
  17.     std::vector<Rect> faces;  
  18.   
  19.     if(img.empty())  
  20.     {  
  21.       return 1;  
  22.     }  
  23.   
  24.     if(img.channels() ==3)  
  25.     {  
  26.        cvtColor(img, imgGray, CV_RGB2GRAY);  
  27.     }  
  28.     else  
  29.     {  
  30.        imgGray = img;  
  31.     }  
  32.   
  33.     faceCascade.detectMultiScale(imgGray, faces, 1.2, 6, 0, Size(0, 0));   //检测人脸  
  34.   
  35.     if(faces.size()>0)  
  36.     {  
  37.        for(int i =0; i<faces.size(); i++)  
  38.        {  
  39.            rectangle(img, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height),   
  40.                            Scalar(0, 255, 0), 1, 8);    //框出人脸位置  
  41.        }  
  42.     }  
  43.   
  44.     imshow("FacesOfPrettyGirl", img);  
  45.   
  46.     waitKey(0);  
  47.     return 0;  
  48. }  
//头文件
#include<opencv2/objdetect/objdetect.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>

using namespace cv;

//人脸检测的类
CascadeClassifier faceCascade;

int main()
{
	faceCascade.load("../data/haarcascade_frontalface_alt2.xml");   //加载分类器,注意文件路径

	Mat img = imread("../data/PrettyGirl.jpg");
	Mat imgGray;
	vector<Rect> 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<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), 1, 8);    //框出人脸位置
	   }
	}

	imshow("FacesOfPrettyGirl", img);

	waitKey(0);
	return 0;
}

结果如下图:




2、检测视频中的人脸


  1. //头文件  
  2. #include<opencv2/objdetect/objdetect.hpp>  
  3. #include<opencv2/highgui/highgui.hpp>  
  4. #include<opencv2/imgproc/imgproc.hpp>  
  5.   
  6. using namespace cv;  
  7.   
  8. //人脸检测的类  
  9. CascadeClassifier faceCascade;  
  10.   
  11. int main()  
  12. {  
  13.     faceCascade.load("../data/haarcascade_frontalface_alt2.xml");   //加载分类器,注意文件路径  
  14.   
  15.     VideoCapture cap;    
  16.     cap.open(0);   //打开摄像头  
  17.     //cap.open("../data/test.avi");   //打开视频  
  18.     Mat img, imgGray;  
  19.     std::vector<Rect> faces;  
  20.     int c = 0;  
  21.   
  22.     if(!cap.isOpened())  
  23.     {  
  24.       return 1;  
  25.     }  
  26.   
  27.     while(c!=27)  
  28.     {  
  29.         cap>>img;  
  30.        if(img.channels() ==3)  
  31.        {  
  32.           cvtColor(img, imgGray, CV_RGB2GRAY);  
  33.        }  
  34.        else  
  35.        {  
  36.           imgGray = img;  
  37.        }  
  38.   
  39.        faceCascade.detectMultiScale(imgGray, faces, 1.2, 6, 0, Size(0, 0));   //检测人脸  
  40.   
  41.        if(faces.size()>0)  
  42.        {  
  43.           for(int i =0; i<faces.size(); i++)  
  44.           {  
  45.               rectangle(img, Point(faces[i].x, faces[i].y), Point(faces[i].x + faces[i].width, faces[i].y + faces[i].height),   
  46.                               Scalar(0, 255, 0), 1, 8);    //框出人脸位置  
  47.           }  
  48.        }  
  49.       
  50.        imshow("Camera", img);  
  51.        c = waitKey(1);  
  52.     }  
  53.     return 0;  
  54. }  
//头文件
#include<opencv2/objdetect/objdetect.hpp>
#include<opencv2/highgui/highgui.hpp>
#include<opencv2/imgproc/imgproc.hpp>

using namespace cv;

//人脸检测的类
CascadeClassifier faceCascade;

int main()
{
	faceCascade.load("../data/haarcascade_frontalface_alt2.xml");   //加载分类器,注意文件路径

	VideoCapture cap;  
	cap.open(0);   //打开摄像头
	//cap.open("../data/test.avi");   //打开视频
	Mat img, imgGray;
	vector<Rect> faces;
	int c = 0;

	if(!cap.isOpened())
	{
	  return 1;
	}

	while(c!=27)
	{
		cap>>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), 1, 8);    //框出人脸位置
	      }
	   }
	
	   imshow("Camera", img);
	   c = waitKey(1);
	}
	return 0;
}


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

本文完。

猜你喜欢

转载自blog.csdn.net/qq_40525008/article/details/79439692