1. 程式人生 > >【OpenCV人臉識別入門教程之二】人臉檢測

【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”進行人臉檢測

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<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、檢測圖片中的人臉

//標頭檔案
#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、檢測視訊中的人臉

//標頭檔案
#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;
}


在視訊實時檢測時,可能會出現卡頓,是因為檢測人臉花費了過多的時間,這裡程式碼只實現基本功能,並未優化。

本文完。