Commit f7e45a9ea0d41f02f684fbc5e7ef7f2ac9607398
1 parent
fe4366bc
Cleanup in core/boost
Showing
2 changed files
with
52 additions
and
81 deletions
openbr/core/boost.cpp
| 1 | +#include <opencv2/imgproc/imgproc.hpp> | |
| 2 | + | |
| 1 | 3 | #include "boost.h" |
| 2 | -#include <queue> | |
| 3 | 4 | #include "cxmisc.h" |
| 4 | 5 | |
| 5 | 6 | using namespace std; |
| ... | ... | @@ -16,9 +17,6 @@ logRatio( double val ) |
| 16 | 17 | return log( val/(1. - val) ); |
| 17 | 18 | } |
| 18 | 19 | |
| 19 | -#define CV_CMP_FLT(i,j) (i < j) | |
| 20 | -static CV_IMPLEMENT_QSORT_EX( icvSortFlt, float, CV_CMP_FLT, const float* ) | |
| 21 | - | |
| 22 | 20 | #define CV_CMP_NUM_IDX(i,j) (aux[i] < aux[j]) |
| 23 | 21 | static CV_IMPLEMENT_QSORT_EX( icvSortIntAux, int, CV_CMP_NUM_IDX, const float* ) |
| 24 | 22 | static CV_IMPLEMENT_QSORT_EX( icvSortUShAux, unsigned short, CV_CMP_NUM_IDX, const float* ) |
| ... | ... | @@ -145,7 +143,7 @@ void FeatureEvaluator::init(Representation *_representation, int _maxSampleCount |
| 145 | 143 | |
| 146 | 144 | int dx, dy; |
| 147 | 145 | Size windowSize = representation->windowSize(&dx, &dy); |
| 148 | - data.create((int)_maxSampleCount, Size(windowSize.width + dx, windowSize.height + dy).area(), CV_32SC1); | |
| 146 | + data.create((int)_maxSampleCount, (windowSize.width + dx) * (windowSize.height + dy), CV_32SC1); | |
| 149 | 147 | cls.create( (int)_maxSampleCount, 1, CV_32FC1 ); |
| 150 | 148 | } |
| 151 | 149 | |
| ... | ... | @@ -153,10 +151,9 @@ void FeatureEvaluator::setImage(const Mat &img, uchar clsLabel, int idx) |
| 153 | 151 | { |
| 154 | 152 | cls.ptr<float>(idx)[0] = clsLabel; |
| 155 | 153 | |
| 156 | - int dx, dy; | |
| 157 | - Size windowSize = representation->windowSize(&dx, &dy); | |
| 158 | - Mat pp(Size(windowSize.width + dx, windowSize.height + dy), data.type(), data.ptr<int>(idx)); | |
| 154 | + Mat pp; | |
| 159 | 155 | representation->preprocess(img, pp); |
| 156 | + pp.reshape(0, 1).copyTo(data.row(idx)); | |
| 160 | 157 | } |
| 161 | 158 | |
| 162 | 159 | //----------------------------- CascadeBoostParams ------------------------------------------------- |
| ... | ... | @@ -1031,27 +1028,22 @@ void CascadeBoostTree::split_node_data( CvDTreeNode* node ) |
| 1031 | 1028 | |
| 1032 | 1029 | //----------------------------------- CascadeBoost -------------------------------------- |
| 1033 | 1030 | |
| 1034 | -bool CascadeBoost::train( const FeatureEvaluator* _featureEvaluator, | |
| 1035 | - int _numSamples, | |
| 1036 | - int _precalcValBufSize, int _precalcIdxBufSize, | |
| 1037 | - const CascadeBoostParams& _params ) | |
| 1031 | +void CascadeBoost::train(const FeatureEvaluator* _featureEvaluator, | |
| 1032 | + int _numSamples, | |
| 1033 | + int _precalcValBufSize, int _precalcIdxBufSize, | |
| 1034 | + const CascadeBoostParams& _params) | |
| 1038 | 1035 | { |
| 1039 | - bool isTrained = false; | |
| 1040 | - CV_Assert( !data ); | |
| 1036 | + CV_Assert(!data); | |
| 1041 | 1037 | clear(); |
| 1042 | 1038 | |
| 1043 | - data = new CascadeBoostTrainData( _featureEvaluator, _numSamples, | |
| 1044 | - _precalcValBufSize, _precalcIdxBufSize, _params ); | |
| 1045 | - | |
| 1046 | - CvMemStorage *storage = cvCreateMemStorage(); | |
| 1047 | - weak = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvBoostTree*), storage ); | |
| 1048 | - storage = 0; | |
| 1039 | + data = new CascadeBoostTrainData(_featureEvaluator, _numSamples, | |
| 1040 | + _precalcValBufSize, _precalcIdxBufSize, _params); | |
| 1049 | 1041 | |
| 1050 | - set_params( _params ); | |
| 1051 | - if ( (_params.boost_type == LOGIT) || (_params.boost_type == GENTLE) ) | |
| 1042 | + set_params(_params); | |
| 1043 | + if ((_params.boost_type == LOGIT) || (_params.boost_type == GENTLE)) | |
| 1052 | 1044 | data->do_responses_copy(); |
| 1053 | 1045 | |
| 1054 | - update_weights( 0 ); | |
| 1046 | + update_weights(0); | |
| 1055 | 1047 | |
| 1056 | 1048 | cout << "+----+---------+---------+" << endl; |
| 1057 | 1049 | cout << "| N | HR | FA |" << endl; |
| ... | ... | @@ -1060,63 +1052,43 @@ bool CascadeBoost::train( const FeatureEvaluator* _featureEvaluator, |
| 1060 | 1052 | do |
| 1061 | 1053 | { |
| 1062 | 1054 | CascadeBoostTree* tree = new CascadeBoostTree; |
| 1063 | - if( !tree->train( data, subsample_mask, this ) ) | |
| 1064 | - { | |
| 1055 | + if (!tree->train( data, subsample_mask, this)) { | |
| 1065 | 1056 | delete tree; |
| 1066 | - break; | |
| 1057 | + return; | |
| 1067 | 1058 | } |
| 1068 | 1059 | |
| 1069 | 1060 | classifiers.append(tree); |
| 1070 | - cvSeqPush( weak, &tree ); | |
| 1071 | - update_weights( tree ); | |
| 1061 | + update_weights(tree); | |
| 1072 | 1062 | trim_weights(); |
| 1073 | - if( cvCountNonZero(subsample_mask) == 0 ) | |
| 1074 | - break; | |
| 1075 | - } | |
| 1076 | - while( !isErrDesired() && (weak->total < params.weak_count) ); | |
| 1077 | - | |
| 1078 | - if(weak->total > 0) | |
| 1079 | - { | |
| 1080 | - data->is_classifier = true; | |
| 1081 | - data->free_train_data(); | |
| 1082 | - isTrained = true; | |
| 1063 | + if (cvCountNonZero(subsample_mask) == 0) | |
| 1064 | + return; | |
| 1083 | 1065 | } |
| 1084 | - else | |
| 1085 | - clear(); | |
| 1066 | + while (!isErrDesired() && (classifiers.size() < params.weak_count)); | |
| 1086 | 1067 | |
| 1087 | - return isTrained; | |
| 1068 | + clear(); | |
| 1088 | 1069 | } |
| 1089 | 1070 | |
| 1090 | -float CascadeBoost::predict( int sampleIdx, bool returnSum ) const | |
| 1071 | +float CascadeBoost::predict(int sampleIdx, bool returnSum) const | |
| 1091 | 1072 | { |
| 1092 | - CV_Assert( weak ); | |
| 1093 | 1073 | double sum = 0; |
| 1074 | + foreach (const CvBoostTree *tree, classifiers) | |
| 1075 | + sum += ((CascadeBoostTree*)tree)->predict(sampleIdx)->value; | |
| 1094 | 1076 | |
| 1095 | - CvSeqReader reader; | |
| 1096 | - cvStartReadSeq( weak, &reader ); | |
| 1097 | - cvSetSeqReaderPos( &reader, 0 ); | |
| 1098 | - for( int i = 0; i < weak->total; i++ ) | |
| 1099 | - { | |
| 1100 | - CvBoostTree* wtree; | |
| 1101 | - CV_READ_SEQ_ELEM( wtree, reader ); | |
| 1102 | - sum += ((CascadeBoostTree*)wtree)->predict(sampleIdx)->value; | |
| 1103 | - } | |
| 1104 | - | |
| 1105 | - if( !returnSum ) | |
| 1077 | + if (!returnSum) | |
| 1106 | 1078 | sum = sum < threshold - CV_THRESHOLD_EPS ? 0.0 : 1.0; |
| 1107 | 1079 | return (float)sum; |
| 1108 | 1080 | } |
| 1109 | 1081 | |
| 1110 | -bool CascadeBoost::set_params( const CvBoostParams& _params ) | |
| 1082 | +bool CascadeBoost::set_params(const CvBoostParams& _params) | |
| 1111 | 1083 | { |
| 1112 | 1084 | minHitRate = ((CascadeBoostParams&)_params).minHitRate; |
| 1113 | 1085 | maxFalseAlarm = ((CascadeBoostParams&)_params).maxFalseAlarm; |
| 1114 | - return ( ( minHitRate > 0 ) && ( minHitRate < 1) && | |
| 1115 | - ( maxFalseAlarm > 0 ) && ( maxFalseAlarm < 1) && | |
| 1116 | - CvBoost::set_params( _params )); | |
| 1086 | + return (( minHitRate > 0 ) && ( minHitRate < 1) && | |
| 1087 | + (maxFalseAlarm > 0 ) && ( maxFalseAlarm < 1) && | |
| 1088 | + CvBoost::set_params(_params)); | |
| 1117 | 1089 | } |
| 1118 | 1090 | |
| 1119 | -void CascadeBoost::update_weights( CvBoostTree* tree ) | |
| 1091 | +void CascadeBoost::update_weights(CvBoostTree* tree) | |
| 1120 | 1092 | { |
| 1121 | 1093 | int n = data->sample_count; |
| 1122 | 1094 | double sumW = 0.; |
| ... | ... | @@ -1359,34 +1331,33 @@ void CascadeBoost::update_weights( CvBoostTree* tree ) |
| 1359 | 1331 | |
| 1360 | 1332 | bool CascadeBoost::isErrDesired() |
| 1361 | 1333 | { |
| 1362 | - int sCount = data->sample_count, | |
| 1363 | - numPos = 0, numNeg = 0, numFalse = 0, numPosTrue = 0; | |
| 1364 | - vector<float> eval(sCount); | |
| 1365 | - | |
| 1366 | - for( int i = 0; i < sCount; i++ ) | |
| 1367 | - if( ((CascadeBoostTrainData*)data)->featureEvaluator->getCls( i ) == 1.0F ) | |
| 1368 | - eval[numPos++] = predict( i, true ); | |
| 1369 | - icvSortFlt( &eval[0], numPos, 0 ); | |
| 1370 | - int thresholdIdx = (int)((1.0F - minHitRate) * numPos); | |
| 1371 | - threshold = eval[ thresholdIdx ]; | |
| 1372 | - numPosTrue = numPos - thresholdIdx; | |
| 1373 | - for( int i = thresholdIdx - 1; i >= 0; i--) | |
| 1374 | - if ( abs( eval[i] - threshold) < FLT_EPSILON ) | |
| 1334 | + QList<float> posVals; | |
| 1335 | + for (int i = 0; i < data->sample_count; i++) | |
| 1336 | + if (((CascadeBoostTrainData*)data)->featureEvaluator->getCls(i) == 1.0F) | |
| 1337 | + posVals.append(predict(i, true)); | |
| 1338 | + | |
| 1339 | + std::sort(posVals.begin(), posVals.end()); | |
| 1340 | + | |
| 1341 | + int thresholdIdx = (int)((1.0F - minHitRate) * posVals.size()); | |
| 1342 | + threshold = posVals[thresholdIdx]; | |
| 1343 | + | |
| 1344 | + int numPosTrue = posVals.size() - thresholdIdx; | |
| 1345 | + for (int i = thresholdIdx - 1; i >= 0; i--) | |
| 1346 | + if (abs(posVals[i] - threshold) < FLT_EPSILON) | |
| 1375 | 1347 | numPosTrue++; |
| 1376 | - float hitRate = ((float) numPosTrue) / ((float) numPos); | |
| 1348 | + float hitRate = ((float)numPosTrue) / ((float)posVals.size()); | |
| 1377 | 1349 | |
| 1378 | - for( int i = 0; i < sCount; i++ ) | |
| 1379 | - { | |
| 1380 | - if( ((CascadeBoostTrainData*)data)->featureEvaluator->getCls( i ) == 0.0F ) | |
| 1381 | - { | |
| 1350 | + int numNeg = 0, numFalse = 0; | |
| 1351 | + for (int i = 0; i < data->sample_count; i++) { | |
| 1352 | + if (((CascadeBoostTrainData*)data)->featureEvaluator->getCls(i) == 0.0F) { | |
| 1382 | 1353 | numNeg++; |
| 1383 | - if( predict( i ) ) | |
| 1354 | + if (predict(i)) | |
| 1384 | 1355 | numFalse++; |
| 1385 | 1356 | } |
| 1386 | 1357 | } |
| 1387 | - float falseAlarm = ((float) numFalse) / ((float) numNeg); | |
| 1358 | + float falseAlarm = ((float)numFalse) / ((float)numNeg); | |
| 1388 | 1359 | |
| 1389 | - cout << "|"; cout.width(4); cout << right << weak->total; | |
| 1360 | + cout << "|"; cout.width(4); cout << right << classifiers.size(); | |
| 1390 | 1361 | cout << "|"; cout.width(9); cout << right << hitRate; |
| 1391 | 1362 | cout << "|"; cout.width(9); cout << right << falseAlarm; |
| 1392 | 1363 | cout << "|" << endl; | ... | ... |
openbr/core/boost.h
| ... | ... | @@ -82,7 +82,7 @@ protected: |
| 82 | 82 | class CascadeBoost : public CvBoost |
| 83 | 83 | { |
| 84 | 84 | public: |
| 85 | - virtual bool train(const FeatureEvaluator *_featureEvaluator, | |
| 85 | + virtual void train(const FeatureEvaluator *_featureEvaluator, | |
| 86 | 86 | int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize, |
| 87 | 87 | const CascadeBoostParams &_params=CascadeBoostParams()); |
| 88 | 88 | virtual float predict( int sampleIdx, bool returnSum = false ) const; | ... | ... |