opencv下HaarClassifierCascade的简单人脸检测
接触Opencv一段时间了,最近导师一直让我看人脸识别相关的东西,看了这么多大牛写的人脸识别、追踪,一直没有自己动手写过,花了点时间写了一个简单的,单目标下能识别到人脸没问题,多目标下目前没测试,理论上应该可以(多目标识别已测试,识别成功)。
haar classifier cascade是opencv下自带的人脸检测的级联分类器,支持haar特征,新版本的CascadeClassifier好像支持LBP特征,没试过。
PS:要配置好opencv
HaarDect.h
#ifndef HAARDETECT_H
#define HAARDETECT_H
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\objdetect\objdetect.hpp>
using namespace std;
using namespace cv;
CvHaarClassifierCascade* Load_Haar_Cascade();
void detectFace(IplImage* frame,CvHaarClassifierCascade *faceCascade,CvRect *faceRect,int &count);
#endif
Haardetect.cpp
#include "HaarDetect.h"
#include <iostream>
#include <opencv2/opencv.hpp>
using namespace std;
CvHaarClassifierCascade* Load_Haar_Cascade()
{
CvHaarClassifierCascade* faceCascade = NULL;
const char *faceCascadeFilename = "cascades\\haarcascade_frontalface_alt.xml";
faceCascade = (CvHaarClassifierCascade*)cvLoad(faceCascadeFilename,0,0,0);
if(faceCascade==NULL)
{
cout<<"error in Load_Haar_Cascade:faceCascade is NULL"<<endl;
}
return faceCascade;
}
void detectFace(IplImage* frame,CvHaarClassifierCascade *faceCascade,CvRect *faceRect,int &count)
{
const int flag = CV_HAAR_DO_CANNY_PRUNING;
CvSeq *detectedFaces;
CvMemStorage* storage;
const double scale_factore = 1.1f;
storage = cvCreateMemStorage(0);
cvClearMemStorage(storage);
if(faceCascade==NULL)
{
cout<<"error in detectFace:faceCascade is NULL!"<<endl;
exit(1);
}
IplImage* grayFrame = NULL;
grayFrame = cvCreateImage(cvGetSize(frame),IPL_DEPTH_8U,1);
cvCvtColor(frame,grayFrame,CV_RGB2GRAY);
detectedFaces = cvHaarDetectObjects(grayFrame,faceCascade,storage,scale_factore,3,flag,cvSize(20,20));
count = detectedFaces->total;
if(detectedFaces==NULL)
{
cout<<"error in detectFace:detectedFaces is NULL"<<endl;
}
for(int i=0;i<(detectedFaces->total);i++)
{
faceRect[i] = *(CvRect *)cvGetSeqElem(detectedFaces,i);
}
if(faceRect == NULL)
{
cout<<"error in detectFace:faceRect is NULL!"<<endl;
}
cvReleaseMemStorage(&storage);
cvReleaseImage(&grayFrame);
}
main.cpp
#include <iostream>
#include <windows.h>
//#include <conio.h>
#include <opencv2\highgui\highgui.hpp>
#include <opencv2\imgproc\imgproc.hpp>
#include <opencv2\objdetect\objdetect.hpp>
#include "HaarDetect.h"
using namespace std;
using namespace cv;
int main()
{
CvCapture *camera;
CvHaarClassifierCascade* faceCascade = NULL;
CvRect faceRect[30];
int faceCount;
faceCascade = Load_Haar_Cascade();
if(!faceCascade)
return 0;
camera = cvCreateCameraCapture(0);
if(camera==NULL)
{
cout<<"camera is NULL"<<endl;
return 0;
}
IplImage *frame;
/*IplImage *frame = cvCreateImage(
cvSize( cvGetCaptureProperty(camera,CV_CAP_PROP_FRAME_WIDTH),cvGetCaptureProperty(camera,CV_CAP_PROP_FRAME_HEIGHT) ),
IPL_DEPTH_8U,1);*/
Sleep(5000); //wait for init the camera
while(true)
{
/*faceRect = NULL;*/
faceCount = 0;
frame = cvQueryFrame(camera);
if(frame==NULL)
{
cout<<"frame is NULL"<<endl;
break;
}
detectFace(frame,faceCascade,faceRect,faceCount);
//if(faceRect == NULL)
//{
// exit(1);
//}
for(int i=0;i < faceCount;i++)
{
cvRectangle(frame,cvPoint(faceRect[i].x,faceRect[i].y),cvPoint(faceRect[i].x+faceRect[i].width-1,faceRect[i].y+faceRect[i].height-1), CV_RGB(0,255,0), 1, 8, 0);
}
cvNamedWindow("Camera",CV_WINDOW_AUTOSIZE);
cvShowImage("Camera",frame);
cvWaitKey(10);
}
destroyAllWindows();
cvReleaseCapture(&camera);
return 0;
}