C++利用opencv实现人脸检测
小编所有的帖子都是基于unbuntu系统的,当然稍作修改同样试用于windows的,经过小编的绞尽脑汁,把刚刚发的那篇python实现人脸和眼睛的检测的程序用C++实现了,当然,也参考了不少大神的博客,下面我们就一起来看看:
Linux系统下安装opencv我就再啰嗦一次,防止有些人没有安装没调试出来喷小编的程序是个坑,
sudoapt-getinstalllibcv-dev
sudoapt-getinstalllibopencv-dev
看看你的usr/share/opencv/haarcascades目录下有没有出现几个训练集.XML文件,接下来我拿人脸和眼睛检测作为实例玩一下,程序如下:
好多人不会编译opencv,我再多写几句解决一下好多菜鸟的困难吧
copy完代码之后,保存为xiaorun.cpp哦,记得编译试用个g++-oxiaorun./xiaorun.cpp-lopencv_highgui-lopenc_imgproc-lopencv_core-lopencv_objdetect
即可实现
#include#include #include #include #include usingnamespacecv; usingnamespacestd; voiddetectAndDraw(Mat&img,CascadeClassifier&cascade, CascadeClassifier&nestedCascade, doublescale,booltryflip); intmain() { CascadeClassifiercascade,nestedCascade; boolstop=false; cascade.load("/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml"); nestedCascade.load("/usr/share/opencv/haarcascades/haarcascade_eye.xml"); //frame=imread("renlian.jpg"); VideoCapturecap(0);//打开默认摄像头 if(!cap.isOpened()) { return-1; } Matframe; Matedges; while(!stop) { cap>>frame; detectAndDraw(frame,cascade,nestedCascade,2,0); if(waitKey(30)>=0) stop=true; imshow("cam",frame); } //CascadeClassifiercascade,nestedCascade; //boolstop=false; //训练好的文件名称,放置在可执行文件同目录下 //cascade.load("/usr/share/opencv/haarcascades/haarcascade_frontalface_alt.xml"); //nestedCascade.load("/usr/share/opencv/haarcascades/aarcascade_eye.xml"); //frame=imread("renlian.jpg"); //detectAndDraw(frame,cascade,nestedCascade,2,0); //waitKey(); //while(!stop) //{ //cap>>frame; //detectAndDraw(frame,cascade,nestedCascade,2,0); if(waitKey(30)>=0) stop=true; //} return0; } voiddetectAndDraw(Mat&img,CascadeClassifier&cascade, CascadeClassifier&nestedCascade, doublescale,booltryflip) { inti=0; doublet=0; //建立用于存放人脸的向量容器 vector faces,faces2; //定义一些颜色,用来标示不同的人脸 conststaticScalarcolors[]={ CV_RGB(0,0,255), CV_RGB(0,128,255), CV_RGB(0,255,255), CV_RGB(0,255,0), CV_RGB(255,128,0), CV_RGB(255,255,0), CV_RGB(255,0,0), CV_RGB(255,0,255)}; //建立缩小的图片,加快检测速度 //ntcvRound(doublevalue)对一个double型的数进行四舍五入,并返回一个整型数! Matgray,smallImg(cvRound(img.rows/scale),cvRound(img.cols/scale),CV_8UC1); //转成灰度图像,Harr特征基于灰度图 cvtColor(img,gray,CV_BGR2GRAY); //imshow("灰度",gray); //改变图像大小,使用双线性差值 resize(gray,smallImg,smallImg.size(),0,0,INTER_LINEAR); //imshow("缩小尺寸",smallImg); //变换后的图像进行直方图均值化处理 equalizeHist(smallImg,smallImg); //imshow("直方图均值处理",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, 1.1,2,0 //|CV_HAAR_FIND_BIGGEST_OBJECT //|CV_HAAR_DO_ROUGH_SEARCH |CV_HAAR_SCALE_IMAGE ,Size(30,30)); //如果使能,翻转图像继续检测 if(tryflip) { flip(smallImg,smallImg,1); //imshow("反转图像",smallImg); cascade.detectMultiScale(smallImg,faces2, 1.1,2,0 //|CV_HAAR_FIND_BIGGEST_OBJECT //|CV_HAAR_DO_ROUGH_SEARCH |CV_HAAR_SCALE_IMAGE ,Size(30,30)); for(vector ::const_iteratorr=faces2.begin();r!=faces2.end();r++) { faces.push_back(Rect(smallImg.cols-r->x-r->width,r->y,r->width,r->height)); } } t=(double)cvGetTickCount()-t; //qDebug("detectiontime=%gms\n",t/((double)cvGetTickFrequency()*1000.)); for(vector ::const_iteratorr=faces.begin();r!=faces.end();r++,i++) { MatsmallImgROI; vector nestedObjects; Pointcenter; Scalarcolor=colors[i%8]; intradius; doubleaspect_ratio=(double)r->width/r->height; if(0.75 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); } else rectangle(img,cvPoint(cvRound(r->x*scale),cvRound(r->y*scale)), cvPoint(cvRound((r->x+r->width-1)*scale),cvRound((r->y+r->height-1)*scale)), color,3,8,0); if(nestedCascade.empty()) continue; smallImgROI=smallImg(*r); //同样方法检测人眼 nestedCascade.detectMultiScale(smallImgROI,nestedObjects, 1.1,2,0 //|CV_HAAR_FIND_BIGGEST_OBJECT //|CV_HAAR_DO_ROUGH_SEARCH //|CV_HAAR_DO_CANNY_PRUNING |CV_HAAR_SCALE_IMAGE ,Size(30,30)); for(vector ::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,center,radius,color,3,8,0); } } //imshow("识别结果",img); }
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。