OpenCV自带的AdaBoot检测器对人脸检测有着很好的效果,对于双眼的检测结果也很不错,前提是人脸足够大,如大小为320x240的一帧图像,人脸达到150x150大小。
本文简单的包装了一下这个检测器。
- #if !defined(AFX_HARR_DETECTOR_H_INCLUDED)
- #define AFX_HARR_DETECTOR_H_INCLUDED
- #if _MSC_VER > 1000
- #pragma once
- #endif // _MSC_VER > 1000
- #include "cv.h"
- #include "highgui.h"
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <assert.h>
- #include <math.h>
- #include <float.h>
- #include <limits.h>
- #include <time.h>
- #include <ctype.h>
- typedef struct {
- int m_ScaleImg;
- double m_ScaleFactor;
- int m_MinNeighbors;
- bool m_FlagsDoCanny;
- CvSize m_MinSize;
- } HarrParam;
- class CHarrDetector
- {
- public:
- void Process(IplImage *image, const CvRect *pRoi)
- {
- assert(image != NULL);
- assert(image->nChannels == 1);
- IplImage* gray = image;
- IplImage* small_img;
- int i, isFaceFound = 0;
- CvRect roi;
- m_bFound = false;
- if (m_SmallImage == NULL)
- {
- m_SmallImage = cvCreateImage(
- cvSize( cvRound (image->width/m_ScaleImg),
- cvRound (image->height/m_ScaleImg)),
- 8, 1 );
- }
- small_img = m_SmallImage;
- cvResize( gray, small_img, CV_INTER_LINEAR );
- cvEqualizeHist( small_img, small_img );
- cvClearMemStorage( m_storage );
- if (pRoi != NULL)
- {
- roi = *pRoi;
- roi.x /= m_ScaleImg;
- roi.y /= m_ScaleImg;
- roi.width /= m_ScaleImg;
- roi.height/= m_ScaleImg;
- cvSetImageROI(small_img , roi);
- }
- if( m_cascade )
- {
- CvSeq* faces = cvHaarDetectObjects( small_img,
- m_cascade,
- m_storage,
- m_ScaleFactor,
- m_MinNeighbors,
- m_FlagsDoCanny,
- m_MinSize );
- m_bFound = false;
- m_Blob.height = 0;
- m_Blob.width = 0;
- for( i = 0; i < (faces ? faces->total : 0); i++ )
- {
- CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
- CvRect rect;
- rect.x = r->x * m_ScaleImg;
- rect.y = r->y * m_ScaleImg;
- rect.height = r->height * m_ScaleImg;
- rect.width = r->width * m_ScaleImg;
- if (pRoi != NULL)
- {
- rect.x += pRoi->x;
- rect.y += pRoi->y;
- }
- m_bFound = true;
- if (m_Blob.height < rect.height
- && m_Blob.width < rect.width)
- {
- m_Blob = rect;
- }
- }
- }
- if (pRoi != NULL)
- {
- cvResetImageROI(small_img);
- }
- };
- void SetParam(HarrParam *pParam)
- {
- assert(pParam != NULL);
- m_ScaleImg = pParam->m_ScaleImg;
- m_ScaleFactor = pParam->m_ScaleFactor;
- m_MinNeighbors = pParam->m_MinNeighbors-1;
- m_FlagsDoCanny = pParam->m_FlagsDoCanny;
- m_MinSize = pParam->m_MinSize;
- };
- void Init(const char *cascade_name)
- {
- assert(cascade_name != NULL);
- m_cascade = NULL;
- m_storage = NULL;
- m_SmallImage = NULL;
- m_ScaleImg = 4;
- m_ScaleFactor = 1.1f;
- m_MinNeighbors = -1;
- m_FlagsDoCanny = 0;
- m_MinSize = cvSize(30, 30);
- if (m_cascade == NULL)
- {
- m_cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name,
- 0, 0, 0 );
- }
- assert(m_cascade != NULL);
- m_storage = cvCreateMemStorage(0);
- assert(m_storage != NULL);
- };
- CHarrDetector()
- {
- m_bFound = false;
- };
- ~CHarrDetector()
- {
- if (m_SmallImage != NULL)
- {
- cvReleaseImage(&m_SmallImage);
- }
- if (m_storage != NULL)
- {
- cvReleaseMemStorage( &m_storage );
- }
- };
- public:
- bool m_bFound;
- CvRect m_Blob;
- private:
- int m_ScaleImg;
- double m_ScaleFactor;
- int m_MinNeighbors;
- int m_FlagsDoCanny;
- CvSize m_MinSize;
- private:
- CvHaarClassifierCascade* m_cascade;
- CvMemStorage *m_storage;
- IplImage *m_SmallImage;
- };
- class CFaceFounder : public CHarrDetector
- {
- public:
- CFaceFounder()
- {
- const char *cascade_name = "C://Program Files//OpenCV//data//haarcascades//haarcascade_frontalface_alt2.xml";
- Init(cascade_name);
- HarrParam param;
- param.m_FlagsDoCanny = 0;
- param.m_MinNeighbors = -1;
- param.m_MinSize = cvSize(30, 30);
- param.m_ScaleFactor = 1.8f;
- param.m_ScaleImg = 4;
- SetParam(¶m);
- };
- };
- class CEyesFounder : public CHarrDetector
- {
- public:
- CEyesFounder()
- {
- const char *cascade_name = "C://Program Files//OpenCV//data//haarcascades//Eyes45x11.xml";
- Init(cascade_name);
- HarrParam param;
- param.m_FlagsDoCanny = 0;
- param.m_MinNeighbors = -1;
- param.m_MinSize = cvSize(45, 11);
- param.m_ScaleFactor = 1.1f;
- param.m_ScaleImg = 2;
- SetParam(¶m);
- };
- };
- class CMouthFounder : public CHarrDetector
- {
- public:
- CMouthFounder()
- {
- const char *cascade_name = "C://Program Files//OpenCV//data//haarcascades//Mouth25x15.xml";
- Init(cascade_name);
- HarrParam param;
- param.m_FlagsDoCanny = 0;
- param.m_MinNeighbors = -1;
- param.m_MinSize = cvSize(25, 15);
- param.m_ScaleFactor = 1.1f;
- param.m_ScaleImg = 2;
- SetParam(¶m);
- };
- };
- class CNoseFounder : public CHarrDetector
- {
- public:
- CNoseFounder()
- {
- const char *cascade_name = "C://Program Files//OpenCV//data//haarcascades//Nose25x15.xml";
- Init(cascade_name);
- HarrParam param;
- param.m_FlagsDoCanny = 0;
- param.m_MinNeighbors = -1;
- param.m_MinSize = cvSize(25, 15);
- param.m_ScaleFactor = 1.1f;
- param.m_ScaleImg = 2;
- SetParam(¶m);
- };
- };
- #endif // !defined(AFX_HARR_DETECTOR_H_INCLUDED)