1 /*M///////////////////////////////////////////////////////////////////////////////////////
3 // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
5 // By downloading, copying, installing or using the software you agree to this license.
6 // If you do not agree to this license, do not download, install,
7 // copy or use the software.
10 // Intel License Agreement
11 // For Open Source Computer Vision Library
13 // Copyright (C) 2000, Intel Corporation, all rights reserved.
14 // Third party copyrights are property of their respective owners.
16 // Redistribution and use in source and binary forms, with or without modification,
17 // are permitted provided that the following conditions are met:
19 // * Redistribution's of source code must retain the above copyright notice,
20 // this list of conditions and the following disclaimer.
22 // * Redistribution's in binary form must reproduce the above copyright notice,
23 // this list of conditions and the following disclaimer in the documentation
24 // and/or other materials provided with the distribution.
26 // * The name of Intel Corporation may not be used to endorse or promote products
27 // derived from this software without specific prior written permission.
29 // This software is provided by the copyright holders and contributors "as is" and
30 // any express or implied warranties, including, but not limited to, the implied
31 // warranties of merchantability and fitness for a particular purpose are disclaimed.
32 // In no event shall the Intel Corporation or contributors be liable for any direct,
33 // indirect, incidental, special, exemplary, or consequential damages
34 // (including, but not limited to, procurement of substitute goods or services;
35 // loss of use, data, or profits; or business interruption) however caused
36 // and on any theory of liability, whether in contract, strict liability,
37 // or tort (including negligence or otherwise) arising in any way out of
38 // the use of this software, even if advised of the possibility of such damage.
52 Fl_Window *root_window=(Fl_Window *)0;
53 VideoWindow* video_window = 0;
54 CvCapture* capture = 0;
55 CvVideoWriter* writer = 0;
56 static int started = 0;
57 double timeout = 0.005;
58 IplImage* video_image = 0;
60 Fl_Value_Slider* video_pos = 0;
65 double fps_alpha = 0.1;
68 double prev_frame_stamp = 0;
70 int total_frames0 = 0;
74 Fl_Button* stop_button = 0;
75 Fl_Button* play_button = 0;
76 Fl_Button* video_button = 0;
77 Fl_Button* cam_button = 0;
78 Fl_Button* record_button = 0;
81 #define ORIG_WIN_SIZE 24
83 #define MIN_NEIGHBORS 2
85 static CvMemStorage* storage = cvCreateMemStorage();
86 static CvHaarClassifierCascade* hid_cascade = 0;
88 int InitFaceDetect( const char* classifier_cascade_path )
90 hid_cascade = cvLoadHaarClassifierCascade(
91 classifier_cascade_path && strlen(classifier_cascade_path) > 0 ?
92 classifier_cascade_path : "<default_face_cascade>",
93 cvSize( ORIG_WIN_SIZE, ORIG_WIN_SIZE ));
94 return hid_cascade != 0;
97 void DetectAndDrawFaces( IplImage* img )
99 if( hid_cascade && img )
102 CvSize img_size = cvGetSize( img );
103 IplImage* temp = cvCreateImage( cvSize(img_size.width/2,img_size.height/2), 8, 3 );
104 IplImage* canvas = cvCreateImage( cvSize(temp->width,temp->height*3/2), 8, 3 );
105 CvPoint offset = cvPoint( 0, temp->height/3 );
109 cvPyrDown( img, temp );
110 cvClearMemStorage( storage );
112 cvSetImageROI( canvas, cvRect( offset.x, offset.y, temp->width, temp->height ));
113 cvCopy( temp, canvas );
114 cvResetImageROI( canvas );
118 CvSeq* faces = cvHaarDetectObjects( canvas, hid_cascade, storage, 1.2, 2, 1 );
121 for( i = 0; i < (faces ? faces->total : 0); i++ )
123 CvRect r = *(CvRect*)cvGetSeqElem( faces, i );
127 cvPoint(r.x*scale,/*img->height - */r.y*scale),
128 cvPoint((r.x+r.width)*scale,/*img->height - */(r.y+r.height)*scale),
129 CV_RGB(255,0,0), 3 );
133 cvReleaseImage( &temp );
134 cvReleaseImage( &canvas );
138 class VideoWindow : public Fl_Box
141 VideoWindow( int x, int y, int w, int h, const char* t = 0 );
146 VideoWindow::VideoWindow( int x, int y, int w, int h, const char* t ):
147 Fl_Box( x, y, w, h, t )
151 VideoWindow::~VideoWindow()
155 void VideoWindow::draw()
159 static void end_capture()
162 cvReleaseCapture( &capture );
165 static void cb_Stop( Fl_Widget*, void* );
166 static void cb_StartStopRecord( Fl_Widget*, void* );
167 static void cb_Exit( Fl_Widget*, void* );
169 static double get_time_accurate(void)
171 return (double)cvGetTickCount()*1e-3/(cpu_freq+1e-10);
174 static void get_next_frame(void*)
176 static int repositioning = 0;
178 double new_pos = video_pos->value();
180 if( (new_pos-old_pos >= 1e-10 || new_pos-old_pos <= -1e-10) && !repositioning)
182 video_window->redraw();
183 cvSetCaptureProperty( capture, CV_CAP_PROP_POS_AVI_RATIO, new_pos );
184 new_pos = cvGetCaptureProperty( capture, CV_CAP_PROP_POS_AVI_RATIO );
185 printf("Repositioning\n");
190 new_pos = cvGetCaptureProperty( capture, CV_CAP_PROP_POS_AVI_RATIO );
191 video_pos->value(new_pos);
195 frame = cvQueryFrame( capture );
197 if( frame == 0 && is_avi )
203 if( video_window && frame )
205 if( video_window->w() < frame->width || video_window->h() < frame->height )
206 root_window->size( (short)(frame->width + 40), (short)(frame->height + 150));
208 CvRect rect = { video_window->x(), video_window->y(),
209 frame->width, frame->height };
211 if( !video_image || video_image->width < rect.width ||
212 video_image->height < rect.height )
214 cvReleaseImage( &video_image );
215 video_image = cvCreateImage( cvSize( rect.width, rect.height ), 8, 3 );
218 cvSetImageROI( video_image, cvRect(0,0,rect.width, rect.height));
219 if( frame->origin == 1 )
220 cvFlip( frame, video_image, 0 );
222 cvCopy( frame, video_image, 0 );
224 DetectAndDrawFaces( video_image );
225 if( writer && is_recorded )
227 cvWriteToAVI( writer, video_image );
229 cvCvtColor( video_image, video_image, CV_RGB2BGR );
234 cvGetRawData( video_image, &data, &step, &size );
236 video_window->redraw();
237 fl_draw_image( (uchar*)data, video_window->x(), video_window->y(),
238 size.width, size.height, 3, step );
243 double cur_frame_stamp = get_time_accurate();
246 fps = 1000/(cur_frame_stamp - prev_frame_stamp);
248 fps = (1-fps_alpha)*fps + fps_alpha*1000/(cur_frame_stamp - prev_frame_stamp);
249 prev_frame_stamp = cur_frame_stamp;
250 sprintf( fps_buffer, "FPS: %5.1f", fps );
251 fps_box->label( fps_buffer );
253 if( total_frames > 0 )
255 if( --total_frames == 0 )
260 total_frames = total_frames0;
261 cvSetCaptureProperty( capture, CV_CAP_PROP_POS_FRAMES, start_pos );
264 Fl::add_timeout( timeout, get_next_frame, 0 );
268 static void cb_PauseResume( Fl_Widget*, void* )
270 video_button->deactivate();
271 cam_button->deactivate();
272 stop_button->activate();
277 play_button->label("@||");
278 play_button->activate();
279 play_button->redraw();
280 stop_button->activate();
281 stop_button->redraw();
282 record_button->activate();
284 video_window->redraw();
285 prev_frame_stamp = get_time_accurate();
286 Fl::add_timeout( timeout, get_next_frame, 0 );
291 play_button->label("@>");
292 play_button->redraw();
297 static void cb_Stop( Fl_Widget*, void* )
302 cb_StartStopRecord(0,0);
303 cvSetCaptureProperty( capture, CV_CAP_PROP_POS_AVI_RATIO, 0 );
304 video_button->activate();
305 cam_button->activate();
306 stop_button->deactivate();
307 record_button->deactivate();
310 static void cb_StartAVI( const char* newfile, int start_pos, int was_started )
315 capture = cvCaptureFromAVI( newfile );
320 cvSetCaptureProperty( capture, CV_CAP_PROP_POS_FRAMES, start_pos );
330 static void cb_Open( Fl_Widget*, void* )
342 char *newfile = fl_file_chooser("Open File?", "*", filename);
343 cb_StartAVI( newfile, 0, was_started );
347 static void cb_StartCam( Fl_Widget*, void* )
356 capture = cvCaptureFromCAM( -1 );
361 static void cb_StartStopRecord( Fl_Widget*, void* )
367 writer = cvCreateAVIWriter( "c:\\test.avi", -1, 15, cvGetSize( video_image ));
370 record_button->box( FL_DOWN_BOX );
377 record_button->box( FL_UP_BOX );
378 cvReleaseVideoWriter( &writer );
383 static void cb_AutoRun( void* _aviname )
385 char* aviname = (char*)_aviname;
386 char* ext_pos = strrchr( aviname, '.' );
389 char* colon_pos = strchr( ext_pos, ':' );
393 start_pos = strtoul( colon_pos+1, &colon_pos, 10 );
394 if( colon_pos && *colon_pos == ':' )
395 total_frames0 = total_frames = strtoul( colon_pos+1, &colon_pos, 10 );
396 if( colon_pos && *colon_pos == ':' )
401 cb_StartAVI( aviname, start_pos, 0 );
405 static void cb_Exit( Fl_Widget*, void* )
407 cvReleaseCapture( &capture );
408 cvReleaseVideoWriter( &writer );
412 const int root_w = 400, root_h = 400;
414 int main( int argc, char **argv )
416 const char* facebaseopt="--facebase=";
417 char* classifierbase = 0;
421 if( argc > 1 && argv[argc-1][0] != '-' )
423 aviname = argv[argc-1];
428 if( argc > 1 && strncmp(argv[argc-1],facebaseopt,strlen(facebaseopt))==0 )
430 classifierbase=argv[argc-1] + strlen(facebaseopt);
434 if( !InitFaceDetect(classifierbase))
436 fprintf( stderr, "Could not locate face classifier base at %s\n"
437 "Use --facebase=<classifier base path> option to specify the base\n",
442 cpu_freq = cvGetTickFrequency();
443 printf("Tick frequency (*10^-6): %g\n", cpu_freq );
447 Fl_Window* o = root_window = new Fl_Window( root_w, root_h );
450 Fl_Tabs* o = new Fl_Tabs( 10, 10, root_w - 20, root_h - 100 );
453 Fl_Group* o = new Fl_Group( 10, 30, root_w - 20, root_h - 110, "Face Detection" );
455 VideoWindow* o = new VideoWindow( 15, 35, root_w - 30, root_h - 120 );
457 o->box( FL_BORDER_BOX );
463 Fl_Group::current()->resizable(o);
466 const int bwidth = 30, bheight = 30;
467 play_button = new Fl_Button( 10, root_h - 35, bwidth, bheight, "@>" );
468 play_button->callback((Fl_Callback*)cb_PauseResume);
469 play_button->deactivate();
470 stop_button = new Fl_Button( 10 + bwidth, root_h - 35, bwidth, bheight, "@square" );
471 stop_button->callback((Fl_Callback*)cb_Stop);
472 stop_button->deactivate();
473 video_button = new Fl_Button( 10 + bwidth*2, root_h - 35, bwidth, bheight, "..." );
474 video_button->callback((Fl_Callback*)cb_Open);
475 cam_button = new Fl_Button( 10 + bwidth*3, root_h - 35, bwidth, bheight, "[o]" );
476 cam_button->callback((Fl_Callback*)cb_StartCam);
477 video_pos = new Fl_Value_Slider( 10 + bwidth*4 + 10, root_h - 35, 200, 20, "Position" );
478 video_pos->type( FL_HOR_NICE_SLIDER );
479 record_button = new Fl_Button( 10 + bwidth*4 + 230, root_h - 35, bwidth, bheight, "@circle" );
480 record_button->labelcolor(FL_RED);
481 record_button->callback((Fl_Callback*)cb_StartStopRecord );
482 record_button->deactivate();
483 fps_box = new Fl_Box( 10, root_h - 75, bwidth*4, bheight, "<No data>" );
484 fps_box->box( FL_DOWN_BOX );
491 Fl::add_timeout( 0.1, cb_AutoRun, aviname );