f2606e8a30daed1038ef2a9bb74fe918993ad228
[opencv] / samples / c / facedetect.c
1 #include "cv.h"
2 #include "highgui.h"
3
4 #include <stdio.h>
5 #include <stdlib.h>
6 #include <string.h>
7 #include <assert.h>
8 #include <math.h>
9 #include <float.h>
10 #include <limits.h>
11 #include <time.h>
12 #include <ctype.h>
13
14 #ifdef _EiC
15 #define WIN32
16 #endif
17
18 static CvMemStorage* storage = 0;
19 static CvHaarClassifierCascade* cascade = 0;
20
21 void detect_and_draw( IplImage* image );
22
23 const char* cascade_name =
24     "haarcascade_frontalface_alt.xml";
25 /*    "haarcascade_profileface.xml";*/
26
27 int main( int argc, char** argv )
28 {
29     CvCapture* capture = 0;
30     IplImage *frame, *frame_copy = 0;
31     int optlen = strlen("--cascade=");
32     const char* input_name;
33
34     if( argc > 1 && strncmp( argv[1], "--cascade=", optlen ) == 0 )
35     {
36         cascade_name = argv[1] + optlen;
37         input_name = argc > 2 ? argv[2] : 0;
38     }
39     else
40     {
41         cascade_name = "../../data/haarcascades/haarcascade_frontalface_alt2.xml";
42         input_name = argc > 1 ? argv[1] : 0;
43     }
44
45     cascade = (CvHaarClassifierCascade*)cvLoad( cascade_name, 0, 0, 0 );
46     
47     if( !cascade )
48     {
49         fprintf( stderr, "ERROR: Could not load classifier cascade\n" );
50         fprintf( stderr,
51         "Usage: facedetect --cascade=\"<cascade_path>\" [filename|camera_index]\n" );
52         return -1;
53     }
54     storage = cvCreateMemStorage(0);
55     
56     if( !input_name || (isdigit(input_name[0]) && input_name[1] == '\0') )
57         capture = cvCaptureFromCAM( !input_name ? 0 : input_name[0] - '0' );
58     else
59         capture = cvCaptureFromAVI( input_name ); 
60
61     cvNamedWindow( "result", 1 );
62
63     if( capture )
64     {
65         for(;;)
66         {
67             if( !cvGrabFrame( capture ))
68                 break;
69             frame = cvRetrieveFrame( capture );
70             if( !frame )
71                 break;
72             if( !frame_copy )
73                 frame_copy = cvCreateImage( cvSize(frame->width,frame->height),
74                                             IPL_DEPTH_8U, frame->nChannels );
75             if( frame->origin == IPL_ORIGIN_TL )
76                 cvCopy( frame, frame_copy, 0 );
77             else
78                 cvFlip( frame, frame_copy, 0 );
79             
80             detect_and_draw( frame_copy );
81
82             if( cvWaitKey( 10 ) >= 0 )
83                 break;
84         }
85
86         cvReleaseImage( &frame_copy );
87         cvReleaseCapture( &capture );
88     }
89     else
90     {
91         const char* filename = input_name ? input_name : (char*)"lena.jpg";
92         IplImage* image = cvLoadImage( filename, 1 );
93
94         if( image )
95         {
96             detect_and_draw( image );
97             cvWaitKey(0);
98             cvReleaseImage( &image );
99         }
100         else
101         {
102             /* assume it is a text file containing the
103                list of the image filenames to be processed - one per line */
104             FILE* f = fopen( filename, "rt" );
105             if( f )
106             {
107                 char buf[1000+1];
108                 while( fgets( buf, 1000, f ) )
109                 {
110                     int len = (int)strlen(buf);
111                     while( len > 0 && isspace(buf[len-1]) )
112                         len--;
113                     buf[len] = '\0';
114                     image = cvLoadImage( buf, 1 );
115                     if( image )
116                     {
117                         detect_and_draw( image );
118                         cvWaitKey(0);
119                         cvReleaseImage( &image );
120                     }
121                 }
122                 fclose(f);
123             }
124         }
125
126     }
127     
128     cvDestroyWindow("result");
129
130     return 0;
131 }
132
133 void detect_and_draw( IplImage* img )
134 {
135     static CvScalar colors[] = 
136     {
137         {{0,0,255}},
138         {{0,128,255}},
139         {{0,255,255}},
140         {{0,255,0}},
141         {{255,128,0}},
142         {{255,255,0}},
143         {{255,0,0}},
144         {{255,0,255}}
145     };
146
147     double scale = 1.3;
148     IplImage* gray = cvCreateImage( cvSize(img->width,img->height), 8, 1 );
149     IplImage* small_img = cvCreateImage( cvSize( cvRound (img->width/scale),
150                          cvRound (img->height/scale)),
151                      8, 1 );
152     int i;
153
154     cvCvtColor( img, gray, CV_BGR2GRAY );
155     cvResize( gray, small_img, CV_INTER_LINEAR );
156     cvEqualizeHist( small_img, small_img );
157     cvClearMemStorage( storage );
158
159     if( cascade )
160     {
161         double t = (double)cvGetTickCount();
162         CvSeq* faces = cvHaarDetectObjects( small_img, cascade, storage,
163                                             1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,
164                                             cvSize(30, 30) );
165         t = (double)cvGetTickCount() - t;
166         printf( "detection time = %gms\n", t/((double)cvGetTickFrequency()*1000.) );
167         for( i = 0; i < (faces ? faces->total : 0); i++ )
168         {
169             CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
170             CvPoint center;
171             int radius;
172             center.x = cvRound((r->x + r->width*0.5)*scale);
173             center.y = cvRound((r->y + r->height*0.5)*scale);
174             radius = cvRound((r->width + r->height)*0.25*scale);
175             cvCircle( img, center, radius, colors[i%8], 3, 8, 0 );
176         }
177     }
178
179     cvShowImage( "result", img );
180     cvReleaseImage( &gray );
181     cvReleaseImage( &small_img );
182 }