opencv/apps/haartraining/_cvhaartraining.h
2012-10-17 15:57:49 +04:00

415 lines
13 KiB
C

/*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 <cstring>
#include <cstdio>
/* 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 <data> with samples from .vec file, passed <cascade>
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 <stdout> */
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_ */