opencv中具有检测人体各部分的级联分类器,在opencv文件夹里面的sources/data/haarcascades里面。
这里要选择的是能够检测人体头像的还有检测眼睛的级联分类器的文件。
它们分别是:
检测头像 | haarcascade_frontalface_alt.xml或者haarcascade_frontalface_alt2.xml |
检测眼睛 | haarcascade_eye.xml或者haarcascade_eye_tree_eyeglasses.xml |
检测用的函数是:
cvHaarDetectObjects(CvArr* image,
CvHaarClassifierCascade *cascade,
cvMemStorage* storage,
double scale_factor=1.1,
int min_neighors=0,
int flags=0,
CvSize min_size=cvSize(0,0),
CvSize max_size=cvSize(0,0)
);
image 被检图像 cascade haar 分类器级联的内部标识形式 storage 用来存储检测到的一序列候选目标矩形框的内存区域。 可以通过cvCreateStorage(int block_size)来创建缓冲内存。 当设置block_size=0,默认分配64k的缓冲空间内存块。
scale_factor 在前后两次相继的扫描中,搜索窗口的比例系数。
min_neighbors 构成检测目标的相邻矩形的最小个数(缺省-1)。 如果组成检测目标的小矩形的个数和小于 min_neighbors-1 都会被排除。 如果min_neighbors 为 0, 则函数不做任何操作就返回所有的被检候选矩形框, 这种设定值一般用在用户自定义对检测结果的组合程序上。
flags 操作方式。当前唯一可以定义的操作方式是 CV_HAAR_DO_CANNY_PRUNING。 如果被设定,函数利用Canny边缘检测器来排除一 些边缘很少或者很多的图像区域,因为这样的区域一般不含被检目标。 人脸检测中通过设定阈值使用了这种方法,并因此提高了检测速度。 min_size 检测窗口的最小尺寸。
缺省的情况下被设为分类器训练时采用的样本尺寸(人脸检测中缺省大小是~20×20)。 |
1 #define _CRT_SECURE_NO_WARNINGS
2 #include<iostream>
3 #include"cv.h"
4 #include"highgui.h"
5 using namespace cv;
6 using namespace std;
7
8 IplImage* Dectimg(IplImage *getimg);
9 //要将这两个文件的文件路径写清楚或者把他们复制到本项目文件夹里
10 //检测人眼
11 //static char *cascade_name = "haarcascade_eye_tree_eyeglasses.xml";
12 //检测人脸
13 static char* cascade_name = "haarcascade_frontalface_alt2.xml";
14
15 CvHaarClassifierCascade *cascade = 0;
16 int main()
17 {
18 //用cvLoad()加载级联分类器文件
19 cascade = (CvHaarClassifierCascade *)cvLoad(cascade_name);
20
21 //打开摄像头,读入个人录像
22 CvCapture* capture = cvCreateCameraCapture(CV_CAP_ANY);
23 //定义IplImage的指针并且初始化。
24 IplImage * getfile = cvQueryFrame(capture);
25 //命名窗口
26 cvNamedWindow("Result");
27 //循环读入帧
28 while ((getfile = cvQueryFrame(capture)) != NULL)
29 {
30 //每次读入图像帧后进入检测函数
31 IplImage *picture = Dectimg(getfile);
32
33 cvShowImage("Result", picture);
34 //间隔时间15 us,等待输入按键,如果按键为ESC(这个键的键值为27)就退出。
35 if (cvWaitKey(15) == 27)break;
36 }
37 cvWaitKey();
38 //释放图片指针
39 cvReleaseImage(&getfile);
40 //释放读入视频帧的指针
41 cvReleaseCapture(&capture);
42 //关闭所有窗口
43 cvDestroyAllWindows();
44 return 0;
45 }
46
47 //检测图片中的目标图像,并且用矩形将目标圈出来
48 IplImage* Dectimg(IplImage *getimg)
49 {
50 //克隆图像
51 IplImage *img = cvCloneImage(getimg);
52 double scale = 1.2;
53 //缩小图像,提高检测速度
54 IplImage *smallimg = cvCreateImage(cvSize(img->width / scale,img->height/scale),img->depth,img->nChannels);
55 cvResize(img, smallimg);
56 //创建单通道图像
57 IplImage *grayimg = cvCreateImage(cvGetSize(smallimg),smallimg->depth,1);
58 //转换成灰度图像
59 cvCvtColor(smallimg,grayimg,CV_RGB2GRAY);
60 //创建缓存
61 CvMemStorage *storage = 0;
62 storage = cvCreateMemStorage(0);
63 //将图像均衡化
64 cvEqualizeHist(grayimg,grayimg);
65 cvClearMemStorage(storage);
66 //检测图像,将会得到目标区域的矩形
67 CvSeq *objects = cvHaarDetectObjects(grayimg,cascade,storage,scale,3,0,cvSize(30,30));
68 if (objects->total > 0)
69 {
70 /*
71 for (int i = 0; i < objects->total; i++)
72 {
73 CvPoint center;
74 int radius;
75 CvRect *rect = (CvRect*)cvGetSeqElem(objects,i);
76 center.x = (rect->x + rect->width / 2)*scale;
77 center.y = (rect->y + rect->height / 2)*scale
78 ;
79 radius = cvRound((rect->width+rect->height)*0.26*scale);
80 cvCircle(getimg, center, radius, cvScalar(14, 45, 73), 4);
81 }
82 */
83 for (int i = 0; i < objects->total; i++)
84 {
85 CvRect *rect = (CvRect*)cvGetSeqElem(objects,i);
86 cvRectangle(getimg,
87 cvPoint(cvRound( rect->x*scale),cvRound( rect->y*scale)),
88 cvPoint(cvRound(1.2*(rect->x+rect->width)),
89 cvRound(1.2*(rect->y+rect->height))),
90 cvScalar(34,87,155),5);
91 }
92 }
93 else
94 return NULL;//如果没有检测到目标图像就返回空指针
95 return getimg;
96 }