CvFaceTrack.hh

Go to the documentation of this file.
00001 /*M///////////////////////////////////////////////////////////////////////////////////////
00002 //
00003 //  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
00004 //
00005 //  By downloading, copying, installing or using the software you agree to this license.
00006 //  If you do not agree to this license, do not download, install,
00007 //  copy or use the software.
00008 //
00009 //
00010 //                        Intel License Agreement
00011 //                For Open Source Computer Vision Library
00012 //                                   
00013 //                    Contributors License Agreement
00014 //
00015 // Copyright (C) 2006, Zecchini Fabio, all rights reserved.
00016 //
00017 // Copyright (C) 2006, Cora' Massimo, all rights reserved. Code adapting and integration into Omnimeeting.
00018 //
00019 // Third party copyrights are property of their respective owners.
00020 //
00021 // Redistribution and use in source and binary forms, with or without modification,
00022 // are permitted provided that the following conditions are met:
00023 //
00024 //   * Redistribution's of source code must retain the above copyright notice,
00025 //     this list of conditions and the following disclaimer.
00026 //
00027 //   * Redistribution's in binary form must reproduce the above copyright notice,
00028 //     this list of conditions and the following disclaimer in the documentation
00029 //     and/or other materials provided with the distribution.
00030 //
00031 //   * The name of Intel Corporation may not be used to endorse or promote products
00032 //     derived from this software without specific prior written permission.
00033 //
00034 // This software is provided by the copyright holders and contributors "as is" and
00035 // any express or implied warranties, including, but not limited to, the implied
00036 // warranties of merchantability and fitness for a particular purpose are disclaimed.
00037 // In no event shall the Intel Corporation or contributors be liable for any direct,
00038 // indirect, incidental, special, exemplary, or consequential damages
00039 // (including, but not limited to, procurement of substitute goods or services;
00040 // loss of use, data, or profits; or business interruption) however caused
00041 // and on any theory of liability, whether in contract, strict liability,
00042 // or tort (including negligence or otherwise) arising in any way out of
00043 // the use of this software, even if advised of the possibility of such damage.
00044 //
00045 //M*/
00046 
00047 #ifndef __CVFACETRACKING_H__
00048 #define __CVFACETRACKING_H__
00049 
00050 
00051 // opencv
00052 #include <cv.h>
00053 #include <highgui.h>
00054 
00055 #include <stdio.h>
00056 #include "OmniConfig.hh"
00057 
00066 template <class ConverterT, class AngleT>
00067 class CvFaceTrack
00068 {       
00070         IplImage *image;
00072         IplImage *grey ;
00074         IplImage *prev_grey ;
00076         IplImage *pyramid ;
00078         IplImage *prev_pyramid ;
00080         IplImage *swap_temp;
00082         CvSize size;
00083         
00085         int win_size ;
00087         int MAX_TRACKED_COUNT;
00088 
00090         CvPoint2D32f* tracked_points[2] ;
00092         CvPoint2D32f *swap_points;
00093         
00095         Cvface* face2track; 
00097         int face_count;
00098 
00100         char* tracked_status ;
00102         int tracked_count ;
00103 
00105         int track_flags ;
00106 
00108         bool started ;
00109         
00111         bool add_pt ;
00112         
00114         OmniConversion<ConverterT, AngleT, IplImage, CvPoint> *conv_table;
00115 
00116         // define here the default callbacks
00117         on_create_image_context_cb* create_image_context;
00118         on_image_do_action_cb* image_show;
00119         on_destroy_image_context_cb* destroy_image_context;
00120         void* _callback_data_image_cb;
00121         
00122 public:
00123         
00125 
00127         CvFaceTrack( OmniConversion<ConverterT, AngleT, IplImage, CvPoint> *conv_table );
00128 
00130         virtual ~CvFaceTrack();
00131         
00133 
00137         int cvAddPoint2Track( CvSeq * faces);
00138 
00140 
00144         void cvTrackNextFrame(IplImage *frame);
00145 
00146         void register_image_callbacks( on_create_image_context_cb* create_image_context,
00147                                                                    on_image_do_action_cb* image_show,                                                              
00148                                                                    on_destroy_image_context_cb* destroy_image_context,
00149                                                                    void* callback_data_image_cb
00150                                                                    );   
00151         
00152 private:
00153         
00155 
00158         void icvInitBuffer(IplImage *first_frame);
00159         
00160 };
00161 
00162 
00166 
00167 
00168 template <class ConverterT, class AngleT>
00169 CvFaceTrack<ConverterT, AngleT>::CvFaceTrack( OmniConversion<ConverterT, AngleT, IplImage, CvPoint> *c_table ) : 
00170                         conv_table ( c_table )
00171 {
00172         this->win_size = 10;
00173         this->MAX_TRACKED_COUNT = 20;
00174 
00175         this->tracked_points[0] = 0;
00176         this->tracked_points[1] = 0;
00177 
00178         this->tracked_status = 0;
00179         this->tracked_count = 0;
00180 
00181         this->track_flags = 0;
00182         this->started = false ;
00183 
00184         this->add_pt = false;
00185 
00186         this->face2track = (Cvface*)
00187                         cvAlloc( MAX_TRACKED_COUNT * sizeof(Cvface));
00188         
00189         this->face_count = 0 ;
00190         
00191         
00192         // set the default callbacks. They can be changed with register_callbacks () call.
00193         // callback data to NULL to avoid strange behaviour on pointers.
00194         register_image_callbacks( omnistuff_create_image_context, omnistuff_image_do_action, 
00195                                                          omnistuff_destroy_image_context, NULL );
00196         
00197 }
00198 
00199 template <class ConverterT, class AngleT>
00200 CvFaceTrack<ConverterT, AngleT>::~CvFaceTrack()
00201 {
00202 
00203 }
00204 
00205 template <class ConverterT, class AngleT>
00206 void 
00207 CvFaceTrack<ConverterT, AngleT>::cvTrackNextFrame(IplImage *frame)
00208 {
00209         if(!started)
00210         {
00211                 icvInitBuffer(frame);
00212                 started = true ;
00213         }
00214 
00215         int i, k;
00216 
00217     cvCopy( frame, image, 0 );
00218     cvCvtColor( image, grey, CV_BGR2GRAY );
00219 
00220         if( tracked_count > 0 )
00221         {
00222                 cvCalcOpticalFlowPyrLK( prev_grey, grey, prev_pyramid, pyramid,
00223                 tracked_points[0], tracked_points[1], tracked_count, cvSize(win_size,win_size), 3, tracked_status, 0,
00224                 cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03), track_flags );
00225                 
00226                 track_flags |= CV_LKFLOW_PYR_A_READY;
00227         
00228                 for( i = k = 0; i < tracked_count; i++ )
00229                 {
00230                         if( !tracked_status[i] )
00231                                 continue;
00232                 
00233                         tracked_points[1][k++] = tracked_points[1][i];
00234             
00235                         face2track[i].skin_face.skin_box.center = tracked_points[1][i];
00236 
00237                         //show windows faces
00238 
00239                         CvPoint angle_point = cvPointFrom32f( tracked_points[1][i] );
00240                         OmniAngle<int> angle_int;
00241 
00242                         float rad_angle = 
00243                                 atan2f( angle_point.y - ((float)conv_table->get_omni_center_y()),
00244                                                 angle_point.x - ((float)conv_table->get_omni_center_x()));
00245                         
00246                         OmniAngle<double> angle_double (rad_angle - FACE_TRACK_ANGLE_WINDOW, 
00247                                                                                  rad_angle + FACE_TRACK_ANGLE_WINDOW,
00248                                                                                  2 * FACE_TRACK_ANGLE_WINDOW);
00249                         
00250                         
00251                         // get the angle interval we want to track [= a window]
00252                         conv_table->angle_type_conversion( angle_double, angle_int );                   
00253 
00254                         char title[30];
00255                         sprintf(title, "Tracking face id #%d", k );
00256             create_image_context( title, _callback_data_image_cb );
00257                         IplImage *face;
00258 
00259                         face = conv_table->omni2pano( frame, angle_int );
00260 
00261                         // So !*DO NOT FREE*! the image when you call this function.
00262                         image_show( face, k, title, _callback_data_image_cb );
00263 
00264                         face2track[i].skin_face.skin_box.center = tracked_points[1][i];
00265                 }
00266         tracked_count = k;
00267         }
00268         
00269         if( add_pt && tracked_count < MAX_TRACKED_COUNT )
00270     {   
00271                 tracked_count = 0;
00272                 
00273                 for(int i = 0; i < face_count; i++)
00274                 {
00275                         tracked_points[1][tracked_count++] = face2track[i].skin_face.skin_box.center;
00276 
00277                         cvFindCornerSubPix( grey, tracked_points[1] + tracked_count - 1, 1,
00278                                                                 cvSize(win_size,win_size), cvSize(-1,-1),
00279                                                                 cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS,20,0.03));
00280                 }
00281                 
00282                 add_pt = false;
00283         }
00284 
00285     CV_SWAP( prev_grey, grey, swap_temp );
00286     CV_SWAP( prev_pyramid, pyramid, swap_temp );
00287     CV_SWAP( tracked_points[0], tracked_points[1], swap_points );
00288 }
00289 
00290 template <class ConverterT, class AngleT>
00291 int
00292 CvFaceTrack<ConverterT, AngleT>::cvAddPoint2Track(CvSeq * faces)
00293 {       
00294 
00295         //printf("face_tracking.cpp faces->total : %d \n", faces->total);       
00296         face_count = 0;
00297 
00298         for (int i = 0; i < faces->total ; i++)
00299         {       
00300                 Cvface *face;
00301                 face = (Cvface *)cvGetSeqElem( faces, i );
00302                 
00303                 if (!face->track)
00304                         continue;
00305                 
00306                 //printf("center : x=%f y=%f \n", face->skin_face.skin_box.center.x , face->skin_face.skin_box.center.y);
00307                 face2track[face_count++] = *face ;
00308 
00309         }
00310         
00311         if (face_count > 0)
00312         {
00313                 add_pt = true ;
00314         }
00315 
00316         return face_count;
00317 }
00318 
00319 template <class ConverterT, class AngleT>
00320 void
00321 CvFaceTrack<ConverterT, AngleT>::icvInitBuffer(IplImage *first_frame)
00322 {       
00323         this->size = cvGetSize(first_frame);
00324 
00325         // allocate all the buffers
00326     this->image = cvCreateImage( this->size, 8, 3 );
00327         this->image->origin = first_frame->origin;
00328 
00329         // grey image
00330     this->grey = cvCreateImage( this->size, 8, 1 );
00331     this->prev_grey = cvCreateImage( this->size, 8, 1 );
00332 
00333         // pyramid image
00334     this->pyramid = cvCreateImage( this->size, 8, 1 );
00335     this->prev_pyramid = cvCreateImage( this->size, 8, 1 );
00336 
00337         // alloc the space for the max number of tracked points
00338     this->tracked_points[0] = (CvPoint2D32f*)
00339                         cvAlloc( MAX_TRACKED_COUNT * sizeof(tracked_points[0][0]));
00340     this->tracked_points[1] = (CvPoint2D32f*)
00341                         cvAlloc( MAX_TRACKED_COUNT * sizeof(tracked_points[0][0]));
00342 
00343     this->tracked_status = (char*)cvAlloc( MAX_TRACKED_COUNT );
00344 
00345 
00346 }
00347 
00348 template <class ConverterT, class AngleT>
00349 void 
00350 CvFaceTrack<ConverterT, AngleT>::register_image_callbacks( 
00351                                                                    on_create_image_context_cb* create_image_context,
00352                                                                    on_image_do_action_cb* image_show,
00353                                                                    on_destroy_image_context_cb* destroy_image_context,
00354                                                                    void* callback_data
00355                                                                   )
00356 {
00357         this->create_image_context = create_image_context;
00358         this->image_show = image_show;
00359         this->destroy_image_context = destroy_image_context;
00360         this->_callback_data_image_cb = callback_data;
00361 }
00362 
00363 
00364 
00365 #endif /*_CVFACETRACKING_H_*/

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