一 ,环境设置
工具:
1. 安装opencv2.4.9,解压,请务必记住自己解压的路径。以我自己的路径为例D:\
IplImage* image = cvLoadImage(filename ); //加载图像
if( image )
{
detect_and_draw( image );
cvWaitKey(0);
cvReleaseImage( &image );
}
cvDestroyWindow("result");
cvWaitKey(0);
return 0;
}
void detect_and_draw( IplImage* img ) //检测人脸并画出区域
{
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}}
};
double scale = 1.3;
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 );
int i;
cvCvtColor( img, gray, CV_BGR2GRAY );//彩色图转化为灰度图
cvResize( gray, small_img, CV_INTER_LINEAR ); //利用线性插值算法归一化图像
cvEqualizeHist( small_img, small_img ); //直方图均衡化
cvClearMemStorage( storage );
if( cascade )
{
double t = (double)cvGetTickCount();
CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,
1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,
cvSize(30, 30) );
t = (double)cvGetTickCount() - t;
printf( "detection time = %gms/n", t/((double)cvGetTickFrequency()*1000.) ); //统计人脸定位所用时间
for( i = 0; i <(faces ? faces->total : 0); i++ )
{
CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
CvPoint center;
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); //半径
cvCircle( img, center, radius, colors[i%8], 3, 8, 0 ); //用圆形圈出人脸区域
}
}
cvShowImage( "result", img );
cvReleaseImage( &gray );
cvReleaseImage( &small_img );
}
2. 人脸识别 ———视频
#include "cv.h"
#include "highgui.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;
static CvMemStorage* storage = 0;
static CvHaarClassifierCascade* cascade = 0;
void detect_and_draw(IplImage* image);
const char* cascade_name = "D:/opencv2.4.9/opencv/sources/data/haarcascades/haarcascade_frontalface_alt.xml"; //opencv×Ô´øÈËÁ³Ê¶±ðѵÁ·½á¹û
/* "haarcascade_profileface.xml";*/
int main()
{
CvCapture* capture;
capture = cvCreateCameraCapture(0);
cvNamedWindow("face", 1);
cascade = (CvHaarClassifierCascade*)cvLoad(cascade_name, 0, 0, 0);//¼ÓÔØopencv×Ô´øÈËÁ³Ê¶±ðѵÁ·½á¹û
if (!cascade)
{
fprintf(stderr, "ERROR: Could not load classifier cascade/n");
//fprintf( stderr,
//"Usage: facedetect --cascade=/""/[filename|camera_index]/n" );
return -1;
}
storage = cvCreateMemStorage(0);
assert(capture != NULL);
IplImage* frame;
frame = cvQueryFrame( capture ); //ÏȶÁÒ»´Î¹æ±ÜµôµÚÒ»Ö¡
while (1) {
frame = cvQueryFrame(capture);
detect_and_draw(frame);
//if (!frame) break; //Èç¹û³ÌÐò²»ÄܶÁÈ¡ÉãÏñÍ·£¬ÄÇô½«´Ë¾äɾ³ý»ò¼Ó¸öÅжϼ´²ÉÓÃ×¢Ê͵ôµÄiÓï¾äÓÖ»òÕßÔÚwhileÇ°¶ÁÒ»´Î
//if( !frame&i>0 ) break;
//if(i>0)
cvShowImage("face", frame);
char c = cvWaitKey(10);
if (c == 27) break;
//i++;
}
cvReleaseCapture(&capture);
cvDestroyWindow("face");
cvWaitKey(0);
return 0;
}
void detect_and_draw(IplImage* img) //¼ì²âÈËÁ³²¢»³öÇøÓò
{
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 } }
};
double scale = 1.3;
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);
int i;
cvCvtColor(img, gray, CV_BGR2GRAY);//²Êɫͼת»¯Îª»Ò¶Èͼ
cvResize(gray, small_img, CV_INTER_LINEAR); //ÀûÓÃÏßÐÔ²åÖµËã·¨¹éÒ»»¯Í¼Ïñ
cvEqualizeHist(small_img, small_img); //Ö±·½Í¼¾ùºâ»¯
cvClearMemStorage(storage);
if (cascade)
{
double t = (double)cvGetTickCount();
CvSeq* faces = cvHaarDetectObjects(small_img, cascade, storage,
1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,
cvSize(30, 30));
t = (double)cvGetTickCount() - t;
printf("detection time = %gms/n", t / ((double)cvGetTickFrequency()*1000.)); //ͳ¼ÆÈËÁ³¶¨Î»ËùÓÃʱ¼ä
for (i = 0; i <(faces ? faces->total : 0); i++)
{
CvRect* r = (CvRect*)cvGetSeqElem(faces, i);
CvPoint center;
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); //°ë¾¶
cvCircle(img, center, radius, colors[i % 8], 3, 8, 0); //ÓÃÔ²ÐÎȦ³öÈËÁ³ÇøÓò
}
}
//cvShowImage("result", img);
cvReleaseImage(&gray);
cvReleaseImage(&small_img);
}
注释:
const char* cascade_name="haarcascade_frontalface_alt2.xml";//分类器的名称
const char* cascade_name1="haarcascade_eye_tree_eyeglasses.xml";//分类器的名称
const char* cascade_name2="haarcascade_frontalface_alt_tree.xml";//分类器的名称
const char* cascade_name3="haarcascade_mcs_mouth.xml";//分类器的名称
const char* cascade_name4="haarcascade_mcs_nose.xml";//分类器的名称
这是不同的分类器,你可以在你安装的OpenCV中找到。如D:\Program Files\OpenCV2.0\vs2008\data\haarcascades
不同分类器能够帮助你识别不同的部分,如眼睛,鼻子和嘴,更多的需要自己去探索吧。
注释:
把圆形转换成矩形:
pt1.x = r->x*scale;
pt2.x = (r->x+r->width)*scale;
pt1.y = r->y*scale;
pt2.y = (r->y+r->height)*scale;
cvRectangle( img, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
pt1 : 矩形左上角
pt2: 矩形右下角
只需把
cvCircle(img, center, radius, colors[i % 8], 3, 8, 0); //用圆形圈出人脸区域
换成
cvRectangle(img, cvPoint(r->x*scale, r->y*scale), cvPoint((r->x + r->width)*scale, (r->x + r->height)*scale), cvScalar(0, 0, 255), 2, 8, 0);