今天跑了下Opencv的人脸识别,简化了一下代码,不用在Dos下就可以操作了,当然,用的model说Opencv里面自带的。
haarcascade_frontalface_alt.xml
haarcascade_frontalface_alt2.xml
学习了下分类器使用,发现很简单
load进去后使用detectMultiScale就可以检测了。
但是好像和Opencv中的Hog.detectMultiScale不太一样,hog类和分类器的类没有实质的关系。
修改后的代码如下:
#include <fstream> #include <string> #include <cv.h> #include <highgui.h> #include <ml.h> #include <iostream> #include <fstream> #include <string> #include <vector> #include "cvaux.h" #include <iostream> #include <stdio.h> #include <string.h> #include <ctype.h> using namespace cv; using namespace std; void detectAndDraw( Mat& img, CascadeClassifier& cascade, CascadeClassifier& nestedCascade, double scale); String cascadeName = "D:\\My Documents\\Visual Studio 2008\\Projects\\webCam\\haarcascade_frontalface_alt.xml"; String nestedCascadeName = "D:\\My Documents\\Visual Studio 2008\\Projects\\webCam\\haarcascade_eye_tree_eyeglasses.xml"; int main() { IplImage* aplace = 0; IplImage* colorlaplace = 0; IplImage* planes[3] = {0,0,0}; CvCapture* capture = 0; Mat frame, frameCopy, image; double scale = 1; CascadeClassifier cascade, nestedCascade; capture = cvCaptureFromCAM(0); if(!cascade.load(cascadeName)) { cout<<"Load 1 is false!"<<endl; } //if(!nestedCascade.load(nestedCascadeName)) //{ // cout<<"Load 2 is false!"<<endl; //} cvNamedWindow("Example",0); for(;;) { IplImage* frame0 = 0; int i; frame0 = cvQueryFrame(capture); frame = frame0; if(!frame0) { break; } if( frame0->origin == IPL_ORIGIN_TL ) frame.copyTo( frameCopy ); else flip( frame, frameCopy, 0 ); detectAndDraw( frameCopy, cascade, nestedCascade, scale ); //cvShowImage("Example",frame); cvWaitKey(1); } cvReleaseCapture(&capture); cvDestroyWindow("Example"); return 0; } void detectAndDraw( Mat& img, CascadeClassifier& cascade, CascadeClassifier& nestedCascade, double scale) { int i = 0; double t = 0; vector<Rect> faces; const static Scalar colors[] = { 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)} ; Mat gray, smallImg( cvRound (img.rows/scale), cvRound(img.cols/scale), CV_8UC1 ); cvtColor( img, gray, CV_BGR2GRAY ); resize( gray, smallImg, smallImg.size(), 0, 0, INTER_LINEAR ); equalizeHist( smallImg, smallImg ); t = (double)cvGetTickCount(); 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) ); t = (double)cvGetTickCount() - t; printf( "detection time = %g ms\n", t/((double)cvGetTickFrequency()*1000.) ); for( vector<Rect>::const_iterator r = faces.begin(); r != faces.end(); r++, i++ ) { Mat smallImgROI; vector<Rect> nestedObjects; Point center; // Scalar color = colors[i%8]; Scalar color = colors[3]; int radius; 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, 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<Rect>::const_iterator nr = 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 ); } } cv::imshow( "Example", img ); }
上传一张截图:
运行环境:vs2008,Opencv版本为2.0
最近在研究人体识别,目标跟踪,有兴趣的同学一起讨论!