facedetect.cpp
上传用户:wry1372
上传日期:2022-08-07
资源大小:1438k
文件大小:9k
源码类别:

图形图像处理

开发平台:

C/C++

  1. #include "cv.h"
  2. #include "highgui.h"
  3. #include "cxcore.h"
  4. #include "mmsystem.h"//导入声音头文件
  5. #pragma comment(lib,"winmm.lib")//导入声音头文件库
  6. #include <stdio.h>
  7. #include <stdlib.h>
  8. #include <string.h>
  9. #include <assert.h>
  10. #include <math.h>
  11. #include <float.h>
  12. #include <limits.h>
  13. #include <time.h>
  14. #include <ctype.h>
  15. #include <iostream.h>
  16. #ifdef _EiC
  17. #define WIN32
  18. #endif
  19. static CvMemStorage* storage = 0;
  20. static CvHaarClassifierCascade* cascade = 0;
  21. void detect_and_draw( IplImage* image );
  22. double AreaPercent( IplImage* areadst );
  23. const char* cascade_name =
  24.     "haarcascade_frontalface_alt.xml";
  25. /*    "haarcascade_profileface.xml";*/
  26. double countsum;/*全局变量*/
  27. double average;/*全局变量*/
  28. int firstcount;/*全局变量*/
  29. int secondcount;/*全局变量*/
  30. int numberdetect;/*全局变量*/
  31. int main2(IplImage * img)
  32. {
  33.         IplImage* gray = cvCreateImage( cvGetSize(img), 8, 1 );
  34.         CvMemStorage* storage = cvCreateMemStorage(0);
  35.         cvCvtColor( img, gray, CV_BGR2GRAY );
  36.         cvSmooth( gray, gray, CV_GAUSSIAN, 9, 9 ); // smooth it, otherwise a lot of false circles may be detected
  37.         CvSeq* circles = cvHoughCircles( gray, storage, CV_HOUGH_GRADIENT, 2, gray->height/4, 150, 40 );
  38.         int i;
  39.         for( i = 0; i < circles->total; i++ )
  40.         {
  41.              float* p = (float*)cvGetSeqElem( circles, i );
  42.              cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), 3, CV_RGB(0,255,0), -1, 8, 0 );
  43.              cvCircle( img, cvPoint(cvRound(p[0]),cvRound(p[1])), cvRound(p[2]), CV_RGB(255,0,0), 3, 8, 0 );
  44.          cout<<"圆心坐标x= "<<cvRound(p[0])<<endl<<"圆心坐标y= "<<cvRound(p[1])<<endl;
  45.             cout<<"半径="<<cvRound(p[2])<<endl;
  46.         }
  47.       cout<<"圆数量="<<circles->total<<endl;
  48.         cvNamedWindow( "circles", 1 );
  49.         cvShowImage( "circles", img );
  50.         return 0;
  51. }
  52. int main1( IplImage * Img ){
  53.     int height ,width ,step ,channels ;
  54.     int i,j,k,same ,max,min,thresh;
  55.     uchar*data0,*data1 ;
  56.     IplImage *nimg;
  57.     nimg = cvCreateImage(cvGetSize(Img),8,1);
  58.     height    = Img->height;
  59.     width     = Img->width;
  60.     step      = Img->widthStep/sizeof(uchar);
  61.     channels = Img->nChannels;
  62.     data0   = (uchar*)Img->imageData;
  63.     data1 =    (uchar*)nimg->imageData;
  64.     printf("Processing a %d X %d image with %d channelsn",width,height,channels);
  65.     int OffSetX[37] = { -1, 0, 1,
  66.     -2,-1, 0, 1, 2,
  67.     -3,-2,-1, 0, 1, 2, 3,
  68.     -3,-2,-1, 0, 1, 2, 3,
  69.     -3,-2,-1, 0, 1, 2, 3,
  70.     -2,-1, 0, 1, 2,
  71.     -1, 0, 1 };
  72.     int OffSetY[37] = { -3,-3,-3,
  73.     -2,-2,-2,-2,-2,
  74.     -1,-1,-1,-1,-1,-1,-1,
  75.     0, 0, 0, 0, 0, 0, 0,
  76.     1, 1, 1, 1, 1, 1, 1,
  77.     2, 2, 2, 2, 2,
  78.     3, 3, 3 };
  79.     max = min = data0[0];
  80.     for(i=0;i<height;i++)
  81.         for(j=0;j<width;j++){
  82.             if(data0[i*step+j]>max) max = data0[i*step+j];
  83.             if(data0[i*step+j]<min)   min = data0[i*step+j];
  84.         }
  85.         thresh = (max - min )/10;//也可选取其他方法得到的阈值
  86.         for(i=3;i<height-3;i++)
  87.             for(j=3;j<width-3;j++){
  88.                 same =0;
  89.                 for(k=0;k<37;k++){
  90.                     if(fabs( data0[(i+OffSetY[k])*step+(j+OffSetX[k])]-data0[i*step+j])<thresh)
  91.                     same++;
  92.                     if(same<20)//值可改
  93.                         data1[i*step+j] = 255;
  94.                     else
  95.                         data1[i*step+j] = 0;
  96.                 }
  97.             }
  98.     //main2(cvCreateImage(cvSize(nimg->width, nimg->height), IPL_DEPTH_8U, 1));
  99.     printf("aaan");
  100.     cvNamedWindow( "Image", 1 ); //创建窗口
  101.     cvShowImage( "Image", nimg ); //显示图像
  102.     return 0;
  103. }
  104. int main( int argc, char** argv )
  105. {
  106.     CvCapture* capture = 0;
  107.     IplImage *frame, *frame_copy = 0;
  108.     int optlen = strlen("--cascade=");
  109.     const char* input_name;
  110.     if( argc > 1 && strncmp( argv[1], "--cascade=", optlen ) == 0 )
  111.     {
  112.         cascade_name = argv[1] + optlen;
  113.         input_name = argc > 2 ? argv[2] : 0;
  114.     }
  115.     else
  116.     {
  117.         cascade_name = "data/haarcascades/haarcascade_fullbody.xml";
  118.         input_name = argc > 1 ? argv[1] : 0;
  119.     }
  120.     cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
  121.     if( !cascade )
  122.     {
  123.         fprintf( stderr, "ERROR: Could not load classifier cascaden" );
  124.         fprintf( stderr,
  125.         "Usage: facedetect --cascade="<cascade_path>" [filename|camera_index]n" );
  126.         return -1;
  127.     }
  128.     storage = cvCreateMemStorage(0);
  129.     if( !input_name || (isdigit(input_name[0]) && input_name[1] == '') )
  130.         capture = cvCaptureFromCAM( !input_name ? 0 : input_name[0] - '0' );
  131.     else
  132.         capture = cvCaptureFromAVI( input_name );
  133.     cvNamedWindow( "result", 1 );
  134. cvNamedWindow( "dst", 1 );
  135. if( capture )
  136.     {
  137. extern int firstcount;
  138. extern int secondcount;
  139. extern int numberdetect;
  140. extern double countsum;
  141. extern double average;
  142. /*for(firstcount=0;firstcount<100;)  //取前100关键帧作为样本
  143.         {
  144.             if( !cvGrabFrame( capture ))
  145.                 break;
  146.             frame = cvQueryFrame( capture );
  147.             if( !frame )
  148.                 break;
  149.             if( !frame_copy )
  150.                 frame_copy = cvCreateImage( cvSize(frame->width,frame->height),
  151.                                             IPL_DEPTH_8U, frame->nChannels );
  152.             if( frame->origin == IPL_ORIGIN_TL )
  153.                 cvCopy( frame, frame_copy, 0 );
  154.             else
  155.                 cvFlip( frame, frame_copy, 0 );
  156.             detect_and_draw( frame_copy );
  157.             if( cvWaitKey( 10 ) >= 0 )
  158.                 break;
  159.         }*/
  160.         average= countsum*0.6/100;  //取样本平均值,与比例系数相乘作为后续参照值
  161. printf("naverage=%fn",average);
  162.         int i = 2;
  163.         IplImage* pFrame = NULL;
  164. while(pFrame = cvQueryFrame( capture )){
  165.     //pFrame = cvLoadImage("test.jpg", 1);
  166.     cvShowImage( "result", pFrame );
  167.     if( cvWaitKey( 10 ) >= 0 )
  168.                 break;
  169.     //IplImage * img = cvCreateImage(cvSize(pFrame->width, pFrame->height), IPL_DEPTH_8U, 1);
  170.             if(i % 50 == 1){
  171.                 printf("%dn", i);
  172.                 i = 2;
  173.                 detect_and_draw( pFrame );
  174.             }
  175.             i++;
  176.         }
  177.         cvReleaseImage( &frame_copy );
  178.         cvReleaseCapture( &capture );
  179.     }else{
  180.         printf("请指定输入视频流!");
  181.     }
  182.     cvDestroyWindow("result");
  183. cvDestroyWindow("dst");
  184.     return 0;
  185. }
  186. void detect_and_draw( IplImage* img )
  187. {
  188.     static CvScalar colors[] =
  189.     {
  190.         {{0,0,255}},
  191.         {{0,128,255}},
  192.         {{0,255,255}},
  193.         {{0,255,0}},
  194.         {{255,128,0}},
  195.         {{255,255,0}},
  196.         {{255,0,0}},
  197.         {{255,0,255}}
  198.     };
  199.     double scale = 1.3;
  200.     IplImage* dsb = cvCloneImage( img );
  201. IplImage* dst = cvCloneImage( img );
  202.     IplImage* gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );
  203.     IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale),
  204.                          cvRound (img->height/scale)),
  205.                      8, 1 );
  206.     int i;
  207.     cvCvtColor( img, gray, CV_BGR2GRAY );
  208.     cvResize( gray, small_img, CV_INTER_LINEAR );
  209.     cvEqualizeHist( small_img, small_img );
  210.     cvClearMemStorage( storage );
  211.     if( cascade )
  212.     {
  213. double length;
  214. extern int firstcount;
  215. extern int secondcount;
  216. extern double countsum;
  217. extern double average;
  218.         double t = (double)cvGetTickCount();
  219.         CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,
  220.                                             1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,
  221.                                             cvSize(30, 30) );
  222.         t = (double)cvGetTickCount() - t;
  223.         printf( "detection time = %gmsn", t/((double)cvGetTickFrequency()*1000.) );
  224.         for( i = 0; i < (faces ? faces->total : 0); i++ ){
  225.             CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
  226. CvPoint left,right;
  227. left.x = cvRound((r->x + r->width/6)*scale);
  228.             left.y = cvRound((r->y + r->height/4)*scale);
  229. right.x = cvRound((r->x + r->width*5/6)*scale);
  230.             right.y = cvRound((r->y + r->height/2)*scale);
  231.             cvRectangle( img, left, right, colors[i%8], 3, 8, 0 );
  232.       cvSetImageROI( dsb, cvRect( left.x, left.y, right.x-left.x, right.y-left.y ));
  233. dst = cvCreateImage( cvSize( right.x-left.x, right.y-left.y ), 8, 1 );
  234. cvCvtColor( dsb, dst, CV_BGR2GRAY);
  235. cvThreshold( dst, dst, 50, 255, CV_THRESH_BINARY);
  236. cvAdaptiveThreshold( dst, dst, 255, CV_ADAPTIVE_THRESH_MEAN_C, CV_THRESH_BINARY, 21, 5 );
  237. length = AreaPercent(dst);
  238. main1(dst);
  239. printf("Area Percent=%fn",length);
  240. if(firstcount < 100)
  241. {
  242. firstcount++;
  243. printf("first count number=%dn",firstcount);
  244. countsum+=length;
  245. }
  246. else
  247.             {
  248. secondcount++;
  249.                 printf("second count number=%dn",secondcount);
  250.                 if(length < average)
  251. numberdetect++;
  252. }
  253.         }
  254.     }
  255.     cvShowImage( "dst", dst );
  256.     cvShowImage( "result", img );
  257.     cvReleaseImage( &dsb );
  258. cvReleaseImage( &dst );
  259. cvReleaseImage( &gray );
  260.     cvReleaseImage( &small_img );
  261. }
  262. double AreaPercent(IplImage* areadst )//计算图像面积,黑色像素的百分比
  263. {
  264. double areapercent,area;
  265. area=(areadst->width)*(areadst->height);
  266. areapercent=(double)(cvCountNonZero(areadst)/area);
  267. return 1-areapercent;
  268. }