- /face_detect.cpp:定义控制台应用程序的入口点。
- //
- //#include"stdafx.h"
- #include"opencv2/objdetect/objdetect.hpp"
- #include"opencv2/highgui/highgui.hpp"
- #include"opencv2/imgproc/imgproc.hpp"
- #include"opencv2/ml/ml.hpp"
- #include<iostream>
- #include<stdio.h>
- usingnamespacestd;
- namespacecv;
- StringcascadeName="./haarcascade_frontalface_alt2.xml";//人脸的训练数据
- //StringnestedCascadeName="./haarcascade_eye_tree_eyeglasses.xml";//人眼的训练数据
- StringnestedCascadeName="./haarcascade_eye.xml";//人眼的训练数据
- voiddetectAndDraw(Mat&img,
- CascadeClassifier&cascade,CascadeClassifier&nestedCascade,
- doublescale)
- {
- inti=0;
- doublet=0;
- vector<Rect>faces;
- conststaticScalarcolors[]={CV_RGB(0,255),
- CV_RGB(0,128,
- CV_RGB(0,255,0),248)"> CV_RGB(255,108); color:inherit; line-height:18px; margin-top:0px!important; margin-right:0px!important; margin-bottom:0px!important; padding:0px 3px 0px 10px!important"> CV_RGB(255,255)};//用不同的颜色表示不同的人脸
- Matgray,smallImg(cvRound(img.rows/scale),cvRound(img.cols/scale),CV_8UC1);//将图片缩小,加快检测速度
- cvtColor(img,gray,CV_BGR2GRAY);//因为用的是类haar特征,所以都是基于灰度图像的,这里要转换成灰度图像
- resize(gray,smallImg,smallImg.size(),INTER_LINEAR);//将尺寸缩小到1/scale,用线性插值
- equalizeHist(smallImg,smallImg);//直方图均衡
- t=(double)cvGetTickCount();//用来计算算法执行时间
- //检测人脸
- //detectMultiScale函数中smallImg表示的是要检测的输入图像为smallImg,faces表示检测到的人脸目标序列,1.1表示
- //每次图像尺寸减小的比例为1.1,2表示每一个目标至少要被检测到3次才算是真的目标(因为周围的像素和不同的窗口大
- //小都可以检测到人脸),CV_HAAR_SCALE_IMAGE表示不是缩放分类器来检测,而是缩放图像,Size(30,30)为目标的
- //最小最大尺寸
- cascade.detectMultiScale(smallImg,faces,248)"> 1.1,2,0
- //|CV_HAAR_FIND_BIGGEST_OBJECT
- //|CV_HAAR_DO_ROUGH_SEARCH
- |CV_HAAR_SCALE_IMAGE
- ,108); color:inherit; line-height:18px; margin-top:0px!important; margin-right:0px!important; margin-bottom:0px!important; padding:0px 3px 0px 10px!important"> Size(30,30));
- double)cvGetTickCount()-t;//相减为算法执行的时间
- printf("detectiontime=%gms\n",t/((double)cvGetTickFrequency()*1000.));
- for(vector<Rect>::const_iteratorr=faces.begin();r!=faces.end();r++,i++)
- MatsmallImgROI;
- vector<Rect>nestedObjects;
- Pointcenter;
- Scalarcolor=colors[i%8];
- intradius;
- center.x=cvRound((r->x+r->width*0.5)*scale);//还原成原来的大小
- center.y=cvRound((r->y+r->height*0.5)*scale);
- radius=cvRound((r->width+r->height)*0.25*scale);
- circle(img,center,radius,color,3,8,0);
- //检测人眼,在每幅人脸图上画出人眼
- if(nestedCascade.empty())
- continue;
- smallImgROI=smallImg(*r);
- //和上面的函数功能一样
- nestedCascade.detectMultiScale(smallImgROI,nestedObjects,0); background-color:inherit">//|CV_HAAR_DO_CANNY_PRUNING
- |CV_HAAR_SCALE_IMAGE
- ,248)"> Size(30,30));
- for(vector<Rect>::const_iteratornr=nestedObjects.begin();nr!=nestedObjects.end();nr++)
- center.x=cvRound((r->x+nr->x+nr->width*0.5)*scale);
- center.y=cvRound((r->y+nr->y+nr->height*0.5)*scale);
- radius=cvRound((nr->width+nr->height)*0.25*scale);
- circle(img,0);//将眼睛也画出来,和对应人脸的图形是一样的
- }
- }
- cv::imshow("result",img);
- intmain(intargc,constchar**argv)
- Matimage;
- CascadeClassifiercascade,nestedCascade;//创建级联分类器对象
- doublescale=1.3;
- //image=imread("lena.jpg",1);//读入lena图片
- image=imread("0055.jpg",1);
- namedWindow("result",1);//opencv2.0以后用namedWindow函数会自动销毁窗口
- if(!cascade.load(cascadeName))//从指定的文件目录中加载级联分类器
- cerr<<"ERROR:Couldnotloadclassifiercascade"<<endl;
- return0;
- if(!nestedCascade.load(nestedCascadeName))
- cerr<<"WARNING:Couldnotloadclassifiercascadefornestedobjects"<<endl;
- if(!image.empty())//读取图片数据不能为空
- detectAndDraw(image,cascade,nestedCascade,scale);
- waitKey(0);
- return0;
- }