mirror of
https://github.com/opencv/opencv.git
synced 2024-11-25 19:50:38 +08:00
415 lines
13 KiB
C
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_ */
|