mirror of
https://github.com/opencv/opencv.git
synced 2026-09-12 21:37:09 -05:00
removed contrib, legacy and softcsscade modules; removed latentsvm and datamatrix detector from objdetect. removed haartraining and sft apps.
some of the stuff will be moved to opencv_contrib module. in order to make this PR pass buildbot, please, comment off opencv_legacy, opencv_contrib and opencv_softcascade test runs.
This commit is contained in:
@@ -1,6 +1,4 @@
|
||||
add_definitions(-D__OPENCV_BUILD=1)
|
||||
link_libraries(${OPENCV_LINKER_LIBS})
|
||||
|
||||
add_subdirectory(haartraining)
|
||||
add_subdirectory(traincascade)
|
||||
add_subdirectory(sft)
|
||||
|
||||
@@ -1,89 +0,0 @@
|
||||
SET(OPENCV_HAARTRAINING_DEPS opencv_core opencv_imgproc opencv_photo opencv_ml opencv_highgui opencv_objdetect opencv_calib3d opencv_video opencv_features2d opencv_flann opencv_legacy)
|
||||
ocv_check_dependencies(${OPENCV_HAARTRAINING_DEPS})
|
||||
|
||||
if(NOT OCV_DEPENDENCIES_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(haartraining)
|
||||
|
||||
ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}" "${OpenCV_SOURCE_DIR}/include/opencv")
|
||||
ocv_include_modules(${OPENCV_HAARTRAINING_DEPS})
|
||||
|
||||
if(WIN32)
|
||||
link_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
endif()
|
||||
|
||||
link_libraries(${OPENCV_HAARTRAINING_DEPS} opencv_haartraining_engine)
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# Library
|
||||
# -----------------------------------------------------------
|
||||
set(cvhaartraining_lib_src
|
||||
_cvcommon.h
|
||||
cvclassifier.h
|
||||
_cvhaartraining.h
|
||||
cvhaartraining.h
|
||||
cvboost.cpp
|
||||
cvcommon.cpp
|
||||
cvhaarclassifier.cpp
|
||||
cvhaartraining.cpp
|
||||
cvsamples.cpp
|
||||
)
|
||||
|
||||
add_library(opencv_haartraining_engine STATIC ${cvhaartraining_lib_src})
|
||||
set_target_properties(opencv_haartraining_engine PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
INSTALL_NAME_DIR lib
|
||||
)
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# haartraining
|
||||
# -----------------------------------------------------------
|
||||
|
||||
add_executable(opencv_haartraining cvhaartraining.h haartraining.cpp)
|
||||
set_target_properties(opencv_haartraining PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
OUTPUT_NAME "opencv_haartraining")
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# createsamples
|
||||
# -----------------------------------------------------------
|
||||
|
||||
add_executable(opencv_createsamples cvhaartraining.h createsamples.cpp)
|
||||
set_target_properties(opencv_createsamples PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
OUTPUT_NAME "opencv_createsamples")
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# performance
|
||||
# -----------------------------------------------------------
|
||||
add_executable(opencv_performance performance.cpp)
|
||||
set_target_properties(opencv_performance PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
OUTPUT_NAME "opencv_performance")
|
||||
|
||||
# -----------------------------------------------------------
|
||||
# Install part
|
||||
# -----------------------------------------------------------
|
||||
|
||||
if(INSTALL_CREATE_DISTRIB)
|
||||
if(BUILD_SHARED_LIBS)
|
||||
install(TARGETS opencv_haartraining RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
|
||||
install(TARGETS opencv_createsamples RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
|
||||
install(TARGETS opencv_performance RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} CONFIGURATIONS Release COMPONENT dev)
|
||||
endif()
|
||||
else()
|
||||
install(TARGETS opencv_haartraining RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
|
||||
install(TARGETS opencv_createsamples RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
|
||||
install(TARGETS opencv_performance RUNTIME DESTINATION ${OPENCV_BIN_INSTALL_PATH} COMPONENT dev)
|
||||
endif()
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(opencv_performance PROPERTIES FOLDER "applications")
|
||||
set_target_properties(opencv_createsamples PROPERTIES FOLDER "applications")
|
||||
set_target_properties(opencv_haartraining PROPERTIES FOLDER "applications")
|
||||
set_target_properties(opencv_haartraining_engine PROPERTIES FOLDER "applications")
|
||||
endif()
|
||||
@@ -1,92 +0,0 @@
|
||||
/*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*/
|
||||
|
||||
#ifndef __CVCOMMON_H_
|
||||
#define __CVCOMMON_H_
|
||||
|
||||
#include "opencv2/core.hpp"
|
||||
|
||||
#include "cxcore.h"
|
||||
#include "cv.h"
|
||||
#include "cxmisc.h"
|
||||
|
||||
#define __BEGIN__ __CV_BEGIN__
|
||||
#define __END__ __CV_END__
|
||||
#define EXIT __CV_EXIT__
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 512
|
||||
#endif /* PATH_MAX */
|
||||
|
||||
int icvMkDir( const char* filename );
|
||||
|
||||
/* returns index at specified position from index matrix of any type.
|
||||
if matrix is NULL, then specified position is returned */
|
||||
CV_INLINE
|
||||
int icvGetIdxAt( CvMat* idx, int pos );
|
||||
|
||||
CV_INLINE
|
||||
int icvGetIdxAt( CvMat* idx, int pos )
|
||||
{
|
||||
if( idx == NULL )
|
||||
{
|
||||
return pos;
|
||||
}
|
||||
else
|
||||
{
|
||||
CvScalar sc;
|
||||
int type;
|
||||
|
||||
type = CV_MAT_TYPE( idx->type );
|
||||
cvRawDataToScalar( idx->data.ptr + pos *
|
||||
( (idx->rows == 1) ? CV_ELEM_SIZE( type ) : idx->step ), type, &sc );
|
||||
|
||||
return (int) sc.val[0];
|
||||
}
|
||||
}
|
||||
|
||||
/* debug functions */
|
||||
|
||||
#define CV_DEBUG_SAVE( ptr ) icvSave( ptr, __FILE__, __LINE__ );
|
||||
|
||||
void icvSave( const CvArr* ptr, const char* filename, int line );
|
||||
|
||||
#endif /* __CVCOMMON_H_ */
|
||||
@@ -1,414 +0,0 @@
|
||||
/*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_ */
|
||||
@@ -1,245 +0,0 @@
|
||||
/*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*/
|
||||
|
||||
/*
|
||||
* createsamples.cpp
|
||||
*
|
||||
* Create test/training samples
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "cvhaartraining.h"
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int i = 0;
|
||||
char* nullname = (char*)"(NULL)";
|
||||
char* vecname = NULL; /* .vec file name */
|
||||
char* infoname = NULL; /* file name with marked up image descriptions */
|
||||
char* imagename = NULL; /* single sample image */
|
||||
char* bgfilename = NULL; /* background */
|
||||
int num = 1000;
|
||||
int bgcolor = 0;
|
||||
int bgthreshold = 80;
|
||||
int invert = 0;
|
||||
int maxintensitydev = 40;
|
||||
double maxxangle = 1.1;
|
||||
double maxyangle = 1.1;
|
||||
double maxzangle = 0.5;
|
||||
int showsamples = 0;
|
||||
/* the samples are adjusted to this scale in the sample preview window */
|
||||
double scale = 4.0;
|
||||
int width = 24;
|
||||
int height = 24;
|
||||
|
||||
srand((unsigned int)time(0));
|
||||
|
||||
if( argc == 1 )
|
||||
{
|
||||
printf( "Usage: %s\n [-info <collection_file_name>]\n"
|
||||
" [-img <image_file_name>]\n"
|
||||
" [-vec <vec_file_name>]\n"
|
||||
" [-bg <background_file_name>]\n [-num <number_of_samples = %d>]\n"
|
||||
" [-bgcolor <background_color = %d>]\n"
|
||||
" [-inv] [-randinv] [-bgthresh <background_color_threshold = %d>]\n"
|
||||
" [-maxidev <max_intensity_deviation = %d>]\n"
|
||||
" [-maxxangle <max_x_rotation_angle = %f>]\n"
|
||||
" [-maxyangle <max_y_rotation_angle = %f>]\n"
|
||||
" [-maxzangle <max_z_rotation_angle = %f>]\n"
|
||||
" [-show [<scale = %f>]]\n"
|
||||
" [-w <sample_width = %d>]\n [-h <sample_height = %d>]\n",
|
||||
argv[0], num, bgcolor, bgthreshold, maxintensitydev,
|
||||
maxxangle, maxyangle, maxzangle, scale, width, height );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( i = 1; i < argc; ++i )
|
||||
{
|
||||
if( !strcmp( argv[i], "-info" ) )
|
||||
{
|
||||
infoname = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-img" ) )
|
||||
{
|
||||
imagename = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-vec" ) )
|
||||
{
|
||||
vecname = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bg" ) )
|
||||
{
|
||||
bgfilename = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-num" ) )
|
||||
{
|
||||
num = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bgcolor" ) )
|
||||
{
|
||||
bgcolor = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bgthresh" ) )
|
||||
{
|
||||
bgthreshold = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-inv" ) )
|
||||
{
|
||||
invert = 1;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-randinv" ) )
|
||||
{
|
||||
invert = CV_RANDOM_INVERT;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxidev" ) )
|
||||
{
|
||||
maxintensitydev = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxxangle" ) )
|
||||
{
|
||||
maxxangle = atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxyangle" ) )
|
||||
{
|
||||
maxyangle = atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxzangle" ) )
|
||||
{
|
||||
maxzangle = atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-show" ) )
|
||||
{
|
||||
showsamples = 1;
|
||||
if( i+1 < argc && strlen( argv[i+1] ) > 0 && argv[i+1][0] != '-' )
|
||||
{
|
||||
double d;
|
||||
d = strtod( argv[i+1], 0 );
|
||||
if( d != -HUGE_VAL && d != HUGE_VAL && d > 0 ) scale = d;
|
||||
++i;
|
||||
}
|
||||
}
|
||||
else if( !strcmp( argv[i], "-w" ) )
|
||||
{
|
||||
width = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-h" ) )
|
||||
{
|
||||
height = atoi( argv[++i] );
|
||||
}
|
||||
}
|
||||
|
||||
printf( "Info file name: %s\n", ((infoname == NULL) ? nullname : infoname ) );
|
||||
printf( "Img file name: %s\n", ((imagename == NULL) ? nullname : imagename ) );
|
||||
printf( "Vec file name: %s\n", ((vecname == NULL) ? nullname : vecname ) );
|
||||
printf( "BG file name: %s\n", ((bgfilename == NULL) ? nullname : bgfilename ) );
|
||||
printf( "Num: %d\n", num );
|
||||
printf( "BG color: %d\n", bgcolor );
|
||||
printf( "BG threshold: %d\n", bgthreshold );
|
||||
printf( "Invert: %s\n", (invert == CV_RANDOM_INVERT) ? "RANDOM"
|
||||
: ( (invert) ? "TRUE" : "FALSE" ) );
|
||||
printf( "Max intensity deviation: %d\n", maxintensitydev );
|
||||
printf( "Max x angle: %g\n", maxxangle );
|
||||
printf( "Max y angle: %g\n", maxyangle );
|
||||
printf( "Max z angle: %g\n", maxzangle );
|
||||
printf( "Show samples: %s\n", (showsamples) ? "TRUE" : "FALSE" );
|
||||
if( showsamples )
|
||||
{
|
||||
printf( "Scale: %g\n", scale );
|
||||
}
|
||||
printf( "Width: %d\n", width );
|
||||
printf( "Height: %d\n", height );
|
||||
|
||||
/* determine action */
|
||||
if( imagename && vecname )
|
||||
{
|
||||
printf( "Create training samples from single image applying distortions...\n" );
|
||||
|
||||
cvCreateTrainingSamples( vecname, imagename, bgcolor, bgthreshold, bgfilename,
|
||||
num, invert, maxintensitydev,
|
||||
maxxangle, maxyangle, maxzangle,
|
||||
showsamples, width, height );
|
||||
|
||||
printf( "Done\n" );
|
||||
}
|
||||
else if( imagename && bgfilename && infoname )
|
||||
{
|
||||
printf( "Create test samples from single image applying distortions...\n" );
|
||||
|
||||
cvCreateTestSamples( infoname, imagename, bgcolor, bgthreshold, bgfilename, num,
|
||||
invert, maxintensitydev,
|
||||
maxxangle, maxyangle, maxzangle, showsamples, width, height );
|
||||
|
||||
printf( "Done\n" );
|
||||
}
|
||||
else if( infoname && vecname )
|
||||
{
|
||||
int total;
|
||||
|
||||
printf( "Create training samples from images collection...\n" );
|
||||
|
||||
total = cvCreateTrainingSamplesFromInfo( infoname, vecname, num, showsamples,
|
||||
width, height );
|
||||
|
||||
printf( "Done. Created %d samples\n", total );
|
||||
}
|
||||
else if( vecname )
|
||||
{
|
||||
printf( "View samples from vec file (press ESC to exit)...\n" );
|
||||
|
||||
cvShowVecSamples( vecname, width, height, scale );
|
||||
|
||||
printf( "Done\n" );
|
||||
}
|
||||
else
|
||||
{
|
||||
printf( "Nothing to do\n" );
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,729 +0,0 @@
|
||||
/*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*/
|
||||
|
||||
/*
|
||||
* File cvclassifier.h
|
||||
*
|
||||
* Classifier types
|
||||
*/
|
||||
|
||||
#ifndef _CVCLASSIFIER_H_
|
||||
#define _CVCLASSIFIER_H_
|
||||
|
||||
#include <cmath>
|
||||
#include "cxcore.h"
|
||||
|
||||
#define CV_BOOST_API
|
||||
|
||||
/* Convert matrix to vector */
|
||||
#define CV_MAT2VEC( mat, vdata, vstep, num ) \
|
||||
assert( (mat).rows == 1 || (mat).cols == 1 ); \
|
||||
(vdata) = ((mat).data.ptr); \
|
||||
if( (mat).rows == 1 ) \
|
||||
{ \
|
||||
(vstep) = CV_ELEM_SIZE( (mat).type ); \
|
||||
(num) = (mat).cols; \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
(vstep) = (mat).step; \
|
||||
(num) = (mat).rows; \
|
||||
}
|
||||
|
||||
/* Set up <sample> matrix header to be <num> sample of <trainData> samples matrix */
|
||||
#define CV_GET_SAMPLE( trainData, tdflags, num, sample ) \
|
||||
if( CV_IS_ROW_SAMPLE( tdflags ) ) \
|
||||
{ \
|
||||
cvInitMatHeader( &(sample), 1, (trainData).cols, \
|
||||
CV_MAT_TYPE( (trainData).type ), \
|
||||
((trainData).data.ptr + (num) * (trainData).step), \
|
||||
(trainData).step ); \
|
||||
} \
|
||||
else \
|
||||
{ \
|
||||
cvInitMatHeader( &(sample), (trainData).rows, 1, \
|
||||
CV_MAT_TYPE( (trainData).type ), \
|
||||
((trainData).data.ptr + (num) * CV_ELEM_SIZE( (trainData).type )), \
|
||||
(trainData).step ); \
|
||||
}
|
||||
|
||||
#define CV_GET_SAMPLE_STEP( trainData, tdflags, sstep ) \
|
||||
(sstep) = ( ( CV_IS_ROW_SAMPLE( tdflags ) ) \
|
||||
? (trainData).step : CV_ELEM_SIZE( (trainData).type ) );
|
||||
|
||||
|
||||
#define CV_LOGRATIO_THRESHOLD 0.00001F
|
||||
|
||||
/* log( val / (1 - val ) ) */
|
||||
CV_INLINE float cvLogRatio( float val );
|
||||
|
||||
CV_INLINE float cvLogRatio( float val )
|
||||
{
|
||||
float tval;
|
||||
|
||||
tval = MAX(CV_LOGRATIO_THRESHOLD, MIN( 1.0F - CV_LOGRATIO_THRESHOLD, (val) ));
|
||||
return logf( tval / (1.0F - tval) );
|
||||
}
|
||||
|
||||
|
||||
/* flags values for classifier consturctor flags parameter */
|
||||
|
||||
/* each trainData matrix column is a sample */
|
||||
#define CV_COL_SAMPLE 0
|
||||
|
||||
/* each trainData matrix row is a sample */
|
||||
#define CV_ROW_SAMPLE 1
|
||||
|
||||
#ifndef CV_IS_ROW_SAMPLE
|
||||
# define CV_IS_ROW_SAMPLE( flags ) ( ( flags ) & CV_ROW_SAMPLE )
|
||||
#endif
|
||||
|
||||
/* Classifier supports tune function */
|
||||
#define CV_TUNABLE (1 << 1)
|
||||
|
||||
#define CV_IS_TUNABLE( flags ) ( (flags) & CV_TUNABLE )
|
||||
|
||||
|
||||
/* classifier fields common to all classifiers */
|
||||
#define CV_CLASSIFIER_FIELDS() \
|
||||
int flags; \
|
||||
float(*eval)( struct CvClassifier*, CvMat* ); \
|
||||
void (*tune)( struct CvClassifier*, CvMat*, int flags, CvMat*, CvMat*, CvMat*, \
|
||||
CvMat*, CvMat* ); \
|
||||
int (*save)( struct CvClassifier*, const char* file_name ); \
|
||||
void (*release)( struct CvClassifier** );
|
||||
|
||||
typedef struct CvClassifier
|
||||
{
|
||||
CV_CLASSIFIER_FIELDS()
|
||||
} CvClassifier;
|
||||
|
||||
#define CV_CLASSIFIER_TRAIN_PARAM_FIELDS()
|
||||
typedef struct CvClassifierTrainParams
|
||||
{
|
||||
CV_CLASSIFIER_TRAIN_PARAM_FIELDS()
|
||||
} CvClassifierTrainParams;
|
||||
|
||||
|
||||
/*
|
||||
Common classifier constructor:
|
||||
CvClassifier* cvCreateMyClassifier( CvMat* trainData,
|
||||
int flags,
|
||||
CvMat* trainClasses,
|
||||
CvMat* typeMask,
|
||||
CvMat* missedMeasurementsMask CV_DEFAULT(0),
|
||||
CvCompIdx* compIdx CV_DEFAULT(0),
|
||||
CvMat* sampleIdx CV_DEFAULT(0),
|
||||
CvMat* weights CV_DEFAULT(0),
|
||||
CvClassifierTrainParams* trainParams CV_DEFAULT(0)
|
||||
)
|
||||
|
||||
*/
|
||||
|
||||
typedef CvClassifier* (*CvClassifierConstructor)( CvMat*, int, CvMat*, CvMat*, CvMat*,
|
||||
CvMat*, CvMat*, CvMat*,
|
||||
CvClassifierTrainParams* );
|
||||
|
||||
typedef enum CvStumpType
|
||||
{
|
||||
CV_CLASSIFICATION = 0,
|
||||
CV_CLASSIFICATION_CLASS = 1,
|
||||
CV_REGRESSION = 2
|
||||
} CvStumpType;
|
||||
|
||||
typedef enum CvStumpError
|
||||
{
|
||||
CV_MISCLASSIFICATION = 0,
|
||||
CV_GINI = 1,
|
||||
CV_ENTROPY = 2,
|
||||
CV_SQUARE = 3
|
||||
} CvStumpError;
|
||||
|
||||
|
||||
typedef struct CvStumpTrainParams
|
||||
{
|
||||
CV_CLASSIFIER_TRAIN_PARAM_FIELDS()
|
||||
CvStumpType type;
|
||||
CvStumpError error;
|
||||
} CvStumpTrainParams;
|
||||
|
||||
typedef struct CvMTStumpTrainParams
|
||||
{
|
||||
CV_CLASSIFIER_TRAIN_PARAM_FIELDS()
|
||||
CvStumpType type;
|
||||
CvStumpError error;
|
||||
int portion; /* number of components calculated in each thread */
|
||||
int numcomp; /* total number of components */
|
||||
|
||||
/* callback which fills <mat> with components [first, first+num[ */
|
||||
void (*getTrainData)( CvMat* mat, CvMat* sampleIdx, CvMat* compIdx,
|
||||
int first, int num, void* userdata );
|
||||
CvMat* sortedIdx; /* presorted samples indices */
|
||||
void* userdata; /* passed to callback */
|
||||
} CvMTStumpTrainParams;
|
||||
|
||||
typedef struct CvStumpClassifier
|
||||
{
|
||||
CV_CLASSIFIER_FIELDS()
|
||||
int compidx;
|
||||
|
||||
float lerror; /* impurity of the right node */
|
||||
float rerror; /* impurity of the left node */
|
||||
|
||||
float threshold;
|
||||
float left;
|
||||
float right;
|
||||
} CvStumpClassifier;
|
||||
|
||||
typedef struct CvCARTTrainParams
|
||||
{
|
||||
CV_CLASSIFIER_TRAIN_PARAM_FIELDS()
|
||||
/* desired number of internal nodes */
|
||||
int count;
|
||||
CvClassifierTrainParams* stumpTrainParams;
|
||||
CvClassifierConstructor stumpConstructor;
|
||||
|
||||
/*
|
||||
* Split sample indices <idx>
|
||||
* on the "left" indices <left> and "right" indices <right>
|
||||
* according to samples components <compidx> values and <threshold>.
|
||||
*
|
||||
* NOTE: Matrices <left> and <right> must be allocated using cvCreateMat function
|
||||
* since they are freed using cvReleaseMat function
|
||||
*
|
||||
* If it is NULL then the default implementation which evaluates training
|
||||
* samples from <trainData> passed to classifier constructor is used
|
||||
*/
|
||||
void (*splitIdx)( int compidx, float threshold,
|
||||
CvMat* idx, CvMat** left, CvMat** right,
|
||||
void* userdata );
|
||||
void* userdata;
|
||||
} CvCARTTrainParams;
|
||||
|
||||
typedef struct CvCARTClassifier
|
||||
{
|
||||
CV_CLASSIFIER_FIELDS()
|
||||
/* number of internal nodes */
|
||||
int count;
|
||||
|
||||
/* internal nodes (each array of <count> elements) */
|
||||
int* compidx;
|
||||
float* threshold;
|
||||
int* left;
|
||||
int* right;
|
||||
|
||||
/* leaves (array of <count>+1 elements) */
|
||||
float* val;
|
||||
} CvCARTClassifier;
|
||||
|
||||
CV_BOOST_API
|
||||
void cvGetSortedIndices( CvMat* val, CvMat* idx, int sortcols CV_DEFAULT( 0 ) );
|
||||
|
||||
CV_BOOST_API
|
||||
void cvReleaseStumpClassifier( CvClassifier** classifier );
|
||||
|
||||
CV_BOOST_API
|
||||
float cvEvalStumpClassifier( CvClassifier* classifier, CvMat* sample );
|
||||
|
||||
CV_BOOST_API
|
||||
CvClassifier* cvCreateStumpClassifier( CvMat* trainData,
|
||||
int flags,
|
||||
CvMat* trainClasses,
|
||||
CvMat* typeMask,
|
||||
CvMat* missedMeasurementsMask CV_DEFAULT(0),
|
||||
CvMat* compIdx CV_DEFAULT(0),
|
||||
CvMat* sampleIdx CV_DEFAULT(0),
|
||||
CvMat* weights CV_DEFAULT(0),
|
||||
CvClassifierTrainParams* trainParams CV_DEFAULT(0) );
|
||||
|
||||
/*
|
||||
* cvCreateMTStumpClassifier
|
||||
*
|
||||
* Multithreaded stump classifier constructor
|
||||
* Includes huge train data support through callback function
|
||||
*/
|
||||
CV_BOOST_API
|
||||
CvClassifier* cvCreateMTStumpClassifier( CvMat* trainData,
|
||||
int flags,
|
||||
CvMat* trainClasses,
|
||||
CvMat* typeMask,
|
||||
CvMat* missedMeasurementsMask,
|
||||
CvMat* compIdx,
|
||||
CvMat* sampleIdx,
|
||||
CvMat* weights,
|
||||
CvClassifierTrainParams* trainParams );
|
||||
|
||||
/*
|
||||
* cvCreateCARTClassifier
|
||||
*
|
||||
* CART classifier constructor
|
||||
*/
|
||||
CV_BOOST_API
|
||||
CvClassifier* cvCreateCARTClassifier( CvMat* trainData,
|
||||
int flags,
|
||||
CvMat* trainClasses,
|
||||
CvMat* typeMask,
|
||||
CvMat* missedMeasurementsMask,
|
||||
CvMat* compIdx,
|
||||
CvMat* sampleIdx,
|
||||
CvMat* weights,
|
||||
CvClassifierTrainParams* trainParams );
|
||||
|
||||
CV_BOOST_API
|
||||
void cvReleaseCARTClassifier( CvClassifier** classifier );
|
||||
|
||||
CV_BOOST_API
|
||||
float cvEvalCARTClassifier( CvClassifier* classifier, CvMat* sample );
|
||||
|
||||
/****************************************************************************************\
|
||||
* Boosting *
|
||||
\****************************************************************************************/
|
||||
|
||||
/*
|
||||
* CvBoostType
|
||||
*
|
||||
* The CvBoostType enumeration specifies the boosting type.
|
||||
*
|
||||
* Remarks
|
||||
* Four different boosting variants for 2 class classification problems are supported:
|
||||
* Discrete AdaBoost, Real AdaBoost, LogitBoost and Gentle AdaBoost.
|
||||
* The L2 (2 class classification problems) and LK (K class classification problems)
|
||||
* algorithms are close to LogitBoost but more numerically stable than last one.
|
||||
* For regression three different loss functions are supported:
|
||||
* Least square, least absolute deviation and huber loss.
|
||||
*/
|
||||
typedef enum CvBoostType
|
||||
{
|
||||
CV_DABCLASS = 0, /* 2 class Discrete AdaBoost */
|
||||
CV_RABCLASS = 1, /* 2 class Real AdaBoost */
|
||||
CV_LBCLASS = 2, /* 2 class LogitBoost */
|
||||
CV_GABCLASS = 3, /* 2 class Gentle AdaBoost */
|
||||
CV_L2CLASS = 4, /* classification (2 class problem) */
|
||||
CV_LKCLASS = 5, /* classification (K class problem) */
|
||||
CV_LSREG = 6, /* least squares regression */
|
||||
CV_LADREG = 7, /* least absolute deviation regression */
|
||||
CV_MREG = 8 /* M-regression (Huber loss) */
|
||||
} CvBoostType;
|
||||
|
||||
/****************************************************************************************\
|
||||
* Iterative training functions *
|
||||
\****************************************************************************************/
|
||||
|
||||
/*
|
||||
* CvBoostTrainer
|
||||
*
|
||||
* The CvBoostTrainer structure represents internal boosting trainer.
|
||||
*/
|
||||
typedef struct CvBoostTrainer CvBoostTrainer;
|
||||
|
||||
/*
|
||||
* cvBoostStartTraining
|
||||
*
|
||||
* The cvBoostStartTraining function starts training process and calculates
|
||||
* response values and weights for the first weak classifier training.
|
||||
*
|
||||
* Parameters
|
||||
* trainClasses
|
||||
* Vector of classes of training samples classes. Each element must be 0 or 1 and
|
||||
* of type CV_32FC1.
|
||||
* weakTrainVals
|
||||
* Vector of response values for the first trained weak classifier.
|
||||
* Must be of type CV_32FC1.
|
||||
* weights
|
||||
* Weight vector of training samples for the first trained weak classifier.
|
||||
* Must be of type CV_32FC1.
|
||||
* type
|
||||
* Boosting type. CV_DABCLASS, CV_RABCLASS, CV_LBCLASS, CV_GABCLASS
|
||||
* types are supported.
|
||||
*
|
||||
* Return Values
|
||||
* The return value is a pointer to internal trainer structure which is used
|
||||
* to perform next training iterations.
|
||||
*
|
||||
* Remarks
|
||||
* weakTrainVals and weights must be allocated before calling the function
|
||||
* and of the same size as trainingClasses. Usually weights should be initialized
|
||||
* with 1.0 value.
|
||||
* The function calculates response values and weights for the first weak
|
||||
* classifier training and stores them into weakTrainVals and weights
|
||||
* respectively.
|
||||
* Note, the training of the weak classifier using weakTrainVals, weight,
|
||||
* trainingData is outside of this function.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
CvBoostTrainer* cvBoostStartTraining( CvMat* trainClasses,
|
||||
CvMat* weakTrainVals,
|
||||
CvMat* weights,
|
||||
CvMat* sampleIdx,
|
||||
CvBoostType type );
|
||||
/*
|
||||
* cvBoostNextWeakClassifier
|
||||
*
|
||||
* The cvBoostNextWeakClassifier function performs next training
|
||||
* iteration and caluclates response values and weights for the next weak
|
||||
* classifier training.
|
||||
*
|
||||
* Parameters
|
||||
* weakEvalVals
|
||||
* Vector of values obtained by evaluation of each sample with
|
||||
* the last trained weak classifier (iteration i). Must be of CV_32FC1 type.
|
||||
* trainClasses
|
||||
* Vector of classes of training samples. Each element must be 0 or 1,
|
||||
* and of type CV_32FC1.
|
||||
* weakTrainVals
|
||||
* Vector of response values for the next weak classifier training
|
||||
* (iteration i+1). Must be of type CV_32FC1.
|
||||
* weights
|
||||
* Weight vector of training samples for the next weak classifier training
|
||||
* (iteration i+1). Must be of type CV_32FC1.
|
||||
* trainer
|
||||
* A pointer to internal trainer returned by the cvBoostStartTraining
|
||||
* function call.
|
||||
*
|
||||
* Return Values
|
||||
* The return value is the coefficient for the last trained weak classifier.
|
||||
*
|
||||
* Remarks
|
||||
* weakTrainVals and weights must be exactly the same vectors as used in
|
||||
* the cvBoostStartTraining function call and should not be modified.
|
||||
* The function calculates response values and weights for the next weak
|
||||
* classifier training and stores them into weakTrainVals and weights
|
||||
* respectively.
|
||||
* Note, the training of the weak classifier of iteration i+1 using
|
||||
* weakTrainVals, weight, trainingData is outside of this function.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
float cvBoostNextWeakClassifier( CvMat* weakEvalVals,
|
||||
CvMat* trainClasses,
|
||||
CvMat* weakTrainVals,
|
||||
CvMat* weights,
|
||||
CvBoostTrainer* trainer );
|
||||
|
||||
/*
|
||||
* cvBoostEndTraining
|
||||
*
|
||||
* The cvBoostEndTraining function finishes training process and releases
|
||||
* internally allocated memory.
|
||||
*
|
||||
* Parameters
|
||||
* trainer
|
||||
* A pointer to a pointer to internal trainer returned by the cvBoostStartTraining
|
||||
* function call.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
void cvBoostEndTraining( CvBoostTrainer** trainer );
|
||||
|
||||
/****************************************************************************************\
|
||||
* Boosted tree models *
|
||||
\****************************************************************************************/
|
||||
|
||||
/*
|
||||
* CvBtClassifier
|
||||
*
|
||||
* The CvBtClassifier structure represents boosted tree model.
|
||||
*
|
||||
* Members
|
||||
* flags
|
||||
* Flags. If CV_IS_TUNABLE( flags ) != 0 then the model supports tuning.
|
||||
* eval
|
||||
* Evaluation function. Returns sample predicted class (0, 1, etc.)
|
||||
* for classification or predicted value for regression.
|
||||
* tune
|
||||
* Tune function. If the model supports tuning then tune call performs
|
||||
* one more boosting iteration if passed to the function flags parameter
|
||||
* is CV_TUNABLE otherwise releases internally allocated for tuning memory
|
||||
* and makes the model untunable.
|
||||
* NOTE: Since tuning uses the pointers to parameters,
|
||||
* passed to the cvCreateBtClassifier function, they should not be modified
|
||||
* or released between tune calls.
|
||||
* save
|
||||
* This function stores the model into given file.
|
||||
* release
|
||||
* This function releases the model.
|
||||
* type
|
||||
* Boosted tree model type.
|
||||
* numclasses
|
||||
* Number of classes for CV_LKCLASS type or 1 for all other types.
|
||||
* numiter
|
||||
* Number of iterations. Number of weak classifiers is equal to number
|
||||
* of iterations for all types except CV_LKCLASS. For CV_LKCLASS type
|
||||
* number of weak classifiers is (numiter * numclasses).
|
||||
* numfeatures
|
||||
* Number of features in sample.
|
||||
* trees
|
||||
* Stores weak classifiers when the model does not support tuning.
|
||||
* seq
|
||||
* Stores weak classifiers when the model supports tuning.
|
||||
* trainer
|
||||
* Pointer to internal tuning parameters if the model supports tuning.
|
||||
*/
|
||||
typedef struct CvBtClassifier
|
||||
{
|
||||
CV_CLASSIFIER_FIELDS()
|
||||
|
||||
CvBoostType type;
|
||||
int numclasses;
|
||||
int numiter;
|
||||
int numfeatures;
|
||||
union
|
||||
{
|
||||
CvCARTClassifier** trees;
|
||||
CvSeq* seq;
|
||||
};
|
||||
void* trainer;
|
||||
} CvBtClassifier;
|
||||
|
||||
/*
|
||||
* CvBtClassifierTrainParams
|
||||
*
|
||||
* The CvBtClassifierTrainParams structure stores training parameters for
|
||||
* boosted tree model.
|
||||
*
|
||||
* Members
|
||||
* type
|
||||
* Boosted tree model type.
|
||||
* numiter
|
||||
* Desired number of iterations.
|
||||
* param
|
||||
* Parameter Model Type Parameter Meaning
|
||||
* param[0] Any Shrinkage factor
|
||||
* param[1] CV_MREG alpha. (1-alpha) determines "break-down" point of
|
||||
* the training procedure, i.e. the fraction of samples
|
||||
* that can be arbitrary modified without serious
|
||||
* degrading the quality of the result.
|
||||
* CV_DABCLASS, Weight trimming factor.
|
||||
* CV_RABCLASS,
|
||||
* CV_LBCLASS,
|
||||
* CV_GABCLASS,
|
||||
* CV_L2CLASS,
|
||||
* CV_LKCLASS
|
||||
* numsplits
|
||||
* Desired number of splits in each tree.
|
||||
*/
|
||||
typedef struct CvBtClassifierTrainParams
|
||||
{
|
||||
CV_CLASSIFIER_TRAIN_PARAM_FIELDS()
|
||||
|
||||
CvBoostType type;
|
||||
int numiter;
|
||||
float param[2];
|
||||
int numsplits;
|
||||
} CvBtClassifierTrainParams;
|
||||
|
||||
/*
|
||||
* cvCreateBtClassifier
|
||||
*
|
||||
* The cvCreateBtClassifier function creates boosted tree model.
|
||||
*
|
||||
* Parameters
|
||||
* trainData
|
||||
* Matrix of feature values. Must have CV_32FC1 type.
|
||||
* flags
|
||||
* Determines how samples are stored in trainData.
|
||||
* One of CV_ROW_SAMPLE or CV_COL_SAMPLE.
|
||||
* Optionally may be combined with CV_TUNABLE to make tunable model.
|
||||
* trainClasses
|
||||
* Vector of responses for regression or classes (0, 1, 2, etc.) for classification.
|
||||
* typeMask,
|
||||
* missedMeasurementsMask,
|
||||
* compIdx
|
||||
* Not supported. Must be NULL.
|
||||
* sampleIdx
|
||||
* Indices of samples used in training. If NULL then all samples are used.
|
||||
* For CV_DABCLASS, CV_RABCLASS, CV_LBCLASS and CV_GABCLASS must be NULL.
|
||||
* weights
|
||||
* Not supported. Must be NULL.
|
||||
* trainParams
|
||||
* A pointer to CvBtClassifierTrainParams structure. Training parameters.
|
||||
* See CvBtClassifierTrainParams description for details.
|
||||
*
|
||||
* Return Values
|
||||
* The return value is a pointer to created boosted tree model of type CvBtClassifier.
|
||||
*
|
||||
* Remarks
|
||||
* The function performs trainParams->numiter training iterations.
|
||||
* If CV_TUNABLE flag is specified then created model supports tuning.
|
||||
* In this case additional training iterations may be performed by
|
||||
* tune function call.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
CvClassifier* cvCreateBtClassifier( CvMat* trainData,
|
||||
int flags,
|
||||
CvMat* trainClasses,
|
||||
CvMat* typeMask,
|
||||
CvMat* missedMeasurementsMask,
|
||||
CvMat* compIdx,
|
||||
CvMat* sampleIdx,
|
||||
CvMat* weights,
|
||||
CvClassifierTrainParams* trainParams );
|
||||
|
||||
/*
|
||||
* cvCreateBtClassifierFromFile
|
||||
*
|
||||
* The cvCreateBtClassifierFromFile function restores previously saved
|
||||
* boosted tree model from file.
|
||||
*
|
||||
* Parameters
|
||||
* filename
|
||||
* The name of the file with boosted tree model.
|
||||
*
|
||||
* Remarks
|
||||
* The restored model does not support tuning.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
CvClassifier* cvCreateBtClassifierFromFile( const char* filename );
|
||||
|
||||
/****************************************************************************************\
|
||||
* Utility functions *
|
||||
\****************************************************************************************/
|
||||
|
||||
/*
|
||||
* cvTrimWeights
|
||||
*
|
||||
* The cvTrimWeights function performs weight trimming.
|
||||
*
|
||||
* Parameters
|
||||
* weights
|
||||
* Weights vector.
|
||||
* idx
|
||||
* Indices vector of weights that should be considered.
|
||||
* If it is NULL then all weights are used.
|
||||
* factor
|
||||
* Weight trimming factor. Must be in [0, 1] range.
|
||||
*
|
||||
* Return Values
|
||||
* The return value is a vector of indices. If all samples should be used then
|
||||
* it is equal to idx. In other case the cvReleaseMat function should be called
|
||||
* to release it.
|
||||
*
|
||||
* Remarks
|
||||
*/
|
||||
CV_BOOST_API
|
||||
CvMat* cvTrimWeights( CvMat* weights, CvMat* idx, float factor );
|
||||
|
||||
/*
|
||||
* cvReadTrainData
|
||||
*
|
||||
* The cvReadTrainData function reads feature values and responses from file.
|
||||
*
|
||||
* Parameters
|
||||
* filename
|
||||
* The name of the file to be read.
|
||||
* flags
|
||||
* One of CV_ROW_SAMPLE or CV_COL_SAMPLE. Determines how feature values
|
||||
* will be stored.
|
||||
* trainData
|
||||
* A pointer to a pointer to created matrix with feature values.
|
||||
* cvReleaseMat function should be used to destroy created matrix.
|
||||
* trainClasses
|
||||
* A pointer to a pointer to created matrix with response values.
|
||||
* cvReleaseMat function should be used to destroy created matrix.
|
||||
*
|
||||
* Remarks
|
||||
* File format:
|
||||
* ============================================
|
||||
* m n
|
||||
* value_1_1 value_1_2 ... value_1_n response_1
|
||||
* value_2_1 value_2_2 ... value_2_n response_2
|
||||
* ...
|
||||
* value_m_1 value_m_2 ... value_m_n response_m
|
||||
* ============================================
|
||||
* m
|
||||
* Number of samples
|
||||
* n
|
||||
* Number of features in each sample
|
||||
* value_i_j
|
||||
* Value of j-th feature of i-th sample
|
||||
* response_i
|
||||
* Response value of i-th sample
|
||||
* For classification problems responses represent classes (0, 1, etc.)
|
||||
* All values and classes are integer or real numbers.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
void cvReadTrainData( const char* filename,
|
||||
int flags,
|
||||
CvMat** trainData,
|
||||
CvMat** trainClasses );
|
||||
|
||||
|
||||
/*
|
||||
* cvWriteTrainData
|
||||
*
|
||||
* The cvWriteTrainData function stores feature values and responses into file.
|
||||
*
|
||||
* Parameters
|
||||
* filename
|
||||
* The name of the file.
|
||||
* flags
|
||||
* One of CV_ROW_SAMPLE or CV_COL_SAMPLE. Determines how feature values
|
||||
* are stored.
|
||||
* trainData
|
||||
* Feature values matrix.
|
||||
* trainClasses
|
||||
* Response values vector.
|
||||
* sampleIdx
|
||||
* Vector of idicies of the samples that should be stored. If it is NULL
|
||||
* then all samples will be stored.
|
||||
*
|
||||
* Remarks
|
||||
* See the cvReadTrainData function for file format description.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
void cvWriteTrainData( const char* filename,
|
||||
int flags,
|
||||
CvMat* trainData,
|
||||
CvMat* trainClasses,
|
||||
CvMat* sampleIdx );
|
||||
|
||||
/*
|
||||
* cvRandShuffle
|
||||
*
|
||||
* The cvRandShuffle function perfroms random shuffling of given vector.
|
||||
*
|
||||
* Parameters
|
||||
* vector
|
||||
* Vector that should be shuffled.
|
||||
* Must have CV_8UC1, CV_16SC1, CV_32SC1 or CV_32FC1 type.
|
||||
*/
|
||||
CV_BOOST_API
|
||||
void cvRandShuffleVec( CvMat* vector );
|
||||
|
||||
#endif /* _CVCLASSIFIER_H_ */
|
||||
@@ -1,125 +0,0 @@
|
||||
/*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*/
|
||||
|
||||
#include "_cvcommon.h"
|
||||
|
||||
#include <cstring>
|
||||
#include <ctime>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/types.h>
|
||||
#ifdef _WIN32
|
||||
#include <direct.h>
|
||||
#endif /* _WIN32 */
|
||||
|
||||
int icvMkDir( const char* filename )
|
||||
{
|
||||
char path[PATH_MAX];
|
||||
char* p;
|
||||
int pos;
|
||||
|
||||
#ifdef _WIN32
|
||||
struct _stat st;
|
||||
#else /* _WIN32 */
|
||||
struct stat st;
|
||||
mode_t mode;
|
||||
|
||||
mode = 0755;
|
||||
#endif /* _WIN32 */
|
||||
|
||||
strcpy( path, filename );
|
||||
|
||||
p = path;
|
||||
for( ; ; )
|
||||
{
|
||||
pos = (int)strcspn( p, "/\\" );
|
||||
|
||||
if( pos == (int) strlen( p ) ) break;
|
||||
if( pos != 0 )
|
||||
{
|
||||
p[pos] = '\0';
|
||||
|
||||
#ifdef _WIN32
|
||||
if( p[pos-1] != ':' )
|
||||
{
|
||||
if( _stat( path, &st ) != 0 )
|
||||
{
|
||||
if( _mkdir( path ) != 0 ) return 0;
|
||||
}
|
||||
}
|
||||
#else /* _WIN32 */
|
||||
if( stat( path, &st ) != 0 )
|
||||
{
|
||||
if( mkdir( path, mode ) != 0 ) return 0;
|
||||
}
|
||||
#endif /* _WIN32 */
|
||||
}
|
||||
|
||||
p[pos] = '/';
|
||||
|
||||
p += pos + 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
#if 0
|
||||
/* debug functions */
|
||||
void icvSave( const CvArr* ptr, const char* filename, int line )
|
||||
{
|
||||
CvFileStorage* fs;
|
||||
char buf[PATH_MAX];
|
||||
const char* name;
|
||||
|
||||
name = strrchr( filename, '\\' );
|
||||
if( !name ) name = strrchr( filename, '/' );
|
||||
if( !name ) name = filename;
|
||||
else name++; /* skip '/' or '\\' */
|
||||
|
||||
sprintf( buf, "%s-%d-%d", name, line, time( NULL ) );
|
||||
fs = cvOpenFileStorage( buf, NULL, CV_STORAGE_WRITE_TEXT );
|
||||
if( !fs ) return;
|
||||
cvWrite( fs, "debug", ptr );
|
||||
cvReleaseFileStorage( &fs );
|
||||
}
|
||||
#endif // #if 0
|
||||
|
||||
/* End of file. */
|
||||
@@ -1,835 +0,0 @@
|
||||
/*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*/
|
||||
|
||||
/*
|
||||
* cvhaarclassifier.cpp
|
||||
*
|
||||
* haar classifiers (stump, CART, stage, cascade)
|
||||
*/
|
||||
|
||||
#include "_cvhaartraining.h"
|
||||
|
||||
|
||||
CvIntHaarClassifier* icvCreateCARTHaarClassifier( int count )
|
||||
{
|
||||
CvCARTHaarClassifier* cart;
|
||||
size_t datasize;
|
||||
|
||||
datasize = sizeof( *cart ) +
|
||||
( sizeof( int ) +
|
||||
sizeof( CvTHaarFeature ) + sizeof( CvFastHaarFeature ) +
|
||||
sizeof( float ) + sizeof( int ) + sizeof( int ) ) * count +
|
||||
sizeof( float ) * (count + 1);
|
||||
|
||||
cart = (CvCARTHaarClassifier*) cvAlloc( datasize );
|
||||
memset( cart, 0, datasize );
|
||||
|
||||
cart->feature = (CvTHaarFeature*) (cart + 1);
|
||||
cart->fastfeature = (CvFastHaarFeature*) (cart->feature + count);
|
||||
cart->threshold = (float*) (cart->fastfeature + count);
|
||||
cart->left = (int*) (cart->threshold + count);
|
||||
cart->right = (int*) (cart->left + count);
|
||||
cart->val = (float*) (cart->right + count);
|
||||
cart->compidx = (int*) (cart->val + count + 1 );
|
||||
cart->count = count;
|
||||
cart->eval = icvEvalCARTHaarClassifier;
|
||||
cart->save = icvSaveCARTHaarClassifier;
|
||||
cart->release = icvReleaseHaarClassifier;
|
||||
|
||||
return (CvIntHaarClassifier*) cart;
|
||||
}
|
||||
|
||||
|
||||
void icvReleaseHaarClassifier( CvIntHaarClassifier** classifier )
|
||||
{
|
||||
cvFree( classifier );
|
||||
*classifier = NULL;
|
||||
}
|
||||
|
||||
|
||||
void icvInitCARTHaarClassifier( CvCARTHaarClassifier* carthaar, CvCARTClassifier* cart,
|
||||
CvIntHaarFeatures* intHaarFeatures )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < cart->count; i++ )
|
||||
{
|
||||
carthaar->feature[i] = intHaarFeatures->feature[cart->compidx[i]];
|
||||
carthaar->fastfeature[i] = intHaarFeatures->fastfeature[cart->compidx[i]];
|
||||
carthaar->threshold[i] = cart->threshold[i];
|
||||
carthaar->left[i] = cart->left[i];
|
||||
carthaar->right[i] = cart->right[i];
|
||||
carthaar->val[i] = cart->val[i];
|
||||
carthaar->compidx[i] = cart->compidx[i];
|
||||
}
|
||||
carthaar->count = cart->count;
|
||||
carthaar->val[cart->count] = cart->val[cart->count];
|
||||
}
|
||||
|
||||
|
||||
float icvEvalCARTHaarClassifier( CvIntHaarClassifier* classifier,
|
||||
sum_type* sum, sum_type* tilted, float normfactor )
|
||||
{
|
||||
int idx = 0;
|
||||
|
||||
do
|
||||
{
|
||||
if( cvEvalFastHaarFeature(
|
||||
((CvCARTHaarClassifier*) classifier)->fastfeature + idx, sum, tilted )
|
||||
< (((CvCARTHaarClassifier*) classifier)->threshold[idx] * normfactor) )
|
||||
{
|
||||
idx = ((CvCARTHaarClassifier*) classifier)->left[idx];
|
||||
}
|
||||
else
|
||||
{
|
||||
idx = ((CvCARTHaarClassifier*) classifier)->right[idx];
|
||||
}
|
||||
} while( idx > 0 );
|
||||
|
||||
return ((CvCARTHaarClassifier*) classifier)->val[-idx];
|
||||
}
|
||||
|
||||
|
||||
CvIntHaarClassifier* icvCreateStageHaarClassifier( int count, float threshold )
|
||||
{
|
||||
CvStageHaarClassifier* stage;
|
||||
size_t datasize;
|
||||
|
||||
datasize = sizeof( *stage ) + sizeof( CvIntHaarClassifier* ) * count;
|
||||
stage = (CvStageHaarClassifier*) cvAlloc( datasize );
|
||||
memset( stage, 0, datasize );
|
||||
|
||||
stage->count = count;
|
||||
stage->threshold = threshold;
|
||||
stage->classifier = (CvIntHaarClassifier**) (stage + 1);
|
||||
|
||||
stage->eval = icvEvalStageHaarClassifier;
|
||||
stage->save = icvSaveStageHaarClassifier;
|
||||
stage->release = icvReleaseStageHaarClassifier;
|
||||
|
||||
return (CvIntHaarClassifier*) stage;
|
||||
}
|
||||
|
||||
|
||||
void icvReleaseStageHaarClassifier( CvIntHaarClassifier** classifier )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < ((CvStageHaarClassifier*) *classifier)->count; i++ )
|
||||
{
|
||||
if( ((CvStageHaarClassifier*) *classifier)->classifier[i] != NULL )
|
||||
{
|
||||
((CvStageHaarClassifier*) *classifier)->classifier[i]->release(
|
||||
&(((CvStageHaarClassifier*) *classifier)->classifier[i]) );
|
||||
}
|
||||
}
|
||||
|
||||
cvFree( classifier );
|
||||
*classifier = NULL;
|
||||
}
|
||||
|
||||
|
||||
float icvEvalStageHaarClassifier( CvIntHaarClassifier* classifier,
|
||||
sum_type* sum, sum_type* tilted, float normfactor )
|
||||
{
|
||||
int i;
|
||||
float stage_sum;
|
||||
|
||||
stage_sum = 0.0F;
|
||||
for( i = 0; i < ((CvStageHaarClassifier*) classifier)->count; i++ )
|
||||
{
|
||||
stage_sum +=
|
||||
((CvStageHaarClassifier*) classifier)->classifier[i]->eval(
|
||||
((CvStageHaarClassifier*) classifier)->classifier[i],
|
||||
sum, tilted, normfactor );
|
||||
}
|
||||
|
||||
return stage_sum;
|
||||
}
|
||||
|
||||
|
||||
CvIntHaarClassifier* icvCreateCascadeHaarClassifier( int count )
|
||||
{
|
||||
CvCascadeHaarClassifier* ptr;
|
||||
size_t datasize;
|
||||
|
||||
datasize = sizeof( *ptr ) + sizeof( CvIntHaarClassifier* ) * count;
|
||||
ptr = (CvCascadeHaarClassifier*) cvAlloc( datasize );
|
||||
memset( ptr, 0, datasize );
|
||||
|
||||
ptr->count = count;
|
||||
ptr->classifier = (CvIntHaarClassifier**) (ptr + 1);
|
||||
|
||||
ptr->eval = icvEvalCascadeHaarClassifier;
|
||||
ptr->save = NULL;
|
||||
ptr->release = icvReleaseCascadeHaarClassifier;
|
||||
|
||||
return (CvIntHaarClassifier*) ptr;
|
||||
}
|
||||
|
||||
|
||||
void icvReleaseCascadeHaarClassifier( CvIntHaarClassifier** classifier )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < ((CvCascadeHaarClassifier*) *classifier)->count; i++ )
|
||||
{
|
||||
if( ((CvCascadeHaarClassifier*) *classifier)->classifier[i] != NULL )
|
||||
{
|
||||
((CvCascadeHaarClassifier*) *classifier)->classifier[i]->release(
|
||||
&(((CvCascadeHaarClassifier*) *classifier)->classifier[i]) );
|
||||
}
|
||||
}
|
||||
|
||||
cvFree( classifier );
|
||||
*classifier = NULL;
|
||||
}
|
||||
|
||||
|
||||
float icvEvalCascadeHaarClassifier( CvIntHaarClassifier* classifier,
|
||||
sum_type* sum, sum_type* tilted, float normfactor )
|
||||
{
|
||||
int i;
|
||||
|
||||
for( i = 0; i < ((CvCascadeHaarClassifier*) classifier)->count; i++ )
|
||||
{
|
||||
if( ((CvCascadeHaarClassifier*) classifier)->classifier[i]->eval(
|
||||
((CvCascadeHaarClassifier*) classifier)->classifier[i],
|
||||
sum, tilted, normfactor )
|
||||
< ( ((CvStageHaarClassifier*)
|
||||
((CvCascadeHaarClassifier*) classifier)->classifier[i])->threshold
|
||||
- CV_THRESHOLD_EPS) )
|
||||
{
|
||||
return 0.0;
|
||||
}
|
||||
}
|
||||
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
|
||||
void icvSaveHaarFeature( CvTHaarFeature* feature, FILE* file )
|
||||
{
|
||||
fprintf( file, "%d\n", ( ( feature->rect[2].weight == 0.0F ) ? 2 : 3) );
|
||||
fprintf( file, "%d %d %d %d %d %d\n",
|
||||
feature->rect[0].r.x,
|
||||
feature->rect[0].r.y,
|
||||
feature->rect[0].r.width,
|
||||
feature->rect[0].r.height,
|
||||
0,
|
||||
(int) (feature->rect[0].weight) );
|
||||
fprintf( file, "%d %d %d %d %d %d\n",
|
||||
feature->rect[1].r.x,
|
||||
feature->rect[1].r.y,
|
||||
feature->rect[1].r.width,
|
||||
feature->rect[1].r.height,
|
||||
0,
|
||||
(int) (feature->rect[1].weight) );
|
||||
if( feature->rect[2].weight != 0.0F )
|
||||
{
|
||||
fprintf( file, "%d %d %d %d %d %d\n",
|
||||
feature->rect[2].r.x,
|
||||
feature->rect[2].r.y,
|
||||
feature->rect[2].r.width,
|
||||
feature->rect[2].r.height,
|
||||
0,
|
||||
(int) (feature->rect[2].weight) );
|
||||
}
|
||||
fprintf( file, "%s\n", &(feature->desc[0]) );
|
||||
}
|
||||
|
||||
|
||||
void icvLoadHaarFeature( CvTHaarFeature* feature, FILE* file )
|
||||
{
|
||||
int nrect;
|
||||
int j;
|
||||
int tmp;
|
||||
int weight;
|
||||
|
||||
nrect = 0;
|
||||
int values_read = fscanf( file, "%d", &nrect );
|
||||
CV_Assert(values_read == 1);
|
||||
|
||||
assert( nrect <= CV_HAAR_FEATURE_MAX );
|
||||
|
||||
for( j = 0; j < nrect; j++ )
|
||||
{
|
||||
values_read = fscanf( file, "%d %d %d %d %d %d",
|
||||
&(feature->rect[j].r.x),
|
||||
&(feature->rect[j].r.y),
|
||||
&(feature->rect[j].r.width),
|
||||
&(feature->rect[j].r.height),
|
||||
&tmp, &weight );
|
||||
CV_Assert(values_read == 6);
|
||||
feature->rect[j].weight = (float) weight;
|
||||
}
|
||||
for( j = nrect; j < CV_HAAR_FEATURE_MAX; j++ )
|
||||
{
|
||||
feature->rect[j].r.x = 0;
|
||||
feature->rect[j].r.y = 0;
|
||||
feature->rect[j].r.width = 0;
|
||||
feature->rect[j].r.height = 0;
|
||||
feature->rect[j].weight = 0.0f;
|
||||
}
|
||||
values_read = fscanf( file, "%s", &(feature->desc[0]) );
|
||||
CV_Assert(values_read == 1);
|
||||
feature->tilted = ( feature->desc[0] == 't' );
|
||||
}
|
||||
|
||||
|
||||
void icvSaveCARTHaarClassifier( CvIntHaarClassifier* classifier, FILE* file )
|
||||
{
|
||||
int i;
|
||||
int count;
|
||||
|
||||
count = ((CvCARTHaarClassifier*) classifier)->count;
|
||||
fprintf( file, "%d\n", count );
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
icvSaveHaarFeature( &(((CvCARTHaarClassifier*) classifier)->feature[i]), file );
|
||||
fprintf( file, "%e %d %d\n",
|
||||
((CvCARTHaarClassifier*) classifier)->threshold[i],
|
||||
((CvCARTHaarClassifier*) classifier)->left[i],
|
||||
((CvCARTHaarClassifier*) classifier)->right[i] );
|
||||
}
|
||||
for( i = 0; i <= count; i++ )
|
||||
{
|
||||
fprintf( file, "%e ", ((CvCARTHaarClassifier*) classifier)->val[i] );
|
||||
}
|
||||
fprintf( file, "\n" );
|
||||
}
|
||||
|
||||
|
||||
CvIntHaarClassifier* icvLoadCARTHaarClassifier( FILE* file, int step )
|
||||
{
|
||||
CvCARTHaarClassifier* ptr;
|
||||
int i;
|
||||
int count;
|
||||
|
||||
ptr = NULL;
|
||||
int values_read = fscanf( file, "%d", &count );
|
||||
CV_Assert(values_read == 1);
|
||||
|
||||
if( count > 0 )
|
||||
{
|
||||
ptr = (CvCARTHaarClassifier*) icvCreateCARTHaarClassifier( count );
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
icvLoadHaarFeature( &(ptr->feature[i]), file );
|
||||
values_read = fscanf( file, "%f %d %d", &(ptr->threshold[i]), &(ptr->left[i]),
|
||||
&(ptr->right[i]) );
|
||||
CV_Assert(values_read == 3);
|
||||
}
|
||||
for( i = 0; i <= count; i++ )
|
||||
{
|
||||
values_read = fscanf( file, "%f", &(ptr->val[i]) );
|
||||
CV_Assert(values_read == 1);
|
||||
}
|
||||
icvConvertToFastHaarFeature( ptr->feature, ptr->fastfeature, ptr->count, step );
|
||||
}
|
||||
|
||||
return (CvIntHaarClassifier*) ptr;
|
||||
}
|
||||
|
||||
|
||||
void icvSaveStageHaarClassifier( CvIntHaarClassifier* classifier, FILE* file )
|
||||
{
|
||||
int count;
|
||||
int i;
|
||||
float threshold;
|
||||
|
||||
count = ((CvStageHaarClassifier*) classifier)->count;
|
||||
fprintf( file, "%d\n", count );
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
((CvStageHaarClassifier*) classifier)->classifier[i]->save(
|
||||
((CvStageHaarClassifier*) classifier)->classifier[i], file );
|
||||
}
|
||||
|
||||
threshold = ((CvStageHaarClassifier*) classifier)->threshold;
|
||||
|
||||
/* to be compatible with the previous implementation */
|
||||
/* threshold = 2.0F * ((CvStageHaarClassifier*) classifier)->threshold - count; */
|
||||
|
||||
fprintf( file, "%e\n", threshold );
|
||||
}
|
||||
|
||||
|
||||
|
||||
static CvIntHaarClassifier* icvLoadCARTStageHaarClassifierF( FILE* file, int step )
|
||||
{
|
||||
CvStageHaarClassifier* ptr = NULL;
|
||||
|
||||
//CV_FUNCNAME( "icvLoadCARTStageHaarClassifierF" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
if( file != NULL )
|
||||
{
|
||||
int count;
|
||||
int i;
|
||||
float threshold;
|
||||
|
||||
count = 0;
|
||||
int values_read = fscanf( file, "%d", &count );
|
||||
CV_Assert(values_read == 1);
|
||||
if( count > 0 )
|
||||
{
|
||||
ptr = (CvStageHaarClassifier*) icvCreateStageHaarClassifier( count, 0.0F );
|
||||
for( i = 0; i < count; i++ )
|
||||
{
|
||||
ptr->classifier[i] = icvLoadCARTHaarClassifier( file, step );
|
||||
}
|
||||
|
||||
values_read = fscanf( file, "%f", &threshold );
|
||||
CV_Assert(values_read == 1);
|
||||
|
||||
ptr->threshold = threshold;
|
||||
/* to be compatible with the previous implementation */
|
||||
/* ptr->threshold = 0.5F * (threshold + count); */
|
||||
}
|
||||
if( feof( file ) )
|
||||
{
|
||||
ptr->release( (CvIntHaarClassifier**) &ptr );
|
||||
ptr = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
__END__;
|
||||
|
||||
return (CvIntHaarClassifier*) ptr;
|
||||
}
|
||||
|
||||
|
||||
CvIntHaarClassifier* icvLoadCARTStageHaarClassifier( const char* filename, int step )
|
||||
{
|
||||
CvIntHaarClassifier* ptr = NULL;
|
||||
|
||||
CV_FUNCNAME( "icvLoadCARTStageHaarClassifier" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
FILE* file;
|
||||
|
||||
file = fopen( filename, "r" );
|
||||
if( file )
|
||||
{
|
||||
CV_CALL( ptr = icvLoadCARTStageHaarClassifierF( file, step ) );
|
||||
fclose( file );
|
||||
}
|
||||
|
||||
__END__;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* tree cascade classifier */
|
||||
|
||||
/* evaluates a tree cascade classifier */
|
||||
|
||||
float icvEvalTreeCascadeClassifier( CvIntHaarClassifier* classifier,
|
||||
sum_type* sum, sum_type* tilted, float normfactor )
|
||||
{
|
||||
CvTreeCascadeNode* ptr;
|
||||
|
||||
ptr = ((CvTreeCascadeClassifier*) classifier)->root;
|
||||
|
||||
while( ptr )
|
||||
{
|
||||
if( ptr->stage->eval( (CvIntHaarClassifier*) ptr->stage,
|
||||
sum, tilted, normfactor )
|
||||
>= ptr->stage->threshold - CV_THRESHOLD_EPS )
|
||||
{
|
||||
ptr = ptr->child;
|
||||
}
|
||||
else
|
||||
{
|
||||
while( ptr && ptr->next == NULL ) ptr = ptr->parent;
|
||||
if( ptr == NULL ) return 0.0F;
|
||||
ptr = ptr->next;
|
||||
}
|
||||
}
|
||||
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
/* sets path int the tree form the root to the leaf node */
|
||||
|
||||
void icvSetLeafNode( CvTreeCascadeClassifier* tcc, CvTreeCascadeNode* leaf )
|
||||
{
|
||||
CV_FUNCNAME( "icvSetLeafNode" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
CvTreeCascadeNode* ptr;
|
||||
|
||||
ptr = NULL;
|
||||
while( leaf )
|
||||
{
|
||||
leaf->child_eval = ptr;
|
||||
ptr = leaf;
|
||||
leaf = leaf->parent;
|
||||
}
|
||||
|
||||
leaf = tcc->root;
|
||||
while( leaf && leaf != ptr ) leaf = leaf->next;
|
||||
if( leaf != ptr )
|
||||
CV_ERROR( CV_StsError, "Invalid tcc or leaf node." );
|
||||
|
||||
tcc->root_eval = ptr;
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
/* evaluates a tree cascade classifier. used in filtering */
|
||||
|
||||
float icvEvalTreeCascadeClassifierFilter( CvIntHaarClassifier* classifier, sum_type* sum,
|
||||
sum_type* tilted, float normfactor )
|
||||
{
|
||||
CvTreeCascadeNode* ptr;
|
||||
//CvTreeCascadeClassifier* tree;
|
||||
|
||||
//tree = (CvTreeCascadeClassifier*) classifier;
|
||||
|
||||
|
||||
|
||||
ptr = ((CvTreeCascadeClassifier*) classifier)->root_eval;
|
||||
while( ptr )
|
||||
{
|
||||
if( ptr->stage->eval( (CvIntHaarClassifier*) ptr->stage,
|
||||
sum, tilted, normfactor )
|
||||
< ptr->stage->threshold - CV_THRESHOLD_EPS )
|
||||
{
|
||||
return 0.0F;
|
||||
}
|
||||
ptr = ptr->child_eval;
|
||||
}
|
||||
|
||||
return 1.0F;
|
||||
}
|
||||
|
||||
/* creates tree cascade node */
|
||||
|
||||
CvTreeCascadeNode* icvCreateTreeCascadeNode()
|
||||
{
|
||||
CvTreeCascadeNode* ptr = NULL;
|
||||
|
||||
CV_FUNCNAME( "icvCreateTreeCascadeNode" );
|
||||
|
||||
__BEGIN__;
|
||||
size_t data_size;
|
||||
|
||||
data_size = sizeof( *ptr );
|
||||
CV_CALL( ptr = (CvTreeCascadeNode*) cvAlloc( data_size ) );
|
||||
memset( ptr, 0, data_size );
|
||||
|
||||
__END__;
|
||||
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* releases all tree cascade nodes accessible via links */
|
||||
|
||||
void icvReleaseTreeCascadeNodes( CvTreeCascadeNode** node )
|
||||
{
|
||||
//CV_FUNCNAME( "icvReleaseTreeCascadeNodes" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
if( node && *node )
|
||||
{
|
||||
CvTreeCascadeNode* ptr;
|
||||
CvTreeCascadeNode* ptr_;
|
||||
|
||||
ptr = *node;
|
||||
|
||||
while( ptr )
|
||||
{
|
||||
while( ptr->child ) ptr = ptr->child;
|
||||
|
||||
if( ptr->stage ) ptr->stage->release( (CvIntHaarClassifier**) &ptr->stage );
|
||||
ptr_ = ptr;
|
||||
|
||||
while( ptr && ptr->next == NULL ) ptr = ptr->parent;
|
||||
if( ptr ) ptr = ptr->next;
|
||||
|
||||
cvFree( &ptr_ );
|
||||
}
|
||||
}
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
|
||||
/* releases tree cascade classifier */
|
||||
|
||||
void icvReleaseTreeCascadeClassifier( CvIntHaarClassifier** classifier )
|
||||
{
|
||||
if( classifier && *classifier )
|
||||
{
|
||||
icvReleaseTreeCascadeNodes( &((CvTreeCascadeClassifier*) *classifier)->root );
|
||||
cvFree( classifier );
|
||||
*classifier = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void icvPrintTreeCascade( CvTreeCascadeNode* root )
|
||||
{
|
||||
//CV_FUNCNAME( "icvPrintTreeCascade" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
CvTreeCascadeNode* node;
|
||||
CvTreeCascadeNode* n;
|
||||
char buf0[256];
|
||||
char buf[256];
|
||||
int level;
|
||||
int i;
|
||||
int max_level;
|
||||
|
||||
node = root;
|
||||
level = max_level = 0;
|
||||
while( node )
|
||||
{
|
||||
while( node->child ) { node = node->child; level++; }
|
||||
if( level > max_level ) { max_level = level; }
|
||||
while( node && !node->next ) { node = node->parent; level--; }
|
||||
if( node ) node = node->next;
|
||||
}
|
||||
|
||||
printf( "\nTree Classifier\n" );
|
||||
printf( "Stage\n" );
|
||||
for( i = 0; i <= max_level; i++ ) printf( "+---" );
|
||||
printf( "+\n" );
|
||||
for( i = 0; i <= max_level; i++ ) printf( "|%3d", i );
|
||||
printf( "|\n" );
|
||||
for( i = 0; i <= max_level; i++ ) printf( "+---" );
|
||||
printf( "+\n\n" );
|
||||
|
||||
node = root;
|
||||
|
||||
buf[0] = 0;
|
||||
while( node )
|
||||
{
|
||||
sprintf( buf + strlen( buf ), "%3d", node->idx );
|
||||
while( node->child )
|
||||
{
|
||||
node = node->child;
|
||||
sprintf( buf + strlen( buf ),
|
||||
((node->idx < 10) ? "---%d" : ((node->idx < 100) ? "--%d" : "-%d")),
|
||||
node->idx );
|
||||
}
|
||||
printf( " %s\n", buf );
|
||||
|
||||
while( node && !node->next ) { node = node->parent; }
|
||||
if( node )
|
||||
{
|
||||
node = node->next;
|
||||
|
||||
n = node->parent;
|
||||
buf[0] = 0;
|
||||
while( n )
|
||||
{
|
||||
if( n->next )
|
||||
sprintf( buf0, " | %s", buf );
|
||||
else
|
||||
sprintf( buf0, " %s", buf );
|
||||
strcpy( buf, buf0 );
|
||||
n = n->parent;
|
||||
}
|
||||
printf( " %s |\n", buf );
|
||||
}
|
||||
}
|
||||
printf( "\n" );
|
||||
fflush( stdout );
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CvIntHaarClassifier* icvLoadTreeCascadeClassifier( const char* filename, int step,
|
||||
int* splits )
|
||||
{
|
||||
CvTreeCascadeClassifier* ptr = NULL;
|
||||
CvTreeCascadeNode** nodes = NULL;
|
||||
|
||||
CV_FUNCNAME( "icvLoadTreeCascadeClassifier" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
size_t data_size;
|
||||
CvStageHaarClassifier* stage;
|
||||
char stage_name[PATH_MAX];
|
||||
char* suffix;
|
||||
int i, num;
|
||||
FILE* f;
|
||||
int result, parent=0, next=0;
|
||||
int stub;
|
||||
|
||||
if( !splits ) splits = &stub;
|
||||
|
||||
*splits = 0;
|
||||
|
||||
data_size = sizeof( *ptr );
|
||||
|
||||
CV_CALL( ptr = (CvTreeCascadeClassifier*) cvAlloc( data_size ) );
|
||||
memset( ptr, 0, data_size );
|
||||
|
||||
ptr->eval = icvEvalTreeCascadeClassifier;
|
||||
ptr->release = icvReleaseTreeCascadeClassifier;
|
||||
|
||||
sprintf( stage_name, "%s/", filename );
|
||||
suffix = stage_name + strlen( stage_name );
|
||||
|
||||
for( i = 0; ; i++ )
|
||||
{
|
||||
sprintf( suffix, "%d/%s", i, CV_STAGE_CART_FILE_NAME );
|
||||
f = fopen( stage_name, "r" );
|
||||
if( !f ) break;
|
||||
fclose( f );
|
||||
}
|
||||
num = i;
|
||||
|
||||
if( num < 1 ) EXIT;
|
||||
|
||||
data_size = sizeof( *nodes ) * num;
|
||||
CV_CALL( nodes = (CvTreeCascadeNode**) cvAlloc( data_size ) );
|
||||
|
||||
for( i = 0; i < num; i++ )
|
||||
{
|
||||
sprintf( suffix, "%d/%s", i, CV_STAGE_CART_FILE_NAME );
|
||||
f = fopen( stage_name, "r" );
|
||||
CV_CALL( stage = (CvStageHaarClassifier*)
|
||||
icvLoadCARTStageHaarClassifierF( f, step ) );
|
||||
|
||||
result = ( f && stage ) ? fscanf( f, "%d%d", &parent, &next ) : 0;
|
||||
if( f ) fclose( f );
|
||||
|
||||
if( result != 2 )
|
||||
{
|
||||
num = i;
|
||||
break;
|
||||
}
|
||||
|
||||
printf( "Stage %d loaded\n", i );
|
||||
|
||||
if( parent >= i || (next != -1 && next != i + 1) )
|
||||
CV_ERROR( CV_StsError, "Invalid tree links" );
|
||||
|
||||
CV_CALL( nodes[i] = icvCreateTreeCascadeNode() );
|
||||
nodes[i]->stage = stage;
|
||||
nodes[i]->idx = i;
|
||||
nodes[i]->parent = (parent != -1 ) ? nodes[parent] : NULL;
|
||||
nodes[i]->next = ( next != -1 ) ? nodes[i] : NULL;
|
||||
nodes[i]->child = NULL;
|
||||
}
|
||||
for( i = 0; i < num; i++ )
|
||||
{
|
||||
if( nodes[i]->next )
|
||||
{
|
||||
(*splits)++;
|
||||
nodes[i]->next = nodes[i+1];
|
||||
}
|
||||
if( nodes[i]->parent && nodes[i]->parent->child == NULL )
|
||||
{
|
||||
nodes[i]->parent->child = nodes[i];
|
||||
}
|
||||
}
|
||||
ptr->root = nodes[0];
|
||||
ptr->next_idx = num;
|
||||
|
||||
__END__;
|
||||
|
||||
cvFree( &nodes );
|
||||
|
||||
return (CvIntHaarClassifier*) ptr;
|
||||
}
|
||||
|
||||
|
||||
CvTreeCascadeNode* icvFindDeepestLeaves( CvTreeCascadeClassifier* tcc )
|
||||
{
|
||||
CvTreeCascadeNode* leaves;
|
||||
|
||||
//CV_FUNCNAME( "icvFindDeepestLeaves" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
int level, cur_level;
|
||||
CvTreeCascadeNode* ptr;
|
||||
CvTreeCascadeNode* last;
|
||||
|
||||
leaves = last = NULL;
|
||||
|
||||
ptr = tcc->root;
|
||||
level = -1;
|
||||
cur_level = 0;
|
||||
|
||||
/* find leaves with maximal level */
|
||||
while( ptr )
|
||||
{
|
||||
if( ptr->child ) { ptr = ptr->child; cur_level++; }
|
||||
else
|
||||
{
|
||||
if( cur_level == level )
|
||||
{
|
||||
last->next_same_level = ptr;
|
||||
ptr->next_same_level = NULL;
|
||||
last = ptr;
|
||||
}
|
||||
if( cur_level > level )
|
||||
{
|
||||
level = cur_level;
|
||||
leaves = last = ptr;
|
||||
ptr->next_same_level = NULL;
|
||||
}
|
||||
while( ptr && ptr->next == NULL ) { ptr = ptr->parent; cur_level--; }
|
||||
if( ptr ) ptr = ptr->next;
|
||||
}
|
||||
}
|
||||
|
||||
__END__;
|
||||
|
||||
return leaves;
|
||||
}
|
||||
|
||||
/* End of file. */
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,192 +0,0 @@
|
||||
/*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
|
||||
*
|
||||
* haar training functions
|
||||
*/
|
||||
|
||||
#ifndef _CVHAARTRAINING_H_
|
||||
#define _CVHAARTRAINING_H_
|
||||
|
||||
/*
|
||||
* cvCreateTrainingSamples
|
||||
*
|
||||
* Create training samples applying random distortions to sample image and
|
||||
* store them in .vec file
|
||||
*
|
||||
* filename - .vec file name
|
||||
* imgfilename - sample image file name
|
||||
* bgcolor - background color for sample image
|
||||
* bgthreshold - background color threshold. Pixels those colors are in range
|
||||
* [bgcolor-bgthreshold, bgcolor+bgthreshold] are considered as transparent
|
||||
* bgfilename - background description file name. If not NULL samples
|
||||
* will be put on arbitrary background
|
||||
* count - desired number of samples
|
||||
* invert - if not 0 sample foreground pixels will be inverted
|
||||
* if invert == CV_RANDOM_INVERT then samples will be inverted randomly
|
||||
* maxintensitydev - desired max intensity deviation of foreground samples pixels
|
||||
* maxxangle - max rotation angles
|
||||
* maxyangle
|
||||
* maxzangle
|
||||
* showsamples - if not 0 samples will be shown
|
||||
* winwidth - desired samples width
|
||||
* winheight - desired samples height
|
||||
*/
|
||||
#define CV_RANDOM_INVERT 0x7FFFFFFF
|
||||
|
||||
void cvCreateTrainingSamples( const char* filename,
|
||||
const char* imgfilename, int bgcolor, int bgthreshold,
|
||||
const char* bgfilename, int count,
|
||||
int invert = 0, int maxintensitydev = 40,
|
||||
double maxxangle = 1.1,
|
||||
double maxyangle = 1.1,
|
||||
double maxzangle = 0.5,
|
||||
int showsamples = 0,
|
||||
int winwidth = 24, int winheight = 24 );
|
||||
|
||||
void cvCreateTestSamples( const char* infoname,
|
||||
const char* imgfilename, int bgcolor, int bgthreshold,
|
||||
const char* bgfilename, int count,
|
||||
int invert, int maxintensitydev,
|
||||
double maxxangle, double maxyangle, double maxzangle,
|
||||
int showsamples,
|
||||
int winwidth, int winheight );
|
||||
|
||||
/*
|
||||
* cvCreateTrainingSamplesFromInfo
|
||||
*
|
||||
* Create training samples from a set of marked up images and store them into .vec file
|
||||
* infoname - file in which marked up image descriptions are stored
|
||||
* num - desired number of samples
|
||||
* showsamples - if not 0 samples will be shown
|
||||
* winwidth - sample width
|
||||
* winheight - sample height
|
||||
*
|
||||
* Return number of successfully created samples
|
||||
*/
|
||||
int cvCreateTrainingSamplesFromInfo( const char* infoname, const char* vecfilename,
|
||||
int num,
|
||||
int showsamples,
|
||||
int winwidth, int winheight );
|
||||
|
||||
/*
|
||||
* cvShowVecSamples
|
||||
*
|
||||
* Shows samples stored in .vec file
|
||||
*
|
||||
* filename
|
||||
* .vec file name
|
||||
* winwidth
|
||||
* sample width
|
||||
* winheight
|
||||
* sample height
|
||||
* scale
|
||||
* the scale each sample is adjusted to
|
||||
*/
|
||||
void cvShowVecSamples( const char* filename, int winwidth, int winheight, double scale );
|
||||
|
||||
|
||||
/*
|
||||
* cvCreateCascadeClassifier
|
||||
*
|
||||
* Create cascade classifier
|
||||
* dirname - directory name in which cascade classifier will be created.
|
||||
* It must exist and contain subdirectories 0, 1, 2, ... (nstages-1).
|
||||
* vecfilename - name of .vec file with object's images
|
||||
* bgfilename - name of background description file
|
||||
* bg_vecfile - true if bgfilename represents a vec file with discrete negatives
|
||||
* npos - number of positive samples used in training of each stage
|
||||
* nneg - number of negative samples used in training of each stage
|
||||
* nstages - number of stages
|
||||
* numprecalculated - number of features being precalculated. Each precalculated feature
|
||||
* requires (number_of_samples*(sizeof( float ) + sizeof( short ))) bytes of memory
|
||||
* numsplits - number of binary splits in each weak classifier
|
||||
* 1 - stumps, 2 and more - trees.
|
||||
* minhitrate - desired min hit rate of each stage
|
||||
* maxfalsealarm - desired max false alarm of each stage
|
||||
* weightfraction - weight trimming parameter
|
||||
* mode - 0 - BASIC = Viola
|
||||
* 1 - CORE = All upright
|
||||
* 2 - ALL = All features
|
||||
* symmetric - if not 0 vertical symmetry is assumed
|
||||
* equalweights - if not 0 initial weights of all samples will be equal
|
||||
* winwidth - sample width
|
||||
* winheight - sample height
|
||||
* boosttype - type of applied boosting algorithm
|
||||
* 0 - Discrete AdaBoost
|
||||
* 1 - Real AdaBoost
|
||||
* 2 - LogitBoost
|
||||
* 3 - Gentle AdaBoost
|
||||
* stumperror - type of used error if Discrete AdaBoost algorithm is applied
|
||||
* 0 - misclassification error
|
||||
* 1 - gini error
|
||||
* 2 - entropy error
|
||||
*/
|
||||
void cvCreateCascadeClassifier( const char* dirname,
|
||||
const char* vecfilename,
|
||||
const char* bgfilename,
|
||||
int npos, int nneg, int nstages,
|
||||
int numprecalculated,
|
||||
int numsplits,
|
||||
float minhitrate = 0.995F, float maxfalsealarm = 0.5F,
|
||||
float weightfraction = 0.95F,
|
||||
int mode = 0, int symmetric = 1,
|
||||
int equalweights = 1,
|
||||
int winwidth = 24, int winheight = 24,
|
||||
int boosttype = 3, int stumperror = 0 );
|
||||
|
||||
void cvCreateTreeCascadeClassifier( const char* dirname,
|
||||
const char* vecfilename,
|
||||
const char* bgfilename,
|
||||
int npos, int nneg, int nstages,
|
||||
int numprecalculated,
|
||||
int numsplits,
|
||||
float minhitrate, float maxfalsealarm,
|
||||
float weightfraction,
|
||||
int mode, int symmetric,
|
||||
int equalweights,
|
||||
int winwidth, int winheight,
|
||||
int boosttype, int stumperror,
|
||||
int maxtreesplits, int minpos, bool bg_vecfile = false );
|
||||
|
||||
#endif /* _CVHAARTRAINING_H_ */
|
||||
@@ -1,953 +0,0 @@
|
||||
/*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*/
|
||||
|
||||
/*
|
||||
* cvsamples.cpp
|
||||
*
|
||||
* support functions for training and test samples creation.
|
||||
*/
|
||||
|
||||
#include "cvhaartraining.h"
|
||||
#include "_cvhaartraining.h"
|
||||
|
||||
/* if ipl.h file is included then iplWarpPerspectiveQ function
|
||||
is used for image transformation during samples creation;
|
||||
otherwise internal cvWarpPerspective function is used */
|
||||
|
||||
//#include <ipl.h>
|
||||
|
||||
#include "cv.h"
|
||||
#include "highgui.h"
|
||||
|
||||
/* Calculates coefficients of perspective transformation
|
||||
* which maps <quad> into rectangle ((0,0), (w,0), (w,h), (h,0)):
|
||||
*
|
||||
* c00*xi + c01*yi + c02
|
||||
* ui = ---------------------
|
||||
* c20*xi + c21*yi + c22
|
||||
*
|
||||
* c10*xi + c11*yi + c12
|
||||
* vi = ---------------------
|
||||
* c20*xi + c21*yi + c22
|
||||
*
|
||||
* Coefficients are calculated by solving linear system:
|
||||
* / x0 y0 1 0 0 0 -x0*u0 -y0*u0 \ /c00\ /u0\
|
||||
* | x1 y1 1 0 0 0 -x1*u1 -y1*u1 | |c01| |u1|
|
||||
* | x2 y2 1 0 0 0 -x2*u2 -y2*u2 | |c02| |u2|
|
||||
* | x3 y3 1 0 0 0 -x3*u3 -y3*u3 |.|c10|=|u3|,
|
||||
* | 0 0 0 x0 y0 1 -x0*v0 -y0*v0 | |c11| |v0|
|
||||
* | 0 0 0 x1 y1 1 -x1*v1 -y1*v1 | |c12| |v1|
|
||||
* | 0 0 0 x2 y2 1 -x2*v2 -y2*v2 | |c20| |v2|
|
||||
* \ 0 0 0 x3 y3 1 -x3*v3 -y3*v3 / \c21/ \v3/
|
||||
*
|
||||
* where:
|
||||
* (xi, yi) = (quad[i][0], quad[i][1])
|
||||
* cij - coeffs[i][j], coeffs[2][2] = 1
|
||||
* (ui, vi) - rectangle vertices
|
||||
*/
|
||||
static void cvGetPerspectiveTransform( CvSize src_size, double quad[4][2],
|
||||
double coeffs[3][3] )
|
||||
{
|
||||
//CV_FUNCNAME( "cvWarpPerspective" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
double a[8][8];
|
||||
double b[8];
|
||||
|
||||
CvMat A = cvMat( 8, 8, CV_64FC1, a );
|
||||
CvMat B = cvMat( 8, 1, CV_64FC1, b );
|
||||
CvMat X = cvMat( 8, 1, CV_64FC1, coeffs );
|
||||
|
||||
int i;
|
||||
for( i = 0; i < 4; ++i )
|
||||
{
|
||||
a[i][0] = quad[i][0]; a[i][1] = quad[i][1]; a[i][2] = 1;
|
||||
a[i][3] = a[i][4] = a[i][5] = a[i][6] = a[i][7] = 0;
|
||||
b[i] = 0;
|
||||
}
|
||||
for( i = 4; i < 8; ++i )
|
||||
{
|
||||
a[i][3] = quad[i-4][0]; a[i][4] = quad[i-4][1]; a[i][5] = 1;
|
||||
a[i][0] = a[i][1] = a[i][2] = a[i][6] = a[i][7] = 0;
|
||||
b[i] = 0;
|
||||
}
|
||||
|
||||
int u = src_size.width - 1;
|
||||
int v = src_size.height - 1;
|
||||
|
||||
a[1][6] = -quad[1][0] * u; a[1][7] = -quad[1][1] * u;
|
||||
a[2][6] = -quad[2][0] * u; a[2][7] = -quad[2][1] * u;
|
||||
b[1] = b[2] = u;
|
||||
|
||||
a[6][6] = -quad[2][0] * v; a[6][7] = -quad[2][1] * v;
|
||||
a[7][6] = -quad[3][0] * v; a[7][7] = -quad[3][1] * v;
|
||||
b[6] = b[7] = v;
|
||||
|
||||
cvSolve( &A, &B, &X );
|
||||
|
||||
coeffs[2][2] = 1;
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
/* Warps source into destination by a perspective transform */
|
||||
static void cvWarpPerspective( CvArr* src, CvArr* dst, double quad[4][2] )
|
||||
{
|
||||
CV_FUNCNAME( "cvWarpPerspective" );
|
||||
|
||||
__BEGIN__;
|
||||
|
||||
#ifdef __IPL_H__
|
||||
IplImage src_stub, dst_stub;
|
||||
IplImage* src_img;
|
||||
IplImage* dst_img;
|
||||
CV_CALL( src_img = cvGetImage( src, &src_stub ) );
|
||||
CV_CALL( dst_img = cvGetImage( dst, &dst_stub ) );
|
||||
iplWarpPerspectiveQ( src_img, dst_img, quad, IPL_WARP_R_TO_Q,
|
||||
IPL_INTER_CUBIC | IPL_SMOOTH_EDGE );
|
||||
#else
|
||||
|
||||
int fill_value = 0;
|
||||
|
||||
double c[3][3]; /* transformation coefficients */
|
||||
double q[4][2]; /* rearranged quad */
|
||||
|
||||
int left = 0;
|
||||
int right = 0;
|
||||
int next_right = 0;
|
||||
int next_left = 0;
|
||||
double y_min = 0;
|
||||
double y_max = 0;
|
||||
double k_left, b_left, k_right, b_right;
|
||||
|
||||
uchar* src_data;
|
||||
int src_step;
|
||||
CvSize src_size;
|
||||
|
||||
uchar* dst_data;
|
||||
int dst_step;
|
||||
CvSize dst_size;
|
||||
|
||||
double d = 0;
|
||||
int direction = 0;
|
||||
int i;
|
||||
|
||||
if( !src || (!CV_IS_IMAGE( src ) && !CV_IS_MAT( src )) ||
|
||||
cvGetElemType( src ) != CV_8UC1 ||
|
||||
cvGetDims( src ) != 2 )
|
||||
{
|
||||
CV_ERROR( CV_StsBadArg,
|
||||
"Source must be two-dimensional array of CV_8UC1 type." );
|
||||
}
|
||||
if( !dst || (!CV_IS_IMAGE( dst ) && !CV_IS_MAT( dst )) ||
|
||||
cvGetElemType( dst ) != CV_8UC1 ||
|
||||
cvGetDims( dst ) != 2 )
|
||||
{
|
||||
CV_ERROR( CV_StsBadArg,
|
||||
"Destination must be two-dimensional array of CV_8UC1 type." );
|
||||
}
|
||||
|
||||
CV_CALL( cvGetRawData( src, &src_data, &src_step, &src_size ) );
|
||||
CV_CALL( cvGetRawData( dst, &dst_data, &dst_step, &dst_size ) );
|
||||
|
||||
CV_CALL( cvGetPerspectiveTransform( src_size, quad, c ) );
|
||||
|
||||
/* if direction > 0 then vertices in quad follow in a CW direction,
|
||||
otherwise they follow in a CCW direction */
|
||||
direction = 0;
|
||||
for( i = 0; i < 4; ++i )
|
||||
{
|
||||
int ni = i + 1; if( ni == 4 ) ni = 0;
|
||||
int pi = i - 1; if( pi == -1 ) pi = 3;
|
||||
|
||||
d = (quad[i][0] - quad[pi][0])*(quad[ni][1] - quad[i][1]) -
|
||||
(quad[i][1] - quad[pi][1])*(quad[ni][0] - quad[i][0]);
|
||||
int cur_direction = CV_SIGN(d);
|
||||
if( direction == 0 )
|
||||
{
|
||||
direction = cur_direction;
|
||||
}
|
||||
else if( direction * cur_direction < 0 )
|
||||
{
|
||||
direction = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if( direction == 0 )
|
||||
{
|
||||
CV_ERROR( CV_StsBadArg, "Quadrangle is nonconvex or degenerated." );
|
||||
}
|
||||
|
||||
/* <left> is the index of the topmost quad vertice
|
||||
if there are two such vertices <left> is the leftmost one */
|
||||
left = 0;
|
||||
for( i = 1; i < 4; ++i )
|
||||
{
|
||||
if( (quad[i][1] < quad[left][1]) ||
|
||||
((quad[i][1] == quad[left][1]) && (quad[i][0] < quad[left][0])) )
|
||||
{
|
||||
left = i;
|
||||
}
|
||||
}
|
||||
/* rearrange <quad> vertices in such way that they follow in a CW
|
||||
direction and the first vertice is the topmost one and put them
|
||||
into <q> */
|
||||
if( direction > 0 )
|
||||
{
|
||||
for( i = left; i < 4; ++i )
|
||||
{
|
||||
q[i-left][0] = quad[i][0];
|
||||
q[i-left][1] = quad[i][1];
|
||||
}
|
||||
for( i = 0; i < left; ++i )
|
||||
{
|
||||
q[4-left+i][0] = quad[i][0];
|
||||
q[4-left+i][1] = quad[i][1];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for( i = left; i >= 0; --i )
|
||||
{
|
||||
q[left-i][0] = quad[i][0];
|
||||
q[left-i][1] = quad[i][1];
|
||||
}
|
||||
for( i = 3; i > left; --i )
|
||||
{
|
||||
q[4+left-i][0] = quad[i][0];
|
||||
q[4+left-i][1] = quad[i][1];
|
||||
}
|
||||
}
|
||||
|
||||
left = right = 0;
|
||||
/* if there are two topmost points, <right> is the index of the rightmost one
|
||||
otherwise <right> */
|
||||
if( q[left][1] == q[left+1][1] )
|
||||
{
|
||||
right = 1;
|
||||
}
|
||||
|
||||
/* <next_left> follows <left> in a CCW direction */
|
||||
next_left = 3;
|
||||
/* <next_right> follows <right> in a CW direction */
|
||||
next_right = right + 1;
|
||||
|
||||
/* subtraction of 1 prevents skipping of the first row */
|
||||
y_min = q[left][1] - 1;
|
||||
|
||||
/* left edge equation: y = k_left * x + b_left */
|
||||
k_left = (q[left][0] - q[next_left][0]) /
|
||||
(q[left][1] - q[next_left][1]);
|
||||
b_left = (q[left][1] * q[next_left][0] -
|
||||
q[left][0] * q[next_left][1]) /
|
||||
(q[left][1] - q[next_left][1]);
|
||||
|
||||
/* right edge equation: y = k_right * x + b_right */
|
||||
k_right = (q[right][0] - q[next_right][0]) /
|
||||
(q[right][1] - q[next_right][1]);
|
||||
b_right = (q[right][1] * q[next_right][0] -
|
||||
q[right][0] * q[next_right][1]) /
|
||||
(q[right][1] - q[next_right][1]);
|
||||
|
||||
for(;;)
|
||||
{
|
||||
int x, y;
|
||||
|
||||
y_max = MIN( q[next_left][1], q[next_right][1] );
|
||||
|
||||
int iy_min = MAX( cvRound(y_min), 0 ) + 1;
|
||||
int iy_max = MIN( cvRound(y_max), dst_size.height - 1 );
|
||||
|
||||
double x_min = k_left * iy_min + b_left;
|
||||
double x_max = k_right * iy_min + b_right;
|
||||
|
||||
/* walk through the destination quadrangle row by row */
|
||||
for( y = iy_min; y <= iy_max; ++y )
|
||||
{
|
||||
int ix_min = MAX( cvRound( x_min ), 0 );
|
||||
int ix_max = MIN( cvRound( x_max ), dst_size.width - 1 );
|
||||
|
||||
for( x = ix_min; x <= ix_max; ++x )
|
||||
{
|
||||
/* calculate coordinates of the corresponding source array point */
|
||||
double div = (c[2][0] * x + c[2][1] * y + c[2][2]);
|
||||
double src_x = (c[0][0] * x + c[0][1] * y + c[0][2]) / div;
|
||||
double src_y = (c[1][0] * x + c[1][1] * y + c[1][2]) / div;
|
||||
|
||||
int isrc_x = cvFloor( src_x );
|
||||
int isrc_y = cvFloor( src_y );
|
||||
double delta_x = src_x - isrc_x;
|
||||
double delta_y = src_y - isrc_y;
|
||||
|
||||
uchar* s = src_data + isrc_y * src_step + isrc_x;
|
||||
|
||||
int i00, i10, i01, i11;
|
||||
i00 = i10 = i01 = i11 = (int) fill_value;
|
||||
|
||||
/* linear interpolation using 2x2 neighborhood */
|
||||
if( isrc_x >= 0 && isrc_x <= src_size.width &&
|
||||
isrc_y >= 0 && isrc_y <= src_size.height )
|
||||
{
|
||||
i00 = s[0];
|
||||
}
|
||||
if( isrc_x >= -1 && isrc_x < src_size.width &&
|
||||
isrc_y >= 0 && isrc_y <= src_size.height )
|
||||
{
|
||||
i10 = s[1];
|
||||
}
|
||||
if( isrc_x >= 0 && isrc_x <= src_size.width &&
|
||||
isrc_y >= -1 && isrc_y < src_size.height )
|
||||
{
|
||||
i01 = s[src_step];
|
||||
}
|
||||
if( isrc_x >= -1 && isrc_x < src_size.width &&
|
||||
isrc_y >= -1 && isrc_y < src_size.height )
|
||||
{
|
||||
i11 = s[src_step+1];
|
||||
}
|
||||
|
||||
double i0 = i00 + (i10 - i00)*delta_x;
|
||||
double i1 = i01 + (i11 - i01)*delta_x;
|
||||
|
||||
((uchar*)(dst_data + y * dst_step))[x] = (uchar) (i0 + (i1 - i0)*delta_y);
|
||||
}
|
||||
x_min += k_left;
|
||||
x_max += k_right;
|
||||
}
|
||||
|
||||
if( (next_left == next_right) ||
|
||||
(next_left+1 == next_right && q[next_left][1] == q[next_right][1]) )
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if( y_max == q[next_left][1] )
|
||||
{
|
||||
left = next_left;
|
||||
next_left = left - 1;
|
||||
|
||||
k_left = (q[left][0] - q[next_left][0]) /
|
||||
(q[left][1] - q[next_left][1]);
|
||||
b_left = (q[left][1] * q[next_left][0] -
|
||||
q[left][0] * q[next_left][1]) /
|
||||
(q[left][1] - q[next_left][1]);
|
||||
}
|
||||
if( y_max == q[next_right][1] )
|
||||
{
|
||||
right = next_right;
|
||||
next_right = right + 1;
|
||||
|
||||
k_right = (q[right][0] - q[next_right][0]) /
|
||||
(q[right][1] - q[next_right][1]);
|
||||
b_right = (q[right][1] * q[next_right][0] -
|
||||
q[right][0] * q[next_right][1]) /
|
||||
(q[right][1] - q[next_right][1]);
|
||||
}
|
||||
y_min = y_max;
|
||||
}
|
||||
#endif /* #ifndef __IPL_H__ */
|
||||
|
||||
__END__;
|
||||
}
|
||||
|
||||
static
|
||||
void icvRandomQuad( int width, int height, double quad[4][2],
|
||||
double maxxangle,
|
||||
double maxyangle,
|
||||
double maxzangle )
|
||||
{
|
||||
double distfactor = 3.0;
|
||||
double distfactor2 = 1.0;
|
||||
|
||||
double halfw, halfh;
|
||||
int i;
|
||||
|
||||
double rotVectData[3];
|
||||
double vectData[3];
|
||||
double rotMatData[9];
|
||||
|
||||
CvMat rotVect;
|
||||
CvMat rotMat;
|
||||
CvMat vect;
|
||||
|
||||
double d;
|
||||
|
||||
rotVect = cvMat( 3, 1, CV_64FC1, &rotVectData[0] );
|
||||
rotMat = cvMat( 3, 3, CV_64FC1, &rotMatData[0] );
|
||||
vect = cvMat( 3, 1, CV_64FC1, &vectData[0] );
|
||||
|
||||
rotVectData[0] = maxxangle * (2.0 * rand() / RAND_MAX - 1.0);
|
||||
rotVectData[1] = ( maxyangle - fabs( rotVectData[0] ) )
|
||||
* (2.0 * rand() / RAND_MAX - 1.0);
|
||||
rotVectData[2] = maxzangle * (2.0 * rand() / RAND_MAX - 1.0);
|
||||
d = (distfactor + distfactor2 * (2.0 * rand() / RAND_MAX - 1.0)) * width;
|
||||
|
||||
/*
|
||||
rotVectData[0] = maxxangle;
|
||||
rotVectData[1] = maxyangle;
|
||||
rotVectData[2] = maxzangle;
|
||||
|
||||
d = distfactor * width;
|
||||
*/
|
||||
|
||||
cvRodrigues2( &rotVect, &rotMat );
|
||||
|
||||
halfw = 0.5 * width;
|
||||
halfh = 0.5 * height;
|
||||
|
||||
quad[0][0] = -halfw;
|
||||
quad[0][1] = -halfh;
|
||||
quad[1][0] = halfw;
|
||||
quad[1][1] = -halfh;
|
||||
quad[2][0] = halfw;
|
||||
quad[2][1] = halfh;
|
||||
quad[3][0] = -halfw;
|
||||
quad[3][1] = halfh;
|
||||
|
||||
for( i = 0; i < 4; i++ )
|
||||
{
|
||||
rotVectData[0] = quad[i][0];
|
||||
rotVectData[1] = quad[i][1];
|
||||
rotVectData[2] = 0.0;
|
||||
cvMatMulAdd( &rotMat, &rotVect, 0, &vect );
|
||||
quad[i][0] = vectData[0] * d / (d + vectData[2]) + halfw;
|
||||
quad[i][1] = vectData[1] * d / (d + vectData[2]) + halfh;
|
||||
|
||||
/*
|
||||
quad[i][0] += halfw;
|
||||
quad[i][1] += halfh;
|
||||
*/
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int icvStartSampleDistortion( const char* imgfilename, int bgcolor, int bgthreshold,
|
||||
CvSampleDistortionData* data )
|
||||
{
|
||||
memset( data, 0, sizeof( *data ) );
|
||||
data->src = cvLoadImage( imgfilename, 0 );
|
||||
if( data->src != NULL && data->src->nChannels == 1
|
||||
&& data->src->depth == IPL_DEPTH_8U )
|
||||
{
|
||||
int r, c;
|
||||
uchar* pmask;
|
||||
uchar* psrc;
|
||||
uchar* perode;
|
||||
uchar* pdilate;
|
||||
uchar dd, de;
|
||||
|
||||
data->dx = data->src->width / 2;
|
||||
data->dy = data->src->height / 2;
|
||||
data->bgcolor = bgcolor;
|
||||
|
||||
data->mask = cvCloneImage( data->src );
|
||||
data->erode = cvCloneImage( data->src );
|
||||
data->dilate = cvCloneImage( data->src );
|
||||
|
||||
/* make mask image */
|
||||
for( r = 0; r < data->mask->height; r++ )
|
||||
{
|
||||
for( c = 0; c < data->mask->width; c++ )
|
||||
{
|
||||
pmask = ( (uchar*) (data->mask->imageData + r * data->mask->widthStep)
|
||||
+ c );
|
||||
if( bgcolor - bgthreshold <= (int) (*pmask) &&
|
||||
(int) (*pmask) <= bgcolor + bgthreshold )
|
||||
{
|
||||
*pmask = (uchar) 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
*pmask = (uchar) 255;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* extend borders of source image */
|
||||
cvErode( data->src, data->erode, 0, 1 );
|
||||
cvDilate( data->src, data->dilate, 0, 1 );
|
||||
for( r = 0; r < data->mask->height; r++ )
|
||||
{
|
||||
for( c = 0; c < data->mask->width; c++ )
|
||||
{
|
||||
pmask = ( (uchar*) (data->mask->imageData + r * data->mask->widthStep)
|
||||
+ c );
|
||||
if( (*pmask) == 0 )
|
||||
{
|
||||
psrc = ( (uchar*) (data->src->imageData + r * data->src->widthStep)
|
||||
+ c );
|
||||
perode =
|
||||
( (uchar*) (data->erode->imageData + r * data->erode->widthStep)
|
||||
+ c );
|
||||
pdilate =
|
||||
( (uchar*)(data->dilate->imageData + r * data->dilate->widthStep)
|
||||
+ c );
|
||||
de = (uchar)(bgcolor - (*perode));
|
||||
dd = (uchar)((*pdilate) - bgcolor);
|
||||
if( de >= dd && de > bgthreshold )
|
||||
{
|
||||
(*psrc) = (*perode);
|
||||
}
|
||||
if( dd > de && dd > bgthreshold )
|
||||
{
|
||||
(*psrc) = (*pdilate);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
data->img = cvCreateImage( cvSize( data->src->width + 2 * data->dx,
|
||||
data->src->height + 2 * data->dy ),
|
||||
IPL_DEPTH_8U, 1 );
|
||||
data->maskimg = cvCloneImage( data->img );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void icvPlaceDistortedSample( CvArr* background,
|
||||
int inverse, int maxintensitydev,
|
||||
double maxxangle, double maxyangle, double maxzangle,
|
||||
int inscribe, double maxshiftf, double maxscalef,
|
||||
CvSampleDistortionData* data )
|
||||
{
|
||||
double quad[4][2];
|
||||
int r, c;
|
||||
uchar* pimg;
|
||||
uchar* pbg;
|
||||
uchar* palpha;
|
||||
uchar chartmp;
|
||||
int forecolordev;
|
||||
float scale;
|
||||
IplImage* img;
|
||||
IplImage* maskimg;
|
||||
CvMat stub;
|
||||
CvMat* bgimg;
|
||||
|
||||
CvRect cr;
|
||||
CvRect roi;
|
||||
|
||||
double xshift, yshift, randscale;
|
||||
|
||||
icvRandomQuad( data->src->width, data->src->height, quad,
|
||||
maxxangle, maxyangle, maxzangle );
|
||||
quad[0][0] += (double) data->dx;
|
||||
quad[0][1] += (double) data->dy;
|
||||
quad[1][0] += (double) data->dx;
|
||||
quad[1][1] += (double) data->dy;
|
||||
quad[2][0] += (double) data->dx;
|
||||
quad[2][1] += (double) data->dy;
|
||||
quad[3][0] += (double) data->dx;
|
||||
quad[3][1] += (double) data->dy;
|
||||
|
||||
cvSet( data->img, cvScalar( data->bgcolor ) );
|
||||
cvSet( data->maskimg, cvScalar( 0.0 ) );
|
||||
|
||||
cvWarpPerspective( data->src, data->img, quad );
|
||||
cvWarpPerspective( data->mask, data->maskimg, quad );
|
||||
|
||||
cvSmooth( data->maskimg, data->maskimg, CV_GAUSSIAN, 3, 3 );
|
||||
|
||||
bgimg = cvGetMat( background, &stub );
|
||||
|
||||
cr.x = data->dx;
|
||||
cr.y = data->dy;
|
||||
cr.width = data->src->width;
|
||||
cr.height = data->src->height;
|
||||
|
||||
if( inscribe )
|
||||
{
|
||||
/* quad's circumscribing rectangle */
|
||||
cr.x = (int) MIN( quad[0][0], quad[3][0] );
|
||||
cr.y = (int) MIN( quad[0][1], quad[1][1] );
|
||||
cr.width = (int) (MAX( quad[1][0], quad[2][0] ) + 0.5F ) - cr.x;
|
||||
cr.height = (int) (MAX( quad[2][1], quad[3][1] ) + 0.5F ) - cr.y;
|
||||
}
|
||||
|
||||
xshift = maxshiftf * rand() / RAND_MAX;
|
||||
yshift = maxshiftf * rand() / RAND_MAX;
|
||||
|
||||
cr.x -= (int) ( xshift * cr.width );
|
||||
cr.y -= (int) ( yshift * cr.height );
|
||||
cr.width = (int) ((1.0 + maxshiftf) * cr.width );
|
||||
cr.height = (int) ((1.0 + maxshiftf) * cr.height);
|
||||
|
||||
randscale = maxscalef * rand() / RAND_MAX;
|
||||
cr.x -= (int) ( 0.5 * randscale * cr.width );
|
||||
cr.y -= (int) ( 0.5 * randscale * cr.height );
|
||||
cr.width = (int) ((1.0 + randscale) * cr.width );
|
||||
cr.height = (int) ((1.0 + randscale) * cr.height);
|
||||
|
||||
scale = MAX( ((float) cr.width) / bgimg->cols, ((float) cr.height) / bgimg->rows );
|
||||
|
||||
roi.x = (int) (-0.5F * (scale * bgimg->cols - cr.width) + cr.x);
|
||||
roi.y = (int) (-0.5F * (scale * bgimg->rows - cr.height) + cr.y);
|
||||
roi.width = (int) (scale * bgimg->cols);
|
||||
roi.height = (int) (scale * bgimg->rows);
|
||||
|
||||
img = cvCreateImage( cvSize( bgimg->cols, bgimg->rows ), IPL_DEPTH_8U, 1 );
|
||||
maskimg = cvCreateImage( cvSize( bgimg->cols, bgimg->rows ), IPL_DEPTH_8U, 1 );
|
||||
|
||||
cvSetImageROI( data->img, roi );
|
||||
cvResize( data->img, img );
|
||||
cvResetImageROI( data->img );
|
||||
cvSetImageROI( data->maskimg, roi );
|
||||
cvResize( data->maskimg, maskimg );
|
||||
cvResetImageROI( data->maskimg );
|
||||
|
||||
forecolordev = (int) (maxintensitydev * (2.0 * rand() / RAND_MAX - 1.0));
|
||||
|
||||
for( r = 0; r < img->height; r++ )
|
||||
{
|
||||
for( c = 0; c < img->width; c++ )
|
||||
{
|
||||
pimg = (uchar*) img->imageData + r * img->widthStep + c;
|
||||
pbg = (uchar*) bgimg->data.ptr + r * bgimg->step + c;
|
||||
palpha = (uchar*) maskimg->imageData + r * maskimg->widthStep + c;
|
||||
chartmp = (uchar) MAX( 0, MIN( 255, forecolordev + (*pimg) ) );
|
||||
if( inverse )
|
||||
{
|
||||
chartmp ^= 0xFF;
|
||||
}
|
||||
*pbg = (uchar) (( chartmp*(*palpha )+(255 - (*palpha) )*(*pbg) ) / 255);
|
||||
}
|
||||
}
|
||||
|
||||
cvReleaseImage( &img );
|
||||
cvReleaseImage( &maskimg );
|
||||
}
|
||||
|
||||
void icvEndSampleDistortion( CvSampleDistortionData* data )
|
||||
{
|
||||
if( data->src )
|
||||
{
|
||||
cvReleaseImage( &data->src );
|
||||
}
|
||||
if( data->mask )
|
||||
{
|
||||
cvReleaseImage( &data->mask );
|
||||
}
|
||||
if( data->erode )
|
||||
{
|
||||
cvReleaseImage( &data->erode );
|
||||
}
|
||||
if( data->dilate )
|
||||
{
|
||||
cvReleaseImage( &data->dilate );
|
||||
}
|
||||
if( data->img )
|
||||
{
|
||||
cvReleaseImage( &data->img );
|
||||
}
|
||||
if( data->maskimg )
|
||||
{
|
||||
cvReleaseImage( &data->maskimg );
|
||||
}
|
||||
}
|
||||
|
||||
void icvWriteVecHeader( FILE* file, int count, int width, int height )
|
||||
{
|
||||
int vecsize;
|
||||
short tmp;
|
||||
|
||||
/* number of samples */
|
||||
fwrite( &count, sizeof( count ), 1, file );
|
||||
/* vector size */
|
||||
vecsize = width * height;
|
||||
fwrite( &vecsize, sizeof( vecsize ), 1, file );
|
||||
/* min/max values */
|
||||
tmp = 0;
|
||||
fwrite( &tmp, sizeof( tmp ), 1, file );
|
||||
fwrite( &tmp, sizeof( tmp ), 1, file );
|
||||
}
|
||||
|
||||
void icvWriteVecSample( FILE* file, CvArr* sample )
|
||||
{
|
||||
CvMat* mat, stub;
|
||||
int r, c;
|
||||
short tmp;
|
||||
uchar chartmp;
|
||||
|
||||
mat = cvGetMat( sample, &stub );
|
||||
chartmp = 0;
|
||||
fwrite( &chartmp, sizeof( chartmp ), 1, file );
|
||||
for( r = 0; r < mat->rows; r++ )
|
||||
{
|
||||
for( c = 0; c < mat->cols; c++ )
|
||||
{
|
||||
tmp = (short) (CV_MAT_ELEM( *mat, uchar, r, c ));
|
||||
fwrite( &tmp, sizeof( tmp ), 1, file );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int cvCreateTrainingSamplesFromInfo( const char* infoname, const char* vecfilename,
|
||||
int num,
|
||||
int showsamples,
|
||||
int winwidth, int winheight )
|
||||
{
|
||||
char fullname[PATH_MAX];
|
||||
char* filename;
|
||||
|
||||
FILE* info;
|
||||
FILE* vec;
|
||||
IplImage* src=0;
|
||||
IplImage* sample;
|
||||
int line;
|
||||
int error;
|
||||
int i;
|
||||
int x, y, width, height;
|
||||
int total;
|
||||
|
||||
assert( infoname != NULL );
|
||||
assert( vecfilename != NULL );
|
||||
|
||||
total = 0;
|
||||
if( !icvMkDir( vecfilename ) )
|
||||
{
|
||||
|
||||
#if CV_VERBOSE
|
||||
fprintf( stderr, "Unable to create directory hierarchy: %s\n", vecfilename );
|
||||
#endif /* CV_VERBOSE */
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
info = fopen( infoname, "r" );
|
||||
if( info == NULL )
|
||||
{
|
||||
|
||||
#if CV_VERBOSE
|
||||
fprintf( stderr, "Unable to open file: %s\n", infoname );
|
||||
#endif /* CV_VERBOSE */
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
vec = fopen( vecfilename, "wb" );
|
||||
if( vec == NULL )
|
||||
{
|
||||
|
||||
#if CV_VERBOSE
|
||||
fprintf( stderr, "Unable to open file: %s\n", vecfilename );
|
||||
#endif /* CV_VERBOSE */
|
||||
|
||||
fclose( info );
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
sample = cvCreateImage( cvSize( winwidth, winheight ), IPL_DEPTH_8U, 1 );
|
||||
|
||||
icvWriteVecHeader( vec, num, sample->width, sample->height );
|
||||
|
||||
if( showsamples )
|
||||
{
|
||||
cvNamedWindow( "Sample", CV_WINDOW_AUTOSIZE );
|
||||
}
|
||||
|
||||
strcpy( fullname, infoname );
|
||||
filename = strrchr( fullname, '\\' );
|
||||
if( filename == NULL )
|
||||
{
|
||||
filename = strrchr( fullname, '/' );
|
||||
}
|
||||
if( filename == NULL )
|
||||
{
|
||||
filename = fullname;
|
||||
}
|
||||
else
|
||||
{
|
||||
filename++;
|
||||
}
|
||||
|
||||
for( line = 1, error = 0, total = 0; total < num ;line++ )
|
||||
{
|
||||
int count;
|
||||
|
||||
error = ( fscanf( info, "%s %d", filename, &count ) != 2 );
|
||||
if( !error )
|
||||
{
|
||||
src = cvLoadImage( fullname, 0 );
|
||||
error = ( src == NULL );
|
||||
if( error )
|
||||
{
|
||||
|
||||
#if CV_VERBOSE
|
||||
fprintf( stderr, "Unable to open image: %s\n", fullname );
|
||||
#endif /* CV_VERBOSE */
|
||||
|
||||
}
|
||||
}
|
||||
for( i = 0; (i < count) && (total < num); i++, total++ )
|
||||
{
|
||||
error = ( fscanf( info, "%d %d %d %d", &x, &y, &width, &height ) != 4 );
|
||||
if( error ) break;
|
||||
cvSetImageROI( src, cvRect( x, y, width, height ) );
|
||||
cvResize( src, sample, width >= sample->width &&
|
||||
height >= sample->height ? CV_INTER_AREA : CV_INTER_LINEAR );
|
||||
|
||||
if( showsamples )
|
||||
{
|
||||
cvShowImage( "Sample", sample );
|
||||
if( cvWaitKey( 0 ) == 27 )
|
||||
{
|
||||
showsamples = 0;
|
||||
}
|
||||
}
|
||||
icvWriteVecSample( vec, sample );
|
||||
}
|
||||
|
||||
if( src )
|
||||
{
|
||||
cvReleaseImage( &src );
|
||||
}
|
||||
|
||||
if( error )
|
||||
{
|
||||
|
||||
#if CV_VERBOSE
|
||||
fprintf( stderr, "%s(%d) : parse error", infoname, line );
|
||||
#endif /* CV_VERBOSE */
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( sample )
|
||||
{
|
||||
cvReleaseImage( &sample );
|
||||
}
|
||||
|
||||
fclose( vec );
|
||||
fclose( info );
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
|
||||
void cvShowVecSamples( const char* filename, int winwidth, int winheight,
|
||||
double scale )
|
||||
{
|
||||
CvVecFile file;
|
||||
short tmp;
|
||||
int i;
|
||||
CvMat* sample;
|
||||
|
||||
tmp = 0;
|
||||
file.input = fopen( filename, "rb" );
|
||||
|
||||
if( file.input != NULL )
|
||||
{
|
||||
size_t elements_read1 = fread( &file.count, sizeof( file.count ), 1, file.input );
|
||||
size_t elements_read2 = fread( &file.vecsize, sizeof( file.vecsize ), 1, file.input );
|
||||
size_t elements_read3 = fread( &tmp, sizeof( tmp ), 1, file.input );
|
||||
size_t elements_read4 = fread( &tmp, sizeof( tmp ), 1, file.input );
|
||||
CV_Assert(elements_read1 == 1 && elements_read2 == 1 && elements_read3 == 1 && elements_read4 == 1);
|
||||
|
||||
if( file.vecsize != winwidth * winheight )
|
||||
{
|
||||
int guessed_w = 0;
|
||||
int guessed_h = 0;
|
||||
|
||||
fprintf( stderr, "Warning: specified sample width=%d and height=%d "
|
||||
"does not correspond to .vec file vector size=%d.\n",
|
||||
winwidth, winheight, file.vecsize );
|
||||
if( file.vecsize > 0 )
|
||||
{
|
||||
guessed_w = cvFloor( sqrt( (float) file.vecsize ) );
|
||||
if( guessed_w > 0 )
|
||||
{
|
||||
guessed_h = file.vecsize / guessed_w;
|
||||
}
|
||||
}
|
||||
|
||||
if( guessed_w <= 0 || guessed_h <= 0 || guessed_w * guessed_h != file.vecsize)
|
||||
{
|
||||
fprintf( stderr, "Error: failed to guess sample width and height\n" );
|
||||
fclose( file.input );
|
||||
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
winwidth = guessed_w;
|
||||
winheight = guessed_h;
|
||||
fprintf( stderr, "Guessed width=%d, guessed height=%d\n",
|
||||
winwidth, winheight );
|
||||
}
|
||||
}
|
||||
|
||||
if( !feof( file.input ) && scale > 0 )
|
||||
{
|
||||
CvMat* scaled_sample = 0;
|
||||
|
||||
file.last = 0;
|
||||
file.vector = (short*) cvAlloc( sizeof( *file.vector ) * file.vecsize );
|
||||
sample = scaled_sample = cvCreateMat( winheight, winwidth, CV_8UC1 );
|
||||
if( scale != 1.0 )
|
||||
{
|
||||
scaled_sample = cvCreateMat( MAX( 1, cvCeil( scale * winheight ) ),
|
||||
MAX( 1, cvCeil( scale * winwidth ) ),
|
||||
CV_8UC1 );
|
||||
}
|
||||
cvNamedWindow( "Sample", CV_WINDOW_AUTOSIZE );
|
||||
for( i = 0; i < file.count; i++ )
|
||||
{
|
||||
icvGetHaarTraininDataFromVecCallback( sample, &file );
|
||||
if( scale != 1.0 ) cvResize( sample, scaled_sample, CV_INTER_LINEAR);
|
||||
cvShowImage( "Sample", scaled_sample );
|
||||
if( cvWaitKey( 0 ) == 27 ) break;
|
||||
}
|
||||
if( scaled_sample && scaled_sample != sample ) cvReleaseMat( &scaled_sample );
|
||||
cvReleaseMat( &sample );
|
||||
cvFree( &file.vector );
|
||||
}
|
||||
fclose( file.input );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* End of file. */
|
||||
@@ -1,284 +0,0 @@
|
||||
/*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*/
|
||||
|
||||
/*
|
||||
* haartraining.cpp
|
||||
*
|
||||
* Train cascade classifier
|
||||
*/
|
||||
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <cstdlib>
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include "cvhaartraining.h"
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int i = 0;
|
||||
char* nullname = (char*)"(NULL)";
|
||||
|
||||
char* vecname = NULL;
|
||||
char* dirname = NULL;
|
||||
char* bgname = NULL;
|
||||
|
||||
bool bg_vecfile = false;
|
||||
int npos = 2000;
|
||||
int nneg = 2000;
|
||||
int nstages = 14;
|
||||
int mem = 200;
|
||||
int nsplits = 1;
|
||||
float minhitrate = 0.995F;
|
||||
float maxfalsealarm = 0.5F;
|
||||
float weightfraction = 0.95F;
|
||||
int mode = 0;
|
||||
int symmetric = 1;
|
||||
int equalweights = 0;
|
||||
int width = 24;
|
||||
int height = 24;
|
||||
const char* boosttypes[] = { "DAB", "RAB", "LB", "GAB" };
|
||||
int boosttype = 3;
|
||||
const char* stumperrors[] = { "misclass", "gini", "entropy" };
|
||||
int stumperror = 0;
|
||||
int maxtreesplits = 0;
|
||||
int minpos = 500;
|
||||
|
||||
if( argc == 1 )
|
||||
{
|
||||
printf( "Usage: %s\n -data <dir_name>\n"
|
||||
" -vec <vec_file_name>\n"
|
||||
" -bg <background_file_name>\n"
|
||||
" [-bg-vecfile]\n"
|
||||
" [-npos <number_of_positive_samples = %d>]\n"
|
||||
" [-nneg <number_of_negative_samples = %d>]\n"
|
||||
" [-nstages <number_of_stages = %d>]\n"
|
||||
" [-nsplits <number_of_splits = %d>]\n"
|
||||
" [-mem <memory_in_MB = %d>]\n"
|
||||
" [-sym (default)] [-nonsym]\n"
|
||||
" [-minhitrate <min_hit_rate = %f>]\n"
|
||||
" [-maxfalsealarm <max_false_alarm_rate = %f>]\n"
|
||||
" [-weighttrimming <weight_trimming = %f>]\n"
|
||||
" [-eqw]\n"
|
||||
" [-mode <BASIC (default) | CORE | ALL>]\n"
|
||||
" [-w <sample_width = %d>]\n"
|
||||
" [-h <sample_height = %d>]\n"
|
||||
" [-bt <DAB | RAB | LB | GAB (default)>]\n"
|
||||
" [-err <misclass (default) | gini | entropy>]\n"
|
||||
" [-maxtreesplits <max_number_of_splits_in_tree_cascade = %d>]\n"
|
||||
" [-minpos <min_number_of_positive_samples_per_cluster = %d>]\n",
|
||||
argv[0], npos, nneg, nstages, nsplits, mem,
|
||||
minhitrate, maxfalsealarm, weightfraction, width, height,
|
||||
maxtreesplits, minpos );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( i = 1; i < argc; i++ )
|
||||
{
|
||||
if( !strcmp( argv[i], "-data" ) )
|
||||
{
|
||||
dirname = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-vec" ) )
|
||||
{
|
||||
vecname = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bg" ) )
|
||||
{
|
||||
bgname = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bg-vecfile" ) )
|
||||
{
|
||||
bg_vecfile = true;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-npos" ) )
|
||||
{
|
||||
npos = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-nneg" ) )
|
||||
{
|
||||
nneg = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-nstages" ) )
|
||||
{
|
||||
nstages = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-nsplits" ) )
|
||||
{
|
||||
nsplits = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-mem" ) )
|
||||
{
|
||||
mem = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-sym" ) )
|
||||
{
|
||||
symmetric = 1;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-nonsym" ) )
|
||||
{
|
||||
symmetric = 0;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-minhitrate" ) )
|
||||
{
|
||||
minhitrate = (float) atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxfalsealarm" ) )
|
||||
{
|
||||
maxfalsealarm = (float) atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-weighttrimming" ) )
|
||||
{
|
||||
weightfraction = (float) atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-eqw" ) )
|
||||
{
|
||||
equalweights = 1;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-mode" ) )
|
||||
{
|
||||
char* tmp = argv[++i];
|
||||
|
||||
if( !strcmp( tmp, "CORE" ) )
|
||||
{
|
||||
mode = 1;
|
||||
}
|
||||
else if( !strcmp( tmp, "ALL" ) )
|
||||
{
|
||||
mode = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
mode = 0;
|
||||
}
|
||||
}
|
||||
else if( !strcmp( argv[i], "-w" ) )
|
||||
{
|
||||
width = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-h" ) )
|
||||
{
|
||||
height = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-bt" ) )
|
||||
{
|
||||
i++;
|
||||
if( !strcmp( argv[i], boosttypes[0] ) )
|
||||
{
|
||||
boosttype = 0;
|
||||
}
|
||||
else if( !strcmp( argv[i], boosttypes[1] ) )
|
||||
{
|
||||
boosttype = 1;
|
||||
}
|
||||
else if( !strcmp( argv[i], boosttypes[2] ) )
|
||||
{
|
||||
boosttype = 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
boosttype = 3;
|
||||
}
|
||||
}
|
||||
else if( !strcmp( argv[i], "-err" ) )
|
||||
{
|
||||
i++;
|
||||
if( !strcmp( argv[i], stumperrors[0] ) )
|
||||
{
|
||||
stumperror = 0;
|
||||
}
|
||||
else if( !strcmp( argv[i], stumperrors[1] ) )
|
||||
{
|
||||
stumperror = 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
stumperror = 2;
|
||||
}
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxtreesplits" ) )
|
||||
{
|
||||
maxtreesplits = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-minpos" ) )
|
||||
{
|
||||
minpos = atoi( argv[++i] );
|
||||
}
|
||||
}
|
||||
|
||||
printf( "Data dir name: %s\n", ((dirname == NULL) ? nullname : dirname ) );
|
||||
printf( "Vec file name: %s\n", ((vecname == NULL) ? nullname : vecname ) );
|
||||
printf( "BG file name: %s, is a vecfile: %s\n", ((bgname == NULL) ? nullname : bgname ), bg_vecfile ? "yes" : "no" );
|
||||
printf( "Num pos: %d\n", npos );
|
||||
printf( "Num neg: %d\n", nneg );
|
||||
printf( "Num stages: %d\n", nstages );
|
||||
printf( "Num splits: %d (%s as weak classifier)\n", nsplits,
|
||||
(nsplits == 1) ? "stump" : "tree" );
|
||||
printf( "Mem: %d MB\n", mem );
|
||||
printf( "Symmetric: %s\n", (symmetric) ? "TRUE" : "FALSE" );
|
||||
printf( "Min hit rate: %f\n", minhitrate );
|
||||
printf( "Max false alarm rate: %f\n", maxfalsealarm );
|
||||
printf( "Weight trimming: %f\n", weightfraction );
|
||||
printf( "Equal weights: %s\n", (equalweights) ? "TRUE" : "FALSE" );
|
||||
printf( "Mode: %s\n", ( (mode == 0) ? "BASIC" : ( (mode == 1) ? "CORE" : "ALL") ) );
|
||||
printf( "Width: %d\n", width );
|
||||
printf( "Height: %d\n", height );
|
||||
//printf( "Max num of precalculated features: %d\n", numprecalculated );
|
||||
printf( "Applied boosting algorithm: %s\n", boosttypes[boosttype] );
|
||||
printf( "Error (valid only for Discrete and Real AdaBoost): %s\n",
|
||||
stumperrors[stumperror] );
|
||||
|
||||
printf( "Max number of splits in tree cascade: %d\n", maxtreesplits );
|
||||
printf( "Min number of positive samples per cluster: %d\n", minpos );
|
||||
|
||||
cvCreateTreeCascadeClassifier( dirname, vecname, bgname,
|
||||
npos, nneg, nstages, mem,
|
||||
nsplits,
|
||||
minhitrate, maxfalsealarm, weightfraction,
|
||||
mode, symmetric,
|
||||
equalweights, width, height,
|
||||
boosttype, stumperror,
|
||||
maxtreesplits, minpos, bg_vecfile );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,377 +0,0 @@
|
||||
/*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*/
|
||||
|
||||
/*
|
||||
* performance.cpp
|
||||
*
|
||||
* Measure performance of classifier
|
||||
*/
|
||||
#include "opencv2/core.hpp"
|
||||
|
||||
#include "cv.h"
|
||||
#include "highgui.h"
|
||||
|
||||
#include <cstdio>
|
||||
#include <cmath>
|
||||
#include <ctime>
|
||||
|
||||
#ifdef _WIN32
|
||||
/* use clock() function insted of time() */
|
||||
#define time( arg ) (((double) clock()) / CLOCKS_PER_SEC)
|
||||
#endif /* _WIN32 */
|
||||
|
||||
#ifndef PATH_MAX
|
||||
#define PATH_MAX 512
|
||||
#endif /* PATH_MAX */
|
||||
|
||||
typedef struct HidCascade
|
||||
{
|
||||
int size;
|
||||
int count;
|
||||
} HidCascade;
|
||||
|
||||
typedef struct ObjectPos
|
||||
{
|
||||
float x;
|
||||
float y;
|
||||
float width;
|
||||
int found; /* for reference */
|
||||
int neghbors;
|
||||
} ObjectPos;
|
||||
|
||||
int main( int argc, char* argv[] )
|
||||
{
|
||||
int i, j;
|
||||
char* classifierdir = NULL;
|
||||
//char* samplesdir = NULL;
|
||||
|
||||
int saveDetected = 1;
|
||||
double scale_factor = 1.2;
|
||||
float maxSizeDiff = 1.5F;
|
||||
float maxPosDiff = 0.3F;
|
||||
|
||||
/* number of stages. if <=0 all stages are used */
|
||||
int nos = -1, nos0;
|
||||
|
||||
int width = 24;
|
||||
int height = 24;
|
||||
|
||||
int rocsize;
|
||||
|
||||
FILE* info;
|
||||
char* infoname;
|
||||
char fullname[PATH_MAX];
|
||||
char detfilename[PATH_MAX];
|
||||
char* filename;
|
||||
char detname[] = "det-";
|
||||
|
||||
CvHaarClassifierCascade* cascade;
|
||||
CvMemStorage* storage;
|
||||
CvSeq* objects;
|
||||
|
||||
double totaltime;
|
||||
|
||||
infoname = (char*)"";
|
||||
rocsize = 40;
|
||||
if( argc == 1 )
|
||||
{
|
||||
printf( "Usage: %s\n -data <classifier_directory_name>\n"
|
||||
" -info <collection_file_name>\n"
|
||||
" [-maxSizeDiff <max_size_difference = %f>]\n"
|
||||
" [-maxPosDiff <max_position_difference = %f>]\n"
|
||||
" [-sf <scale_factor = %f>]\n"
|
||||
" [-ni]\n"
|
||||
" [-nos <number_of_stages = %d>]\n"
|
||||
" [-rs <roc_size = %d>]\n"
|
||||
" [-w <sample_width = %d>]\n"
|
||||
" [-h <sample_height = %d>]\n",
|
||||
argv[0], maxSizeDiff, maxPosDiff, scale_factor, nos, rocsize,
|
||||
width, height );
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
for( i = 1; i < argc; i++ )
|
||||
{
|
||||
if( !strcmp( argv[i], "-data" ) )
|
||||
{
|
||||
classifierdir = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-info" ) )
|
||||
{
|
||||
infoname = argv[++i];
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxSizeDiff" ) )
|
||||
{
|
||||
maxSizeDiff = (float) atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-maxPosDiff" ) )
|
||||
{
|
||||
maxPosDiff = (float) atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-sf" ) )
|
||||
{
|
||||
scale_factor = atof( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-ni" ) )
|
||||
{
|
||||
saveDetected = 0;
|
||||
}
|
||||
else if( !strcmp( argv[i], "-nos" ) )
|
||||
{
|
||||
nos = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-rs" ) )
|
||||
{
|
||||
rocsize = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-w" ) )
|
||||
{
|
||||
width = atoi( argv[++i] );
|
||||
}
|
||||
else if( !strcmp( argv[i], "-h" ) )
|
||||
{
|
||||
height = atoi( argv[++i] );
|
||||
}
|
||||
}
|
||||
|
||||
cascade = cvLoadHaarClassifierCascade( classifierdir, cvSize( width, height ) );
|
||||
if( cascade == NULL )
|
||||
{
|
||||
printf( "Unable to load classifier from %s\n", classifierdir );
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int* numclassifiers = new int[cascade->count];
|
||||
numclassifiers[0] = cascade->stage_classifier[0].count;
|
||||
for( i = 1; i < cascade->count; i++ )
|
||||
{
|
||||
numclassifiers[i] = numclassifiers[i-1] + cascade->stage_classifier[i].count;
|
||||
}
|
||||
|
||||
storage = cvCreateMemStorage();
|
||||
|
||||
nos0 = cascade->count;
|
||||
if( nos <= 0 )
|
||||
nos = nos0;
|
||||
|
||||
strcpy( fullname, infoname );
|
||||
filename = strrchr( fullname, '\\' );
|
||||
if( filename == NULL )
|
||||
{
|
||||
filename = strrchr( fullname, '/' );
|
||||
}
|
||||
if( filename == NULL )
|
||||
{
|
||||
filename = fullname;
|
||||
}
|
||||
else
|
||||
{
|
||||
filename++;
|
||||
}
|
||||
|
||||
info = fopen( infoname, "r" );
|
||||
totaltime = 0.0;
|
||||
if( info != NULL )
|
||||
{
|
||||
int x, y;
|
||||
IplImage* img;
|
||||
int hits, missed, falseAlarms;
|
||||
int totalHits, totalMissed, totalFalseAlarms;
|
||||
int found;
|
||||
float distance;
|
||||
|
||||
int refcount;
|
||||
ObjectPos* ref;
|
||||
int detcount;
|
||||
ObjectPos* det;
|
||||
int error=0;
|
||||
|
||||
int* pos;
|
||||
int* neg;
|
||||
|
||||
pos = (int*) cvAlloc( rocsize * sizeof( *pos ) );
|
||||
neg = (int*) cvAlloc( rocsize * sizeof( *neg ) );
|
||||
for( i = 0; i < rocsize; i++ ) { pos[i] = neg[i] = 0; }
|
||||
|
||||
printf( "+================================+======+======+======+\n" );
|
||||
printf( "| File Name | Hits |Missed| False|\n" );
|
||||
printf( "+================================+======+======+======+\n" );
|
||||
|
||||
totalHits = totalMissed = totalFalseAlarms = 0;
|
||||
while( !feof( info ) )
|
||||
{
|
||||
if( fscanf( info, "%s %d", filename, &refcount ) != 2 || refcount <= 0 ) break;
|
||||
|
||||
img = cvLoadImage( fullname );
|
||||
if( !img ) continue;
|
||||
|
||||
ref = (ObjectPos*) cvAlloc( refcount * sizeof( *ref ) );
|
||||
for( i = 0; i < refcount; i++ )
|
||||
{
|
||||
int w, h;
|
||||
error = (fscanf( info, "%d %d %d %d", &x, &y, &w, &h ) != 4);
|
||||
if( error ) break;
|
||||
ref[i].x = 0.5F * w + x;
|
||||
ref[i].y = 0.5F * h + y;
|
||||
ref[i].width = sqrtf( 0.5F * (w * w + h * h) );
|
||||
ref[i].found = 0;
|
||||
ref[i].neghbors = 0;
|
||||
}
|
||||
if( !error )
|
||||
{
|
||||
cvClearMemStorage( storage );
|
||||
|
||||
cascade->count = nos;
|
||||
totaltime -= time( 0 );
|
||||
objects = cvHaarDetectObjects( img, cascade, storage, scale_factor, 1 );
|
||||
totaltime += time( 0 );
|
||||
cascade->count = nos0;
|
||||
|
||||
detcount = ( objects ? objects->total : 0);
|
||||
det = (detcount > 0) ?
|
||||
( (ObjectPos*)cvAlloc( detcount * sizeof( *det )) ) : NULL;
|
||||
hits = missed = falseAlarms = 0;
|
||||
for( i = 0; i < detcount; i++ )
|
||||
{
|
||||
CvAvgComp r = *((CvAvgComp*) cvGetSeqElem( objects, i ));
|
||||
det[i].x = 0.5F * r.rect.width + r.rect.x;
|
||||
det[i].y = 0.5F * r.rect.height + r.rect.y;
|
||||
det[i].width = sqrtf( 0.5F * (r.rect.width * r.rect.width +
|
||||
r.rect.height * r.rect.height) );
|
||||
det[i].neghbors = r.neighbors;
|
||||
|
||||
if( saveDetected )
|
||||
{
|
||||
cvRectangle( img, cvPoint( r.rect.x, r.rect.y ),
|
||||
cvPoint( r.rect.x + r.rect.width, r.rect.y + r.rect.height ),
|
||||
CV_RGB( 255, 0, 0 ), 3 );
|
||||
}
|
||||
|
||||
found = 0;
|
||||
for( j = 0; j < refcount; j++ )
|
||||
{
|
||||
distance = sqrtf( (det[i].x - ref[j].x) * (det[i].x - ref[j].x) +
|
||||
(det[i].y - ref[j].y) * (det[i].y - ref[j].y) );
|
||||
if( (distance < ref[j].width * maxPosDiff) &&
|
||||
(det[i].width > ref[j].width / maxSizeDiff) &&
|
||||
(det[i].width < ref[j].width * maxSizeDiff) )
|
||||
{
|
||||
ref[j].found = 1;
|
||||
ref[j].neghbors = MAX( ref[j].neghbors, det[i].neghbors );
|
||||
found = 1;
|
||||
}
|
||||
}
|
||||
if( !found )
|
||||
{
|
||||
falseAlarms++;
|
||||
neg[MIN(det[i].neghbors, rocsize - 1)]++;
|
||||
}
|
||||
}
|
||||
for( j = 0; j < refcount; j++ )
|
||||
{
|
||||
if( ref[j].found )
|
||||
{
|
||||
hits++;
|
||||
pos[MIN(ref[j].neghbors, rocsize - 1)]++;
|
||||
}
|
||||
else
|
||||
{
|
||||
missed++;
|
||||
}
|
||||
}
|
||||
|
||||
totalHits += hits;
|
||||
totalMissed += missed;
|
||||
totalFalseAlarms += falseAlarms;
|
||||
printf( "|%32.32s|%6d|%6d|%6d|\n", filename, hits, missed, falseAlarms );
|
||||
printf( "+--------------------------------+------+------+------+\n" );
|
||||
fflush( stdout );
|
||||
|
||||
if( saveDetected )
|
||||
{
|
||||
strcpy( detfilename, detname );
|
||||
strcat( detfilename, filename );
|
||||
strcpy( filename, detfilename );
|
||||
cvvSaveImage( fullname, img );
|
||||
}
|
||||
|
||||
if( det ) { cvFree( &det ); det = NULL; }
|
||||
} /* if( !error ) */
|
||||
|
||||
cvReleaseImage( &img );
|
||||
cvFree( &ref );
|
||||
}
|
||||
fclose( info );
|
||||
|
||||
printf( "|%32.32s|%6d|%6d|%6d|\n", "Total",
|
||||
totalHits, totalMissed, totalFalseAlarms );
|
||||
printf( "+================================+======+======+======+\n" );
|
||||
printf( "Number of stages: %d\n", nos );
|
||||
printf( "Number of weak classifiers: %d\n", numclassifiers[nos - 1] );
|
||||
printf( "Total time: %f\n", totaltime );
|
||||
|
||||
/* print ROC to stdout */
|
||||
for( i = rocsize - 1; i > 0; i-- )
|
||||
{
|
||||
pos[i-1] += pos[i];
|
||||
neg[i-1] += neg[i];
|
||||
}
|
||||
fprintf( stderr, "%d\n", nos );
|
||||
for( i = 0; i < rocsize; i++ )
|
||||
{
|
||||
fprintf( stderr, "\t%d\t%d\t%f\t%f\n", pos[i], neg[i],
|
||||
((float)pos[i]) / (totalHits + totalMissed),
|
||||
((float)neg[i]) / (totalHits + totalMissed) );
|
||||
}
|
||||
|
||||
cvFree( &pos );
|
||||
cvFree( &neg );
|
||||
}
|
||||
|
||||
delete[] numclassifiers;
|
||||
|
||||
cvReleaseHaarClassifierCascade( &cascade );
|
||||
cvReleaseMemStorage( &storage );
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
set(name sft)
|
||||
set(the_target opencv_${name})
|
||||
|
||||
set(OPENCV_${the_target}_DEPS opencv_core opencv_softcascade opencv_highgui opencv_imgproc opencv_ml)
|
||||
ocv_check_dependencies(${OPENCV_${the_target}_DEPS})
|
||||
|
||||
if(NOT OCV_DEPENDENCIES_FOUND)
|
||||
return()
|
||||
endif()
|
||||
|
||||
project(${the_target})
|
||||
|
||||
ocv_include_directories("${CMAKE_CURRENT_SOURCE_DIR}/include" "${OpenCV_SOURCE_DIR}/include/opencv")
|
||||
ocv_include_modules(${OPENCV_${the_target}_DEPS})
|
||||
|
||||
file(GLOB ${the_target}_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.cpp)
|
||||
|
||||
add_executable(${the_target} ${${the_target}_SOURCES})
|
||||
|
||||
target_link_libraries(${the_target} ${OPENCV_${the_target}_DEPS})
|
||||
|
||||
set_target_properties(${the_target} PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
ARCHIVE_OUTPUT_DIRECTORY ${LIBRARY_OUTPUT_PATH}
|
||||
RUNTIME_OUTPUT_DIRECTORY ${EXECUTABLE_OUTPUT_PATH}
|
||||
INSTALL_NAME_DIR lib
|
||||
OUTPUT_NAME "opencv_trainsoftcascade")
|
||||
|
||||
if(ENABLE_SOLUTION_FOLDERS)
|
||||
set_target_properties(${the_target} PROPERTIES FOLDER "applications")
|
||||
endif()
|
||||
|
||||
install(TARGETS ${the_target} RUNTIME DESTINATION bin COMPONENT main)
|
||||
@@ -1,162 +0,0 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2008-2012, Willow Garage Inc., 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 the copyright holders 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*/
|
||||
|
||||
#include <sft/config.hpp>
|
||||
#include <iomanip>
|
||||
|
||||
sft::Config::Config(): seed(0) {}
|
||||
|
||||
void sft::Config::write(cv::FileStorage& fs) const
|
||||
{
|
||||
fs << "{"
|
||||
<< "trainPath" << trainPath
|
||||
<< "testPath" << testPath
|
||||
|
||||
<< "modelWinSize" << modelWinSize
|
||||
<< "offset" << offset
|
||||
<< "octaves" << octaves
|
||||
|
||||
<< "positives" << positives
|
||||
<< "negatives" << negatives
|
||||
<< "btpNegatives" << btpNegatives
|
||||
|
||||
<< "shrinkage" << shrinkage
|
||||
|
||||
<< "treeDepth" << treeDepth
|
||||
<< "weaks" << weaks
|
||||
<< "poolSize" << poolSize
|
||||
|
||||
<< "cascadeName" << cascadeName
|
||||
<< "outXmlPath" << outXmlPath
|
||||
|
||||
<< "seed" << seed
|
||||
<< "featureType" << featureType
|
||||
<< "}";
|
||||
}
|
||||
|
||||
void sft::Config::read(const cv::FileNode& node)
|
||||
{
|
||||
trainPath = (string)node["trainPath"];
|
||||
testPath = (string)node["testPath"];
|
||||
|
||||
cv::FileNodeIterator nIt = node["modelWinSize"].end();
|
||||
modelWinSize = cv::Size((int)*(--nIt), (int)*(--nIt));
|
||||
|
||||
nIt = node["offset"].end();
|
||||
offset = cv::Point2i((int)*(--nIt), (int)*(--nIt));
|
||||
|
||||
node["octaves"] >> octaves;
|
||||
|
||||
positives = (int)node["positives"];
|
||||
negatives = (int)node["negatives"];
|
||||
btpNegatives = (int)node["btpNegatives"];
|
||||
|
||||
shrinkage = (int)node["shrinkage"];
|
||||
|
||||
treeDepth = (int)node["treeDepth"];
|
||||
weaks = (int)node["weaks"];
|
||||
poolSize = (int)node["poolSize"];
|
||||
|
||||
cascadeName = (std::string)node["cascadeName"];
|
||||
outXmlPath = (std::string)node["outXmlPath"];
|
||||
|
||||
seed = (int)node["seed"];
|
||||
featureType = (std::string)node["featureType"];
|
||||
}
|
||||
|
||||
void sft::write(cv::FileStorage& fs, const string&, const Config& x)
|
||||
{
|
||||
x.write(fs);
|
||||
}
|
||||
|
||||
void sft::read(const cv::FileNode& node, Config& x, const Config& default_value)
|
||||
{
|
||||
x = default_value;
|
||||
|
||||
if(!node.empty())
|
||||
x.read(node);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
||||
struct Out
|
||||
{
|
||||
Out(std::ostream& _out): out(_out) {}
|
||||
template<typename T>
|
||||
void operator ()(const T a) const {out << a << " ";}
|
||||
|
||||
std::ostream& out;
|
||||
private:
|
||||
Out& operator=(Out const& other);
|
||||
};
|
||||
}
|
||||
|
||||
std::ostream& sft::operator<<(std::ostream& out, const Config& m)
|
||||
{
|
||||
out << std::setw(14) << std::left << "trainPath" << m.trainPath << std::endl
|
||||
<< std::setw(14) << std::left << "testPath" << m.testPath << std::endl
|
||||
|
||||
<< std::setw(14) << std::left << "modelWinSize" << m.modelWinSize << std::endl
|
||||
<< std::setw(14) << std::left << "offset" << m.offset << std::endl
|
||||
<< std::setw(14) << std::left << "octaves";
|
||||
|
||||
Out o(out);
|
||||
for_each(m.octaves.begin(), m.octaves.end(), o);
|
||||
|
||||
out << std::endl
|
||||
<< std::setw(14) << std::left << "positives" << m.positives << std::endl
|
||||
<< std::setw(14) << std::left << "negatives" << m.negatives << std::endl
|
||||
<< std::setw(14) << std::left << "btpNegatives" << m.btpNegatives << std::endl
|
||||
|
||||
<< std::setw(14) << std::left << "shrinkage" << m.shrinkage << std::endl
|
||||
|
||||
<< std::setw(14) << std::left << "treeDepth" << m.treeDepth << std::endl
|
||||
<< std::setw(14) << std::left << "weaks" << m.weaks << std::endl
|
||||
<< std::setw(14) << std::left << "poolSize" << m.poolSize << std::endl
|
||||
|
||||
<< std::setw(14) << std::left << "cascadeName" << m.cascadeName << std::endl
|
||||
<< std::setw(14) << std::left << "outXmlPath" << m.outXmlPath << std::endl
|
||||
<< std::setw(14) << std::left << "seed" << m.seed << std::endl
|
||||
<< std::setw(14) << std::left << "featureType" << m.featureType << std::endl;
|
||||
|
||||
return out;
|
||||
}
|
||||
@@ -1,77 +0,0 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2008-2012, Willow Garage Inc., 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 the copyright holders 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*/
|
||||
|
||||
#include <sft/dataset.hpp>
|
||||
#include <opencv2/highgui.hpp>
|
||||
|
||||
#include <iostream>
|
||||
#include <queue>
|
||||
|
||||
// in the default case data folders should be aligned as following:
|
||||
// 1. positives: <train or test path>/octave_<octave number>/pos/*.png
|
||||
// 2. negatives: <train or test path>/octave_<octave number>/neg/*.png
|
||||
sft::ScaledDataset::ScaledDataset(const string& path, const int oct)
|
||||
{
|
||||
dprintf("%s\n", "get dataset file names...");
|
||||
dprintf("%s\n", "Positives globing...");
|
||||
cv::glob(path + "/pos/octave_" + cv::format("%d", oct) + "/*.png", pos);
|
||||
|
||||
dprintf("%s\n", "Negatives globing...");
|
||||
cv::glob(path + "/neg/octave_" + cv::format("%d", oct) + "/*.png", neg);
|
||||
|
||||
// Check: files not empty
|
||||
CV_Assert(pos.size() != size_t(0));
|
||||
CV_Assert(neg.size() != size_t(0));
|
||||
}
|
||||
|
||||
cv::Mat sft::ScaledDataset::get(SampleType type, int idx) const
|
||||
{
|
||||
const std::string& src = (type == POSITIVE)? pos[idx]: neg[idx];
|
||||
return cv::imread(src);
|
||||
}
|
||||
|
||||
int sft::ScaledDataset::available(SampleType type) const
|
||||
{
|
||||
return (int)((type == POSITIVE)? pos.size():neg.size());
|
||||
}
|
||||
|
||||
sft::ScaledDataset::~ScaledDataset(){}
|
||||
@@ -1,74 +0,0 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2008-2012, Willow Garage Inc., 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 the copyright holders 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*/
|
||||
|
||||
#ifndef __SFT_COMMON_HPP__
|
||||
#define __SFT_COMMON_HPP__
|
||||
|
||||
#include <opencv2/core.hpp>
|
||||
#include <opencv2/core/utility.hpp>
|
||||
#include <opencv2/softcascade.hpp>
|
||||
|
||||
namespace cv {using namespace softcascade;}
|
||||
namespace sft
|
||||
{
|
||||
|
||||
using cv::Mat;
|
||||
struct ICF;
|
||||
|
||||
typedef cv::String string;
|
||||
|
||||
typedef std::vector<ICF> Icfvector;
|
||||
typedef std::vector<sft::string> svector;
|
||||
typedef std::vector<int> ivector;
|
||||
}
|
||||
|
||||
// used for noisy printfs
|
||||
//#define WITH_DEBUG_OUT
|
||||
|
||||
#if defined WITH_DEBUG_OUT
|
||||
# include <stdio.h>
|
||||
# define dprintf(format, ...) printf(format, ##__VA_ARGS__)
|
||||
#else
|
||||
# define dprintf(format, ...)
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -1,138 +0,0 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2008-2012, Willow Garage Inc., 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 the copyright holders 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*/
|
||||
|
||||
#ifndef __SFT_CONFIG_HPP__
|
||||
#define __SFT_CONFIG_HPP__
|
||||
|
||||
#include <sft/common.hpp>
|
||||
|
||||
#include <ostream>
|
||||
|
||||
namespace sft {
|
||||
|
||||
struct Config
|
||||
{
|
||||
Config();
|
||||
|
||||
void write(cv::FileStorage& fs) const;
|
||||
|
||||
void read(const cv::FileNode& node);
|
||||
|
||||
// Scaled and shrunk model size.
|
||||
cv::Size model(ivector::const_iterator it) const
|
||||
{
|
||||
float octave = powf(2.f, (float)(*it));
|
||||
return cv::Size( cvRound(modelWinSize.width * octave) / shrinkage,
|
||||
cvRound(modelWinSize.height * octave) / shrinkage );
|
||||
}
|
||||
|
||||
// Scaled but, not shrunk bounding box for object in sample image.
|
||||
cv::Rect bbox(ivector::const_iterator it) const
|
||||
{
|
||||
float octave = powf(2.f, (float)(*it));
|
||||
return cv::Rect( cvRound(offset.x * octave), cvRound(offset.y * octave),
|
||||
cvRound(modelWinSize.width * octave), cvRound(modelWinSize.height * octave));
|
||||
}
|
||||
|
||||
string resPath(ivector::const_iterator it) const
|
||||
{
|
||||
return cv::format("%s%d.xml",cascadeName.c_str(), *it);
|
||||
}
|
||||
|
||||
// Paths to a rescaled data
|
||||
string trainPath;
|
||||
string testPath;
|
||||
|
||||
// Original model size.
|
||||
cv::Size modelWinSize;
|
||||
|
||||
// example offset into positive image
|
||||
cv::Point2i offset;
|
||||
|
||||
// List of octaves for which have to be trained cascades (a list of powers of two)
|
||||
ivector octaves;
|
||||
|
||||
// Maximum number of positives that should be used during training
|
||||
int positives;
|
||||
|
||||
// Initial number of negatives used during training.
|
||||
int negatives;
|
||||
|
||||
// Number of weak negatives to add each bootstrapping step.
|
||||
int btpNegatives;
|
||||
|
||||
// Inverse of scale for feature resizing
|
||||
int shrinkage;
|
||||
|
||||
// Depth on weak classifier's decision tree
|
||||
int treeDepth;
|
||||
|
||||
// Weak classifiers number in resulted cascade
|
||||
int weaks;
|
||||
|
||||
// Feature random pool size
|
||||
int poolSize;
|
||||
|
||||
// file name to store cascade
|
||||
string cascadeName;
|
||||
|
||||
// path to resulting cascade
|
||||
string outXmlPath;
|
||||
|
||||
// seed for random generation
|
||||
int seed;
|
||||
|
||||
// channel feature type
|
||||
string featureType;
|
||||
|
||||
// // bounding rectangle for actual example into example window
|
||||
// cv::Rect exampleWindow;
|
||||
};
|
||||
|
||||
// required for cv::FileStorage serialization
|
||||
void write(cv::FileStorage& fs, const string&, const Config& x);
|
||||
void read(const cv::FileNode& node, Config& x, const Config& default_value);
|
||||
std::ostream& operator<<(std::ostream& out, const Config& m);
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,67 +0,0 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2008-2012, Willow Garage Inc., 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 the copyright holders 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*/
|
||||
|
||||
#ifndef __SFT_OCTAVE_HPP__
|
||||
#define __SFT_OCTAVE_HPP__
|
||||
|
||||
#include <sft/common.hpp>
|
||||
namespace sft
|
||||
{
|
||||
|
||||
using cv::softcascade::Dataset;
|
||||
|
||||
class ScaledDataset : public Dataset
|
||||
{
|
||||
public:
|
||||
ScaledDataset(const sft::string& path, const int octave);
|
||||
|
||||
virtual cv::Mat get(SampleType type, int idx) const;
|
||||
virtual int available(SampleType type) const;
|
||||
virtual ~ScaledDataset();
|
||||
|
||||
private:
|
||||
svector pos;
|
||||
svector neg;
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
168
apps/sft/sft.cpp
168
apps/sft/sft.cpp
@@ -1,168 +0,0 @@
|
||||
/*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.
|
||||
//
|
||||
//
|
||||
// License Agreement
|
||||
// For Open Source Computer Vision Library
|
||||
//
|
||||
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
|
||||
// Copyright (C) 2008-2012, Willow Garage Inc., 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 the copyright holders 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*/
|
||||
|
||||
// Training application for Soft Cascades.
|
||||
|
||||
#include <sft/common.hpp>
|
||||
#include <iostream>
|
||||
#include <sft/dataset.hpp>
|
||||
#include <sft/config.hpp>
|
||||
|
||||
#include <opencv2/core/core_c.h>
|
||||
|
||||
int main(int argc, char** argv)
|
||||
{
|
||||
using namespace sft;
|
||||
|
||||
const string keys =
|
||||
"{help h usage ? | | print this message }"
|
||||
"{config c | | path to configuration xml }"
|
||||
;
|
||||
|
||||
cv::CommandLineParser parser(argc, argv, keys);
|
||||
parser.about("Soft cascade training application.");
|
||||
|
||||
if (parser.has("help"))
|
||||
{
|
||||
parser.printMessage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!parser.check())
|
||||
{
|
||||
parser.printErrors();
|
||||
return 1;
|
||||
}
|
||||
|
||||
string configPath = parser.get<string>("config");
|
||||
if (configPath.empty())
|
||||
{
|
||||
std::cout << "Configuration file is missing or empty. Could not start training." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::cout << "Read configuration from file " << configPath << std::endl;
|
||||
cv::FileStorage fs(configPath, cv::FileStorage::READ);
|
||||
if(!fs.isOpened())
|
||||
{
|
||||
std::cout << "Configuration file " << configPath << " can't be opened." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
// 1. load config
|
||||
sft::Config cfg;
|
||||
fs["config"] >> cfg;
|
||||
std::cout << std::endl << "Training will be executed for configuration:" << std::endl << cfg << std::endl;
|
||||
|
||||
// 2. check and open output file
|
||||
cv::FileStorage fso(cfg.outXmlPath, cv::FileStorage::WRITE);
|
||||
if(!fso.isOpened())
|
||||
{
|
||||
std::cout << "Training stopped. Output classifier Xml file " << cfg.outXmlPath << " can't be opened." << std::endl;
|
||||
return 1;
|
||||
}
|
||||
|
||||
fso << cfg.cascadeName
|
||||
<< "{"
|
||||
<< "stageType" << "BOOST"
|
||||
<< "featureType" << cfg.featureType
|
||||
<< "octavesNum" << (int)cfg.octaves.size()
|
||||
<< "width" << cfg.modelWinSize.width
|
||||
<< "height" << cfg.modelWinSize.height
|
||||
<< "shrinkage" << cfg.shrinkage
|
||||
<< "octaves" << "[";
|
||||
|
||||
// 3. Train all octaves
|
||||
for (ivector::const_iterator it = cfg.octaves.begin(); it != cfg.octaves.end(); ++it)
|
||||
{
|
||||
// a. create random feature pool
|
||||
int nfeatures = cfg.poolSize;
|
||||
cv::Size model = cfg.model(it);
|
||||
std::cout << "Model " << model << std::endl;
|
||||
|
||||
int nchannels = (cfg.featureType == "HOG6MagLuv") ? 10: 8;
|
||||
|
||||
std::cout << "number of feature channels is " << nchannels << std::endl;
|
||||
|
||||
cv::Ptr<cv::FeaturePool> pool = cv::FeaturePool::create(model, nfeatures, nchannels);
|
||||
nfeatures = pool->size();
|
||||
|
||||
|
||||
int npositives = cfg.positives;
|
||||
int nnegatives = cfg.negatives;
|
||||
int shrinkage = cfg.shrinkage;
|
||||
cv::Rect boundingBox = cfg.bbox(it);
|
||||
std::cout << "Object bounding box" << boundingBox << std::endl;
|
||||
|
||||
typedef cv::Octave Octave;
|
||||
|
||||
cv::Ptr<cv::ChannelFeatureBuilder> builder = cv::ChannelFeatureBuilder::create(cfg.featureType);
|
||||
std::cout << "Channel builder " << builder->info()->name() << std::endl;
|
||||
cv::Ptr<Octave> boost = Octave::create(boundingBox, npositives, nnegatives, *it, shrinkage, builder);
|
||||
|
||||
std::string path = cfg.trainPath;
|
||||
sft::ScaledDataset dataset(path, *it);
|
||||
|
||||
if (boost->train(&dataset, pool, cfg.weaks, cfg.treeDepth))
|
||||
{
|
||||
CvFileStorage* fout = cvOpenFileStorage(cfg.resPath(it).c_str(), 0, CV_STORAGE_WRITE);
|
||||
boost->write(fout, cfg.cascadeName);
|
||||
|
||||
cvReleaseFileStorage( &fout);
|
||||
|
||||
cv::Mat thresholds;
|
||||
boost->setRejectThresholds(thresholds);
|
||||
|
||||
boost->write(fso, pool, thresholds);
|
||||
|
||||
cv::FileStorage tfs(("thresholds." + cfg.resPath(it)).c_str(), cv::FileStorage::WRITE);
|
||||
tfs << "thresholds" << thresholds;
|
||||
|
||||
std::cout << "Octave " << *it << " was successfully trained..." << std::endl;
|
||||
}
|
||||
}
|
||||
|
||||
fso << "]" << "}";
|
||||
fso.release();
|
||||
std::cout << "Training complete..." << std::endl;
|
||||
return 0;
|
||||
}
|
||||
@@ -1,4 +1,4 @@
|
||||
set(OPENCV_TRAINCASCADE_DEPS opencv_core opencv_ml opencv_imgproc opencv_photo opencv_objdetect opencv_highgui opencv_calib3d opencv_video opencv_features2d opencv_flann opencv_legacy)
|
||||
set(OPENCV_TRAINCASCADE_DEPS opencv_core opencv_ml opencv_imgproc opencv_photo opencv_objdetect opencv_highgui opencv_calib3d opencv_video opencv_features2d)
|
||||
ocv_check_dependencies(${OPENCV_TRAINCASCADE_DEPS})
|
||||
|
||||
if(NOT OCV_DEPENDENCIES_FOUND)
|
||||
@@ -20,7 +20,7 @@ set(traincascade_files traincascade.cpp
|
||||
|
||||
set(the_target opencv_traincascade)
|
||||
add_executable(${the_target} ${traincascade_files})
|
||||
target_link_libraries(${the_target} ${OPENCV_TRAINCASCADE_DEPS} opencv_haartraining_engine)
|
||||
target_link_libraries(${the_target} ${OPENCV_TRAINCASCADE_DEPS})
|
||||
|
||||
set_target_properties(${the_target} PROPERTIES
|
||||
DEBUG_POSTFIX "${OPENCV_DEBUG_POSTFIX}"
|
||||
|
||||
Reference in New Issue
Block a user