/*M/////////////////////////////////////////////////////////////////////////////////////// // // IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING. // // By downloading, copying, installing or using the software you agree to this license. // If you do not agree to this license, do not download, install, // copy or use the software. // // // Intel License Agreement // For Open Source Computer Vision Library // // Copyright (C) 2000, Intel Corporation, all rights reserved. // Third party copyrights are property of their respective owners. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // * Redistribution's of source code must retain the above copyright notice, // this list of conditions and the following disclaimer. // // * Redistribution's in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // * The name of Intel Corporation may not be used to endorse or promote products // derived from this software without specific prior written permission. // // This software is provided by the copyright holders and contributors "as is" and // any express or implied warranties, including, but not limited to, the implied // warranties of merchantability and fitness for a particular purpose are disclaimed. // In no event shall the Intel Corporation or contributors be liable for any direct, // indirect, incidental, special, exemplary, or consequential damages // (including, but not limited to, procurement of substitute goods or services; // loss of use, data, or profits; or business interruption) however caused // and on any theory of liability, whether in contract, strict liability, // or tort (including negligence or otherwise) arising in any way out of // the use of this software, even if advised of the possibility of such damage. // //M*/ /* * _cvhaartraining.h * * training of cascade of boosted classifiers based on haar features */ #ifndef __CVHAARTRAINING_H_ #define __CVHAARTRAINING_H_ #include "_cvcommon.h" #include "cvclassifier.h" #include #include /* parameters for tree cascade classifier training */ /* max number of clusters */ #define CV_MAX_CLUSTERS 3 /* term criteria for K-Means */ #define CV_TERM_CRITERIA() cvTermCriteria( CV_TERMCRIT_EPS, 1000, 1E-5 ) /* print statistic info */ #define CV_VERBOSE 1 #define CV_STAGE_CART_FILE_NAME "AdaBoostCARTHaarClassifier.txt" #define CV_HAAR_FEATURE_MAX 3 #define CV_HAAR_FEATURE_DESC_MAX 20 typedef int sum_type; typedef double sqsum_type; typedef short idx_type; #define CV_SUM_MAT_TYPE CV_32SC1 #define CV_SQSUM_MAT_TYPE CV_64FC1 #define CV_IDX_MAT_TYPE CV_16SC1 #define CV_STUMP_TRAIN_PORTION 100 #define CV_THRESHOLD_EPS (0.00001F) typedef struct CvTHaarFeature { char desc[CV_HAAR_FEATURE_DESC_MAX]; int tilted; struct { CvRect r; float weight; } rect[CV_HAAR_FEATURE_MAX]; } CvTHaarFeature; typedef struct CvFastHaarFeature { int tilted; struct { int p0, p1, p2, p3; float weight; } rect[CV_HAAR_FEATURE_MAX]; } CvFastHaarFeature; typedef struct CvIntHaarFeatures { CvSize winsize; int count; CvTHaarFeature* feature; CvFastHaarFeature* fastfeature; } CvIntHaarFeatures; CV_INLINE CvTHaarFeature cvHaarFeature( const char* desc, int x0, int y0, int w0, int h0, float wt0, int x1, int y1, int w1, int h1, float wt1, int x2 CV_DEFAULT( 0 ), int y2 CV_DEFAULT( 0 ), int w2 CV_DEFAULT( 0 ), int h2 CV_DEFAULT( 0 ), float wt2 CV_DEFAULT( 0.0F ) ); CV_INLINE CvTHaarFeature cvHaarFeature( const char* desc, int x0, int y0, int w0, int h0, float wt0, int x1, int y1, int w1, int h1, float wt1, int x2, int y2, int w2, int h2, float wt2 ) { CvTHaarFeature hf; assert( CV_HAAR_FEATURE_MAX >= 3 ); assert( strlen( desc ) < CV_HAAR_FEATURE_DESC_MAX ); strcpy( &(hf.desc[0]), desc ); hf.tilted = ( hf.desc[0] == 't' ); hf.rect[0].r.x = x0; hf.rect[0].r.y = y0; hf.rect[0].r.width = w0; hf.rect[0].r.height = h0; hf.rect[0].weight = wt0; hf.rect[1].r.x = x1; hf.rect[1].r.y = y1; hf.rect[1].r.width = w1; hf.rect[1].r.height = h1; hf.rect[1].weight = wt1; hf.rect[2].r.x = x2; hf.rect[2].r.y = y2; hf.rect[2].r.width = w2; hf.rect[2].r.height = h2; hf.rect[2].weight = wt2; return hf; } /* Prepared for training samples */ typedef struct CvHaarTrainingData { CvSize winsize; /* training image size */ int maxnum; /* maximum number of samples */ CvMat sum; /* sum images (each row represents image) */ CvMat tilted; /* tilted sum images (each row represents image) */ CvMat normfactor; /* normalization factor */ CvMat cls; /* classes. 1.0 - object, 0.0 - background */ CvMat weights; /* weights */ CvMat* valcache; /* precalculated feature values (CV_32FC1) */ CvMat* idxcache; /* presorted indices (CV_IDX_MAT_TYPE) */ } CvHaarTrainigData; /* Passed to callback functions */ typedef struct CvUserdata { CvHaarTrainingData* trainingData; CvIntHaarFeatures* haarFeatures; } CvUserdata; CV_INLINE CvUserdata cvUserdata( CvHaarTrainingData* trainingData, CvIntHaarFeatures* haarFeatures ); CV_INLINE CvUserdata cvUserdata( CvHaarTrainingData* trainingData, CvIntHaarFeatures* haarFeatures ) { CvUserdata userdata; userdata.trainingData = trainingData; userdata.haarFeatures = haarFeatures; return userdata; } #define CV_INT_HAAR_CLASSIFIER_FIELDS() \ float (*eval)( CvIntHaarClassifier*, sum_type*, sum_type*, float ); \ void (*save)( CvIntHaarClassifier*, FILE* file ); \ void (*release)( CvIntHaarClassifier** ); /* internal weak classifier*/ typedef struct CvIntHaarClassifier { CV_INT_HAAR_CLASSIFIER_FIELDS() } CvIntHaarClassifier; /* * CART classifier */ typedef struct CvCARTHaarClassifier { CV_INT_HAAR_CLASSIFIER_FIELDS() int count; int* compidx; CvTHaarFeature* feature; CvFastHaarFeature* fastfeature; float* threshold; int* left; int* right; float* val; } CvCARTHaarClassifier; /* internal stage classifier */ typedef struct CvStageHaarClassifier { CV_INT_HAAR_CLASSIFIER_FIELDS() int count; float threshold; CvIntHaarClassifier** classifier; } CvStageHaarClassifier; /* internal cascade classifier */ typedef struct CvCascadeHaarClassifier { CV_INT_HAAR_CLASSIFIER_FIELDS() int count; CvIntHaarClassifier** classifier; } CvCascadeHaarClassifier; /* internal tree cascade classifier node */ typedef struct CvTreeCascadeNode { CvStageHaarClassifier* stage; struct CvTreeCascadeNode* next; struct CvTreeCascadeNode* child; struct CvTreeCascadeNode* parent; struct CvTreeCascadeNode* next_same_level; struct CvTreeCascadeNode* child_eval; int idx; int leaf; } CvTreeCascadeNode; /* internal tree cascade classifier */ typedef struct CvTreeCascadeClassifier { CV_INT_HAAR_CLASSIFIER_FIELDS() CvTreeCascadeNode* root; /* root of the tree */ CvTreeCascadeNode* root_eval; /* root node for the filtering */ int next_idx; } CvTreeCascadeClassifier; CV_INLINE float cvEvalFastHaarFeature( const CvFastHaarFeature* feature, const sum_type* sum, const sum_type* tilted ) { const sum_type* img = feature->tilted ? tilted : sum; float ret = feature->rect[0].weight* (img[feature->rect[0].p0] - img[feature->rect[0].p1] - img[feature->rect[0].p2] + img[feature->rect[0].p3]) + feature->rect[1].weight* (img[feature->rect[1].p0] - img[feature->rect[1].p1] - img[feature->rect[1].p2] + img[feature->rect[1].p3]); if( feature->rect[2].weight != 0.0f ) ret += feature->rect[2].weight * ( img[feature->rect[2].p0] - img[feature->rect[2].p1] - img[feature->rect[2].p2] + img[feature->rect[2].p3] ); return ret; } typedef struct CvSampleDistortionData { IplImage* src; IplImage* erode; IplImage* dilate; IplImage* mask; IplImage* img; IplImage* maskimg; int dx; int dy; int bgcolor; } CvSampleDistortionData; /* * icvConvertToFastHaarFeature * * Convert to fast representation of haar features * * haarFeature - input array * fastHaarFeature - output array * size - size of arrays * step - row step for the integral image */ void icvConvertToFastHaarFeature( CvTHaarFeature* haarFeature, CvFastHaarFeature* fastHaarFeature, int size, int step ); void icvWriteVecHeader( FILE* file, int count, int width, int height ); void icvWriteVecSample( FILE* file, CvArr* sample ); void icvPlaceDistortedSample( CvArr* background, int inverse, int maxintensitydev, double maxxangle, double maxyangle, double maxzangle, int inscribe, double maxshiftf, double maxscalef, CvSampleDistortionData* data ); void icvEndSampleDistortion( CvSampleDistortionData* data ); int icvStartSampleDistortion( const char* imgfilename, int bgcolor, int bgthreshold, CvSampleDistortionData* data ); typedef int (*CvGetHaarTrainingDataCallback)( CvMat* img, void* userdata ); typedef struct CvVecFile { FILE* input; int count; int vecsize; int last; short* vector; } CvVecFile; int icvGetHaarTraininDataFromVecCallback( CvMat* img, void* userdata ); /* * icvGetHaarTrainingDataFromVec * * Fill with samples from .vec file, passed int icvGetHaarTrainingDataFromVec( CvHaarTrainingData* data, int first, int count, CvIntHaarClassifier* cascade, const char* filename, int* consumed ); */ CvIntHaarClassifier* icvCreateCARTHaarClassifier( int count ); void icvReleaseHaarClassifier( CvIntHaarClassifier** classifier ); void icvInitCARTHaarClassifier( CvCARTHaarClassifier* carthaar, CvCARTClassifier* cart, CvIntHaarFeatures* intHaarFeatures ); float icvEvalCARTHaarClassifier( CvIntHaarClassifier* classifier, sum_type* sum, sum_type* tilted, float normfactor ); CvIntHaarClassifier* icvCreateStageHaarClassifier( int count, float threshold ); void icvReleaseStageHaarClassifier( CvIntHaarClassifier** classifier ); float icvEvalStageHaarClassifier( CvIntHaarClassifier* classifier, sum_type* sum, sum_type* tilted, float normfactor ); CvIntHaarClassifier* icvCreateCascadeHaarClassifier( int count ); void icvReleaseCascadeHaarClassifier( CvIntHaarClassifier** classifier ); float icvEvalCascadeHaarClassifier( CvIntHaarClassifier* classifier, sum_type* sum, sum_type* tilted, float normfactor ); void icvSaveHaarFeature( CvTHaarFeature* feature, FILE* file ); void icvLoadHaarFeature( CvTHaarFeature* feature, FILE* file ); void icvSaveCARTHaarClassifier( CvIntHaarClassifier* classifier, FILE* file ); CvIntHaarClassifier* icvLoadCARTHaarClassifier( FILE* file, int step ); void icvSaveStageHaarClassifier( CvIntHaarClassifier* classifier, FILE* file ); CvIntHaarClassifier* icvLoadCARTStageHaarClassifier( const char* filename, int step ); /* tree cascade classifier */ float icvEvalTreeCascadeClassifier( CvIntHaarClassifier* classifier, sum_type* sum, sum_type* tilted, float normfactor ); void icvSetLeafNode( CvTreeCascadeClassifier* tree, CvTreeCascadeNode* leaf ); float icvEvalTreeCascadeClassifierFilter( CvIntHaarClassifier* classifier, sum_type* sum, sum_type* tilted, float normfactor ); CvTreeCascadeNode* icvCreateTreeCascadeNode(); void icvReleaseTreeCascadeNodes( CvTreeCascadeNode** node ); void icvReleaseTreeCascadeClassifier( CvIntHaarClassifier** classifier ); /* Prints out current tree structure to */ void icvPrintTreeCascade( CvTreeCascadeNode* root ); /* Loads tree cascade classifier */ CvIntHaarClassifier* icvLoadTreeCascadeClassifier( const char* filename, int step, int* splits ); /* Finds leaves belonging to maximal level and connects them via leaf->next_same_level */ CvTreeCascadeNode* icvFindDeepestLeaves( CvTreeCascadeClassifier* tree ); #endif /* __CVHAARTRAINING_H_ */