Fawkes API  Fawkes Development Version
qa_facesclassifier.cpp
1 
2 /***************************************************************************
3  * qa_camargp.h - QA for camera argument parser
4  *
5  * Generated: Wed Apr 11 16:02:33 2007
6  * Copyright 2005-2007 Tim Niemueller [www.niemueller.de]
7  * 2009 Daniel Beck
8  *
9  ****************************************************************************/
10 
11 /* This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version. A runtime exception applies to
15  * this software (see LICENSE.GPL_WRE file mentioned below for details).
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20  * GNU Library General Public License for more details.
21  *
22  * Read the full text in the LICENSE.GPL_WRE file in the doc directory.
23  */
24 
25 /// @cond QA
26 
27 #include <fvutils/adapters/iplimage.h>
28 #include <fvutils/color/colorspaces.h>
29 #include <fvutils/readers/jpeg.h>
30 #include <fvutils/draw/drawer.h>
31 #include <classifiers/faces.h>
32 #include <filters/roidraw.h>
33 #include <fvwidgets/image_display.h>
34 #include <utils/system/argparser.h>
35 #include <utils/time/tracker.h>
36 #include <cams/factory.h>
37 
38 #include <SDL.h>
39 #include <opencv/cv.h>
40 
41 #include <cstdlib>
42 #include <cstdio>
43 
44 using namespace fawkes;
45 
46 int
47 main(int argc, char **argv)
48 {
49  ArgumentParser* argp = new ArgumentParser( argc, argv, "h:f:c:" );
50 
51  if ( argp->has_arg( "h" ) && argp->has_arg( "f" ) )
52  // read image from file
53  {
54  const char *cascade_file = argp->arg( "h" );
55  const char *image_file = argp->arg( "f" );
56 
57  JpegReader *reader = new JpegReader(image_file);
58  unsigned char *buffer = malloc_buffer(YUV422_PLANAR,
59  reader->pixel_width(), reader->pixel_height());
60 
61  reader->set_buffer(buffer);
62  reader->read();
63 
64  FacesClassifier *classifier = new FacesClassifier(cascade_file, reader->pixel_width(),
65  reader->pixel_height());
66 
67 
68  classifier->set_src_buffer(buffer, reader->pixel_width(), reader->pixel_height());
69  std::list< ROI > *rois = classifier->classify();
70 
71  FilterROIDraw *roi_draw = new FilterROIDraw();
72  for (std::list< ROI >::iterator i = rois->begin(); i != rois->end(); ++i) {
73  printf("ROI: start (%u, %u) extent %u x %u\n", (*i).start.x, (*i).start.y,
74  (*i).width, (*i).height);
75 
76  roi_draw->set_dst_buffer(buffer, &(*i));
77  roi_draw->apply();
78  }
79 
80  ImageDisplay *display = new ImageDisplay(reader->pixel_width(), reader->pixel_height());
81  display->show(buffer);
82 
83  display->loop_until_quit();
84 
85  delete display;
86 
87  delete rois;
88  free(buffer);
89  delete reader;
90  delete classifier;
91  }
92 
93  else if ( argp->has_arg( "h" ) && argp->has_arg( "c" ) )
94  // get images from camera
95  {
96  const char *cascade_file = argp->arg( "h" );
97 
98  Camera* camera = NULL;
99  try
100  {
101  camera = CameraFactory::instance( argp->arg( "c" ) );
102  camera->open();
103  camera->start();
104  }
105  catch ( Exception& e )
106  {
107  printf( "Failed to open camera.\n" );
108  delete camera;
109  return( -1 );
110  }
111 
112  printf( "successfully opened camera: w=%d h=%d\n",
113  camera->pixel_width(), camera->pixel_height() );
114 
115  TimeTracker* tt = new TimeTracker();
116  unsigned int ttc_recognition = tt->add_class( "Face recognition" );
117  unsigned int loop_count = 0;
118 
119 
120  IplImage* image = cvCreateImage( cvSize( camera->pixel_width(),
121  camera->pixel_height() ),
122  IPL_DEPTH_8U, 3 );
123 
124  IplImage* scaled_image = cvCreateImage( cvSize( camera->pixel_width() / 2,
125  camera->pixel_height() / 2 ),
126  IPL_DEPTH_8U, 3 );
127 
128  FacesClassifier *classifier = new FacesClassifier( cascade_file,
129  camera->pixel_width(),
130  camera->pixel_height(),
131  scaled_image,
132  1.2 /* scale factor */,
133  2 /* min neighbours */,
134  CV_HAAR_DO_CANNY_PRUNING );
135 
136  unsigned char* display_buffer = (unsigned char*) malloc( camera->buffer_size() );
137 
138  ImageDisplay* display = new ImageDisplay( camera->pixel_width(),
139  camera->pixel_height(),
140  "QA Faces Classifier" );
141 
142  Drawer* drawer = new Drawer();
143  drawer->set_buffer( display_buffer,
144  camera->pixel_width(),
145  camera->pixel_height() );
146 
147  SDL_Event redraw_event;
148  redraw_event.type = SDL_KEYUP;
149  redraw_event.key.keysym.sym = SDLK_SPACE;
150 
151  SDL_PushEvent( &redraw_event );
152 
153  bool quit = false;
154  while ( !quit )
155  {
156  SDL_Event event;
157  if ( SDL_WaitEvent( &event ) )
158  {
159  switch ( event.type )
160  {
161  case SDL_QUIT:
162  quit = true;
163  break;
164 
165  case SDL_KEYUP:
166  if ( event.key.keysym.sym == SDLK_SPACE )
167  {
168  camera->capture();
169 
170  if ( camera->buffer() != NULL )
171  {
172  IplImageAdapter::convert_image_bgr( camera->buffer(), image );
173  cvResize( image, scaled_image, CV_INTER_LINEAR );
174  memcpy( display_buffer, camera->buffer(), camera->buffer_size() );
175 
176  tt->ping_start( ttc_recognition );
177  std::list< ROI > *rois = classifier->classify();
178  tt->ping_end( ttc_recognition );
179 
180  camera->dispose_buffer();
181 
182  bool first = true;
183  for ( std::list< ROI >::reverse_iterator i = rois->rbegin();
184  i != rois->rend();
185  ++i )
186  {
187  if ( first ) { drawer->set_color( 127, 70, 200 ); }
188  drawer->draw_rectangle( 2 * i->start.x, 2 * i->start.y, 2 * i->width, 2 * i->height );
189  if ( first ) { drawer->set_color( 30, 30, 30 ); first = false; }
190  }
191 
192  if ( ++loop_count % 15 == 0 ) { tt->print_to_stdout(); }
193 
194  display->show( display_buffer );
195  }
196 
197  SDL_PushEvent( &redraw_event );
198  }
199 
200  else if ( event.key.keysym.sym == SDLK_ESCAPE )
201  { quit = true; }
202 
203  break;
204 
205  default:
206  break;
207  }
208  }
209  }
210 
211  camera->stop();
212  camera->close();
213  delete camera;
214  delete display;
215  delete drawer;
216  free( display_buffer );
217  cvReleaseImage( &image );
218  cvReleaseImage( &scaled_image );
219  delete tt;
220  }
221 
222  else
223  {
224  printf("Usage: %s -h <Haar cascade file> -f <Image file as JPEG>\n", argv[0]);
225  printf(" or %s -h <Haar cascade file> -c <Camera argument string>\n", argv[0]);
226  exit(-1);
227  }
228 
229  delete argp;
230 }
231 
232 /// @endcond
const char * arg(const char *argn)
Get argument value.
Definition: argparser.cpp:182
Fawkes library namespace.
Parse command line arguments.
Definition: argparser.h:66
Base class for exceptions in Fawkes.
Definition: exception.h:36
Time tracking utility.
Definition: tracker.h:38
bool has_arg(const char *argn)
Check if argument has been supplied.
Definition: argparser.cpp:169