HaarFaceDetecting.cpp

Go to the documentation of this file.
00001 /*
00002  *  Copyright (C) Massimo Cora' 2005 <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 #include "HaarFaceDetecting.hh"
00021 
00022 
00023 //-------------------------------------------------------------------------
00024 // min_size_x and y are the min sized objects to search for.
00025 
00026 HaarFaceDetecting::HaarFaceDetecting( const char** cascade_file_array, 
00027                                                                          int array_length,
00028                                                                          int min_size_x /* =40 */,
00029                                                                          int min_size_y /* =40 */) {
00030 
00031         if ( array_length <= 0 ) {
00032                 ready_to_detect = false;                                                                                                 
00033                 return;
00034         }
00035 
00036         this->_min_size_x = min_size_x;
00037         this->_min_size_y = min_size_y;
00038         
00039         // will determine the length only of the usable files
00040         int arr_real_length = 0;
00041 
00042         _cascade_array = (CvHaarClassifierCascade**)calloc( array_length, sizeof(CvHaarClassifierCascade*));
00043 
00044     // load haar cascade classifiers
00045         for ( int i = 0; i < array_length; i++ ) {
00046                 _cascade_array[arr_real_length] = (CvHaarClassifierCascade*)cvLoad( cascade_file_array[i] );
00047 
00048                 // is it correctly loaded?
00049                 if ( _cascade_array[arr_real_length] )
00050                         arr_real_length++;
00051         }
00052 
00053         this->_cascade_array_length = arr_real_length;
00054         _storage = 0;
00055         if ( arr_real_length > 0 )
00056                 ready_to_detect = true;
00057         else
00058                 ready_to_detect = false;
00059 }
00060 
00061 
00062 //-------------------------------------------------------------------------
00063 //
00064 
00065 HaarFaceDetecting::~HaarFaceDetecting() {
00066 
00067         if ( _cascade_array_length > 0 )
00068                 free( _cascade_array );
00069 
00070         if ( _storage )
00071                 cvClearMemStorage( _storage );
00072 }
00073 
00074 
00075 //-------------------------------------------------------------------------
00076 // must be implemented
00077 
00078 bool HaarFaceDetecting::is_ready_to_detect() {
00079         return ready_to_detect;
00080 }
00081 
00082 
00083 //-------------------------------------------------------------------------
00084 // must be implemented
00085 // Will return a face center point that is suitable for a LK face tracking
00086 // if HAAR_DEBUG id defined than a red rectangle is painted around the tracked face
00087 
00088 bool HaarFaceDetecting::face_detected( IplImage *image, CvPoint *face_center ) {
00089 
00090     int scale = 1;
00091     CvPoint pt1, pt2;
00092         CvSeq* faces = NULL;
00093         bool detected_something = false;
00094 
00095         if ( !is_ready_to_detect() )
00096                 return false;
00097 
00098         if( !_storage )
00099         _storage = cvCreateMemStorage( 0 );
00100         else
00101                 cvClearMemStorage( _storage );
00102 
00103         for ( int i = 0; i < _cascade_array_length; i++ ) {
00104                 faces = cvHaarDetectObjects( image, _cascade_array[i], _storage,
00105                                                  1.1, 2, 0/*CV_HAAR_DO_CANNY_PRUNING*/,
00106                                                  cvSize(_min_size_x, _min_size_y) );
00107                 if ( faces->total ) {
00108                         detected_something = true;
00109                         break;
00110                 }
00111         }
00112 
00113         for( int i = 0; i < (faces ? faces->total : 0); i++ ) {
00114                 CvRect* r = (CvRect*)cvGetSeqElem( faces, i );
00115         pt1.x = r->x*scale;
00116         pt2.x = (r->x+r->width)*scale;
00117         pt1.y = r->y*scale;
00118         pt2.y = (r->y+r->height)*scale;
00119 
00120                 face_center->x = (pt1.x + pt2.x) / 2;
00121                 face_center->y = (pt1.y + pt2.y) / 2;
00122 
00123 #ifdef HAAR_DEBUG
00124                 cvRectangle( image, pt1, pt2, CV_RGB(255,0,0), 3, 8, 0 );
00125 #endif
00126     }
00127 
00128         if ( faces != NULL )
00129                 cvClearSeq( faces );
00130 
00131         return detected_something;
00132 }
00133 
00134 
00135 

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