opencv自带有很强大的分类器,haarcascade_frontalface_alt用于人脸分类。
电脑中的路径为:/opencv-2.4.9/data/haarcascades/haarcascade_frontalface_alt.xml
程序中我们直接调用即可。
下面这段程序实现了简单的人脸检测功能,同时将人脸部分的图像抠取出来,方便后续人脸识别等操作。
#include
#include
#include
#include
#include
#include
#include
using namespace std;
using namespace cv;
/** Function Headers */
void detectAndDisplay( Mat frame );
/** Global variables */
String face_cascade_name = "/home/jeslie/Program/opencv-2.4.9/data/haarcascades/haarcascade_frontalface_alt.xml";
CascadeClassifier face_cascade;
//the point of the faces
int facx1,facx2,facy1,facy2;
//CascadeClassifier eyes_cascade;
String window_name = "Capture - Face detection";
/** @function main */
int main( void )
{
/** declear the variable: camera and image */
VideoCapture capture;
Mat frame;
//Load the cascades( loads a classifier from a file )
if( !face_cascade.load( face_cascade_name ) ){ printf("--(!)Error loading face cascade\n"); return -1; };
//Read the video stream
capture.open( -1 );
if ( ! capture.isOpened() ) { printf("--(!)Error opening video capture\n"); return -1; }
while ( capture.read(frame) )
{
if( frame.empty() )
{
printf(" --(!) No captured frame -- Break!");
break;
}
//3. Apply the classifier to the frame
detectAndDisplay( frame );
int c = waitKey(10);
if( (char)c == 27 ) { break; } // escape
}
return 0;
}
/** @function detectAndDisplay */
void detectAndDisplay( Mat frame )
{
std::vector faces; //the list of rectangles returned
Mat frame_gray;
Mat face_get;
Mat face_save; //the image saved
//-- transfrom 3 channels image to gray-level image
cvtColor( frame, frame_gray, COLOR_BGR2GRAY ); //function prototype: cvtColor(src, bwsrc, CV_RGB2GRAY);
equalizeHist( frame_gray, frame_gray ); //function prototype: void equalizeHist(InputArray src, OutputArray dst)
//-- Detect faces ( Detects objects of different sizes in the input image.
// The detected objects are returned as a list of rectangles. )
face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CASCADE_SCALE_IMAGE, Size(30, 30) );
//-- faces.size(): the number of the faces
for ( size_t i = 0; i < faces.size(); i++ )
{
//get 4 points of the face
facx1 = faces[i].x;
facx2 = faces[i].x + faces[i].width;
facy1 = faces[i].y;
facy2 = faces[i].y + faces[i].height;
//get the image of face
face_get = frame( Range( facy1, facy2 ), Range( facx1, facx2 ) );
resize( face_get, face_save, Size(150,150) );
//find 2 points to detect the face
Point pt1( faces[i].x, faces[i].y );
Point pt2( faces[i].x + faces[i].width, faces[i].y + faces[i].height );
//drawing a rectangle to mark the face
rectangle( frame, pt1, pt2, Scalar( 255, 0, 255 ), 1, 8, 0 );
}
//-- Show what you got
imshow( window_name, frame );
if( faces.size() != 0 )
imshow( "face_save", face_save );
imwrite( "face.jpg", face_save );
//bug: this demo can detect only one face.also,it is the last face.So you should think about how to improve it.
}
最后归纳几个函数的用法
1、cvtColor
void cvtColor( InputArray src, OutputArray dst, int code, int dstCn=0 );
用于改变图片的color space类型(eg. BGR2RGB, BGR2GRAY…….)
2、detectSingleScale
virtual bool detectSingleScale( const Mat& image, int stripCount, Size processingRectSize,
int stripSize, int yStep, double factor, vector & candidates,
vector<int>& rejectLevels, vector<double>& levelWeights, bool outputRejectLevels=false);
在代码中face_cascade.detectMultiScale( frame_gray, faces, 1.1, 2, 0|CASCADE_SCALE_IMAGE, Size(30, 30) );
可以看见这个函数的参数faces得到的是人脸的区域(矩形),可以用于后续的标记、抠图等操作。
3、face_get = frame( Range( facy1, facy2 ), Range( facx1, facx2 ) );
这也是opencv中常用的一种操作,用于获得图片中某一部分(抠图可以这么理解吧= =)。
4、resize( face_get, face_save, Size(150,150) );
resize也很常用,用于改变图片的尺寸,后续人脸识别等操作中要求图片尺寸和库中的尺寸相同。