OpenCV通过Harr分类器人脸识别


[cpp]
  view plain copy
  1. #include <cv.h>  
  2. #include <highgui.h>  
  3. #include <stdio.h>  
  4. #include <stdlib.h>  
  5. #include <string.h>  
  6. #include <assert.h> //用于防御式编程  
  7. #include <math.h>  
  8. #include <float.h>//<float.h>与<limits.h>一样是定义边界值的,<float.h>定义的是浮点数的边界值  
  9. #include <limits.h>  
  10. #include <time.h>  
  11. #include <ctype.h>//在调用字符函数时,在源文件中包含的头文件  
  12.   
  13. #pragma comment(lib, "cv.lib")  
  14. #pragma comment(lib, "cxcore.lib")  
  15. #pragma comment(lib, "highgui.lib")  
  16.   
  17. static CvMemStorage *storage = 0;  
  18. static CvHaarClassifierCascade *cascade = 0;  
  19. void detect_and_draw( IplImage *image);  
  20. const char *cascade_name = "haarcascade_frontalface_alt.xml";  
  21. int main( int argc, char **argv)  
  22. {  
  23.     CvCapture *capture = 0;  
  24.     IplImage *frame, *frame_copy = 0;  
  25.     int optlen = strlen("--cascade=");  
  26.     const char *input_name;  
  27.     if (argc > 1 && strncmp ( argv[1], "--cascade=", optlen ) == 0 ) //如果有图像或者视频输入执行  
  28.     {  
  29.         cascade_name = argv[1] + optlen;  
  30.         input_name =  argc > 2 ? argv[2] : 0;  
  31.     }  
  32.     else   //实时视频  
  33.     {  
  34.         cascade_name = "haarcascade_frontalface_alt2.xml";  
  35.         input_name = argc > 1 ? argv[1] : "test.png";  
  36.     }  
  37.     cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0);  
  38.     if ( !cascade )  
  39.     {  
  40.         fprintf( stderr, "ERROR:could not load classifier cascade\n");  
  41.         fprintf( stderr, "Usage:facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n");  
  42.         return -1;  
  43.     }  
  44.     storage = cvCreateMemStorage(0);  
  45.     if ( !input_name || (isdigit(input_name[0]) && input_name[1] == '\0'))  //extern int isdigit(char c)判断字符c是否为数字  
  46.         capture = cvCaptureFromCAM( !input_name ? 0 : input_name[0] - '0');  
  47.     else  
  48.         capture = cvCaptureFromAVI( input_name );   //如果有视频文件,就读视频文件  
  49.     cvNamedWindow( "result", 1);  
  50.     if (capture)  
  51.     {  
  52.         for(;;)  
  53.         {  
  54.             if (!cvGrabFrame( capture ))  
  55.                 break;  
  56.             frame = cvRetrieveFrame( capture ); //获得由cvGrabFrame函数抓取的图片  
  57.             if (!frame)  
  58.                 break;  
  59.             if (!frame_copy)  
  60.                 frame_copy = cvCreateImage( cvSize(frame->width,frame->height),  
  61.                 IPL_DEPTH_8U,frame->nChannels);  
  62.             if (frame->origin == IPL_ORIGIN_TL)  
  63.   
  64.                 cvCopy (frame, frame_copy, 0);  
  65.             else  
  66.                 cvFlip (frame, frame_copy, 0);反转图像,沿着x-axis  
  67.             detect_and_draw( frame_copy ); // 检测并且画出人脸  
  68.             if(cvWaitKey (10) >= 0)  
  69.                 break;  
  70.         }  
  71.   
  72.         //释放指针  
  73.         cvReleaseImage( &frame_copy );  
  74.         cvReleaseCapture( &capture);  
  75.     }  
  76.     else  //如果不是视频,那就是图像呗!  
  77.     {  
  78.   
  79.         const char *filename = input_name ? input_name : (char*)"Lena.jpg";  
  80.         IplImage *image = cvLoadImage(filename, 1);  
  81.         if (image)  
  82.         {  
  83.             detect_and_draw(image);  
  84.             cvWaitKey(0);  
  85.             cvReleaseImage(&image);  
  86.         }  
  87.         else  
  88.         {  
  89.   
  90.   
  91.             FILE *f = fopen(filename, "rt");  
  92.             if (f)  
  93.             {  
  94.                 char buf[1000+1];  
  95.                 while (fgets(buf, 1000 , f))  
  96.                 {  
  97.                     int len = (int)strlen(buf);  
  98.   
  99.                     while ( len > 0 && isspace(buf[len-1]))  
  100.                         len--;  
  101.                     buf[len] = '\0';  
  102.                     image = cvLoadImage(buf, 1);  
  103.                     if (image)  
  104.                     {  
  105.                         detect_and_draw(image);  
  106.                         cvWaitKey(0);  
  107.                         cvReleaseImage(&image);  
  108.                     }  
  109.                 }  
  110.                 fclose(f);  
  111.             }  
  112.         }  
  113.     }  
  114.   
  115.     cvDestroyWindow("result");  
  116.     return 0;  
  117. }  
  118.   
  119. void detect_and_draw(IplImage *img) //检测和画出人脸的函数体  
  120. {  
  121.     static CvScalar colors[] =  
  122.     {  
  123.         {{0,0,255}},  
  124.         {{0,128,255}},  
  125.         {{0,255,255}},  
  126.         {{0,255,0}},  
  127.         {{255,128,0}},  
  128.         {{255,255,0}},  
  129.         {{255,0,0}},  
  130.         {{255,0,255}}  
  131.     };  
  132.   
  133.     double scale = 1.3;  
  134.     IplImage *gray = cvCreateImage(cvSize(img->width,img->height), IPL_DEPTH_8U, 1);  
  135.     IplImage *small_img = cvCreateImage(cvSize(cvRound(img->width/scale),  
  136.         cvRound(img->height/scale)),  
  137.         8, 1);  
  138.   
  139.     int i;  
  140.     cvCvtColor(img, gray, CV_BGR2GRAY);//把输入的彩色图像转化为灰度图像  
  141.   
  142.     cvResize(gray, small_img,CV_INTER_LINEAR);  
  143.     cvEqualizeHist(small_img, small_img);//灰度图象直方图均衡化  
  144.     cvClearMemStorage(storage);  
  145.     if (cascade)  
  146.     {  
  147.         double t = (double)cvGetTickCount();  
  148.         CvSeq *faces = cvHaarDetectObjects(small_img, cascade,storage,1.1,2,0,cvSize(30, 30));  
  149.         t = (double)cvGetTickCount() - t; //计算的时间  
  150.         printf("detection time = %gms\n",t/((double)cvGetTickFrequency()*1000.));  
  151.         for (i = 0; i < (faces ? faces->total : 0); i++)  
  152.         {  
  153.             //返回索引所指定的元素指针  
  154.             CvRect *r = (CvRect*)cvGetSeqElem(faces, i);  
  155.   
  156.             //用矩形  
  157.             //确定两个点来确定人脸位置,因为用cvRetangle嘛  
  158.             CvPoint pt1, pt2;  
  159.             //找到画矩形的两个点  
  160.             pt1.x = r->x*scale;  
  161.             pt2.x = (r->x+r->width)*scale;  
  162.             pt1.y = r->y*scale;  
  163.             pt2.y = (r->y+r->height)*scale;  
  164.             //画出矩形  
  165.             cvRectangle( img, pt1, pt2, colors[i%8], 3, 8, 0 );  
  166.         }  
  167.     }  
  168.     cvShowImage("result",img);  
  169.     cvReleaseImage(&gray);  
  170.     cvReleaseImage(&small_img);  
  171. }  


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值