OmniAlgoSimpleDetection.hh

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) Massimo Cora' 2005-2006 <maxcvs@email.it>
00003  *
00004  *  This program is free software; you can redistribute it and/or modify
00005  *  it under the terms of the GNU General Public License as published by
00006  *  the Free Software Foundation; either version 2 of the License, or
00007  *  (at your option) any later version.
00008  *
00009  *  This program is distributed in the hope that it will be useful,
00010  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012  *  GNU General Public License for more details.
00013  *
00014  *  You should have received a copy of the GNU General Public License
00015  *  along with this program; if not, write to the Free Software
00016  *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00017  */
00018 
00019 
00020 #ifndef __OMNIALGO_SIMPLE_DETECTION_H__
00021 #define __OMNIALGO_SIMPLE_DETECTION_H__
00022 
00023 #include "../OmniConfig.hh"
00024 #include "../OmniConversion.hh"
00025 #include "../OmniMotionDetecting.hh"
00026 #include "../OmniTracking.hh"
00027 #include "../OmniTrackingTable.hh"
00028 #include "../OmniFaceDetecting.hh"
00029 #include "../HaarFaceDetecting.hh"
00030 #include "../OmniGCardConverter.hh"
00031 #include "../OmniCallback.hh"
00032 
00033 #include <cxtypes.h>
00034 #include <cv.h>
00035 #include <highgui.h>
00036 
00037 
00046 template <class ConverterT, class AngleT, class ImageT, class PointT>
00047 class OmniAlgoSimpleDetection {
00048 public:
00061         OmniAlgoSimpleDetection( OmniConversion<ConverterT, AngleT, ImageT, PointT> *conversion_klass,
00062                                                         IplImage *first_frame, const char** cascade_file_array, int cascade_length,
00063                                                         int freeze_frame_bound, double track_window_hitrate );
00064         virtual ~OmniAlgoSimpleDetection();
00065 
00071         void loop_next_frame( IplImage* frame );
00072         
00076         void loop_stop();
00077 
00089         static void on_window_trackable_wannabe( IplImage* omni_frame, 
00090                                                                                          int theta_start, 
00091                                                                                          int theta_end, 
00092                                                                                          int win_length,
00093                                                                                          void* callback_data );
00094 
00104         void register_image_callbacks( on_create_image_context_cb* create_image_context,
00105                                                                    on_image_do_action_cb* image_show,
00106                                                                    on_destroy_image_context_cb* destroy_image_context,
00107                                                                    void* callback_data
00108                                                                   );
00109         
00121         void register_all_image_callbacks( on_create_image_context_cb* create_image_context,
00122                                                                            on_image_do_action_cb* image_show,
00123                                                                            on_destroy_image_context_cb* destroy_image_context,
00124                                                                            void* callback_data
00125                                                                           );
00126 
00127 
00128 private:                // functions
00130         on_create_image_context_cb* create_image_context;
00131         
00133         on_image_do_action_cb* image_show;
00134         
00136         on_destroy_image_context_cb* destroy_image_context;
00137 
00138 private:                // data
00139 
00140 #ifdef SHOW_DETECTED_FACES
00141         int _face_detected_num;
00142 #endif  
00143 
00144         void* _callback_data_image_cb;  
00145         HaarFaceDetecting* _face_det;
00146         OmniTracking<ConverterT, AngleT, ImageT, PointT> * _tracking;
00147         OmniConversion<ConverterT, AngleT, ImageT, PointT> *_conv_table;
00148         OmniMotionDetecting<ConverterT, AngleT> *_motion_det;
00149 
00151         bool _is_running;
00152 };
00153 
00154 
00155 
00159 
00160 
00161 
00162 template <class ConverterT, class AngleT, class ImageT, class PointT>
00163 OmniAlgoSimpleDetection<ConverterT, AngleT, ImageT, PointT>::OmniAlgoSimpleDetection( 
00164                                                                                                 OmniConversion<ConverterT, AngleT, ImageT, PointT> *conversion_klass,
00165                                                                                                 IplImage *first_frame, 
00166                                                                                                 const char** cascade_file_array, int cascade_length,
00167                                                                                                 int freeze_frame_bound, double track_window_hitrate ) :
00168                                                                                 _conv_table( conversion_klass )
00169 {
00170         _is_running = false;
00171         _tracking = new OmniTracking<ConverterT, AngleT, ImageT, PointT>( first_frame, 
00172                                                                                                                                          _conv_table, 
00173                                                                                                                                          100, 
00174                                                                                                                                          freeze_frame_bound, 
00175                                                                                                                                          track_window_hitrate );
00176 
00177         _face_det = new HaarFaceDetecting( cascade_file_array, cascade_length );
00178 
00179         _motion_det = new OmniMotionDetecting<ConverterT, AngleT>( OmniAlgoSimpleDetection::on_window_trackable_wannabe,
00180                                                                                   this, _conv_table );
00181 
00182 #ifdef SHOW_DETECTED_FACES
00183         _face_detected_num = 0;
00184 #endif
00185 
00186         _callback_data_image_cb = NULL;
00187         // ok ok, we should also have created OmniTracking and OmniMotionDetecting instances
00188         // outside and then have passed them as parameters, so there wouldn't be the need
00189         // of use these callbacks, but anyway here they are. 
00190         // set the default callbacks. They can be changed with register_callbacks () call.
00191         register_image_callbacks( omnistuff_create_image_context, omnistuff_image_do_action, 
00192                                                           omnistuff_destroy_image_context, NULL );
00193 
00194         _is_running = true;
00195 }
00196 
00197 
00198 //-------------------------------------------------------------------------
00199 //
00200 
00201 template <class ConverterT, class AngleT, class ImageT, class PointT>
00202 OmniAlgoSimpleDetection<ConverterT, AngleT, ImageT, PointT>::~OmniAlgoSimpleDetection() 
00203 {
00204         delete _conv_table;
00205         delete _tracking;
00206         delete _face_det;
00207         delete _motion_det;
00208 }
00209 
00210 
00211 //-------------------------------------------------------------------------
00212 // static. It will be a callback function.
00213 
00214 template <class ConverterT, class AngleT, class ImageT, class PointT>
00215 void OmniAlgoSimpleDetection<ConverterT, AngleT, ImageT, PointT>::on_window_trackable_wannabe( 
00216                                                                                                                         IplImage* omni_frame, 
00217                                                                                                                         int theta_start,  int theta_end, 
00218                                                                                                                         int win_length, void* callback_data ) 
00219 {
00220 
00221         OmniAlgoSimpleDetection<ConverterT, AngleT, ImageT, PointT> *ctrl;
00222         ctrl = (OmniAlgoSimpleDetection<ConverterT, AngleT, ImageT, PointT> *)callback_data;
00223 
00224         // first of all test if the angle we want to test for new faces isn't
00225         // yet tracked
00226         if ( ctrl->_tracking->test_tracking_window_availability( theta_start, 
00227                                                                                                                         theta_end, 
00228                                                                                                                         win_length ) == true ) {
00229                 IplImage *pano_frame;
00230                 CvPoint face_center;
00231                 OmniAngle<int> angle;
00232 
00233                 angle.angle_start = theta_start;
00234                 angle.angle_end = theta_end;
00235                 angle.range = win_length;
00236 
00237                 // trasform the omni part of the angle 
00238                 pano_frame = ctrl->_conv_table->omni2pano( omni_frame, angle );
00239 
00240                 // haar test: detect new faces
00241                 if ( ctrl->_face_det->face_detected( pano_frame, &face_center ) == true ) {
00242 #ifdef SHOW_DETECTED_FACES
00243                         char title[30];
00244                         sprintf(title, "face_detected! - %d", ctrl->_face_detected_num++ );
00245                         ctrl->create_image_context( title );
00246 #endif
00247                         CvPoint omni_point;
00248 
00249                         // get the face center point back to the omni-image system
00250                         ctrl->_conv_table->pano2omni_xy( &face_center,
00251                                                                                   (AngleT)theta_start,
00252                                                                                   &omni_point );
00253 
00254                         // yes, now we can finally add the face center [always if it's not a
00255                         // false positive] to the tracker, that will follow it as long as it can.
00256                         ctrl->_tracking->add_point_to_track( omni_point );
00257 
00258 #ifdef SHOW_DETECTED_FACES
00259                         // FIXME 0
00260                         ctrl->image_show( pano_frame, 0, title, ctrl->_callback_data_image_cb );
00261 #endif
00262                 }
00263                 cvReleaseImage( &pano_frame );
00264         }
00265 }
00266 
00267 
00268 //-------------------------------------------------------------------------
00269 //
00270 
00271 template <class ConverterT, class AngleT, class ImageT, class PointT>
00272 void OmniAlgoSimpleDetection<ConverterT, AngleT, ImageT, PointT>::loop_next_frame( IplImage *frame ) 
00273 {
00274         if ( !_is_running ) {
00275                 return;
00276         }
00277 
00278 #ifdef SHOW_MAIN_VIDEO
00279         create_image_context( "video_window", _callback_data_image_cb );
00280 #endif
00281 
00282         // go on with the motion process of the frame
00283         _motion_det->process_next_frame( frame );
00284 
00285         // now we can track the points we have detected as faces
00286         _tracking->process_next_frame( frame );
00287 
00288 #ifdef SHOW_MAIN_VIDEO
00289         // FIXME 0
00290         image_show( frame, 0, "video_window", _callback_data_image_cb );
00291 #endif
00292 }
00293 
00294 
00295 //-------------------------------------------------------------------------
00296 // Must be called in a mutex context. Otherwise there should be strange effects
00297 
00298 template <class ConverterT, class AngleT, class ImageT, class PointT>
00299 void OmniAlgoSimpleDetection<ConverterT, AngleT, ImageT, PointT>::loop_stop() 
00300 {
00301         _is_running = false;
00302 
00303 #ifdef SHOW_MAIN_VIDEO  
00304         destroy_image_context( "video_window", _callback_data_image_cb );
00305 #endif
00306 
00307 #ifdef SHOW_DETECTED_FACES
00308         // destroy all the tracked faces window
00309         for ( int i = 0; i < _face_detected_num; i++ ) {
00310                 char title[30];
00311                 sprintf(title, "face_detected! - %d", i );
00312                 destroy_image_context( title );
00313         }
00314 #endif
00315 
00316 
00317 }
00318 
00319 //-------------------------------------------------------------------------
00320 //
00321 
00322 template <class ConverterT, class AngleT, class ImageT, class PointT>
00323 void OmniAlgoSimpleDetection<ConverterT, AngleT, ImageT, PointT>::register_image_callbacks( 
00324                                                                    on_create_image_context_cb* create_image_context,
00325                                                                    on_image_do_action_cb* image_show,
00326                                                                    on_destroy_image_context_cb* destroy_image_context,
00327                                                                    void* callback_data_on_image_cb
00328                                                                   )
00329 {
00330         this->create_image_context = create_image_context;
00331         this->image_show = image_show;
00332         this->destroy_image_context = destroy_image_context;
00333         this->_callback_data_image_cb = callback_data_on_image_cb;
00334 }
00335 
00336 //-------------------------------------------------------------------------
00337 //
00338 
00339 template <class ConverterT, class AngleT, class ImageT, class PointT>
00340 void OmniAlgoSimpleDetection<ConverterT, AngleT, ImageT, PointT>::register_all_image_callbacks( 
00341                                                                                 on_create_image_context_cb* create_image_context,
00342                                                                                 on_image_do_action_cb* image_show,
00343                                                                                 on_destroy_image_context_cb* destroy_image_context,
00344                                                                                 void* callback_data_on_image_cb
00345                                                                                 )
00346 {
00347         // instances.
00348         _tracking->register_image_callbacks( create_image_context, image_show, 
00349                                                          destroy_image_context, callback_data_on_image_cb );
00350         
00351         _motion_det->register_image_callbacks( create_image_context, image_show, 
00352                                                          destroy_image_context, callback_data_on_image_cb );
00353 }
00354 
00355 #endif  /* __OMNIALGO_SIMPLE_DETECTION_H__ */
00356 
00357 

Generated on Tue Dec 26 10:32:38 2006 for Omnimeeting by  doxygen 1.4.7