#include "cv.h"
#include "highgui.h"
#include <stdio.h>
#ifdef _EiC
#define WIN32
#endif
static CvMemStorage* storage = 0;
static CvHaarClassifierCascade* cascade = 0;
void detect_and_draw( IplImage* image );
const char* cascade_name = "haarcascade_frontalface_alt.xml";
int main() {
cascade_name = "D:\\Workspace\\Study\\Haar\\OpenCV\\opencv\\data\\haarcascades\\haarcascade_fullbody.xml";
cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
if( !cascade ) {
fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
return -1;
}
storage = cvCreateMemStorage(0);
cvNamedWindow( "result", 1 );
const char* filename = "test2.jpg";
IplImage* image = cvLoadImage( filename, 1 );
if( image ) {
detect_and_draw( image );
cvWaitKey(0);
cvReleaseImage( &image );
}
cvDestroyWindow("result");
return 0;
}
void detect_and_draw(IplImage* img ) {
int scale = 1;
static CvScalar colors[] = {
{ {0,0,255}},{{0,128,255}},{{0,255,255}}, {{0,255,0}},
{{255,128,0}},{{255,255,0}}, {{255,0,0}}, {{255,0,255}}
};
IplImage* gray = cvCreateImage(cvSize(img->width,img->height),8,1);
IplImage* small_img=cvCreateImage(cvSize(cvRound(img->width/scale),cvRound(img->height/scale)),8,1);
cvCvtColor(img,gray, CV_BGR2GRAY);
cvResize(gray, small_img, CV_INTER_LINEAR);
cvEqualizeHist(small_img, small_img);
cvClearMemStorage(storage);
double t = (double)cvGetTickCount();
// Haar Detect
CvSeq* objects = cvHaarDetectObjects(small_img, cascade, storage);
t = (double)cvGetTickCount() - t;
printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.0) );
// Output Image
for(int i=0;i<(objects? objects->total:0);++i) {
CvRect* r=(CvRect*)cvGetSeqElem(objects,i);
cvRectangle(img, cvPoint(r->x*scale,r->y*scale), cvPoint((r->x+r->width)*scale,(r->y+r->height)*scale), colors[i%8], 4);
}
cvShowImage( "result", img );
cvReleaseImage(&gray);
cvReleaseImage(&small_img);
}
cvHaarDetectObjects笔记:
CvSeq* cvHaarDetectObjects(
const CvArr* image,
CvHaarClassifierCascade* cascade,
CvMemStorage* storage,
double scale_factor=1.1,
int min_neighbors=3, int flags=0,
CvSize min_size=cvSize(0,0)
);
函数说明摘自--学习OpenCV:
CvArr* image 一个灰度图像,如果设置了ROI,将只处理这个区域。
CvHaarClassifierCascade* cascade 读入的分类器特征级联。
CvMemStorage* storage 算法的工作缓存。
scale_factor 算法用不同尺寸的窗口进行扫描,scale_factor是每两个不同大小的窗口之间的尺寸关系。
min_neighbors 控制误检测,因为会被不同位置大小的窗口重复检测到,至少有min_neighbors次检测,才认为真的检测到了人脸。
flags 默认值是CV_HAAR_DO_CANNY_PRUNING,其它可选值如下。
min_size 指示寻找的最小区域。max_size 寻找的最大区域
#define CV_HAAR_DO_CANNY_PRUNING 1
//分类器跳过平滑(无边缘)区域
#define CV_HAAR_SCALE_IMAGE 2
//分类器不要缩放分类器,而是缩放图像
#define CV_HAAR_FIND_BIGGEST_OBJECT 4
//分类器只返回最大的目标
#define CV_HAAR_DO_ROUGH_SEARCH 8
//只能和上面一个参数一起使用,使分类器在任何窗口,只要第一个候选者被发现则结束搜寻。
scan_roi_rect:设定感兴趣的区域
局部变量npass=2:
由于cascade结构中的前两个分类器能快速排除大部分非目标图像,可减少对大多数的负目标的判断时间。所以为了将20级的cascade进行分别应用,以提高速度将npass设定为2。
计算积分图:void cvIntegral( const CvArr* image, CvArr* sum, CvArr* sqsum=NULL, CvArr* tilted_sum=NULL );