Commit f7e45a9ea0d41f02f684fbc5e7ef7f2ac9607398

Authored by Jordan Cheney
1 parent fe4366bc

Cleanup in core/boost

openbr/core/boost.cpp
  1 +#include <opencv2/imgproc/imgproc.hpp>
  2 +
1 #include "boost.h" 3 #include "boost.h"
2 -#include <queue>  
3 #include "cxmisc.h" 4 #include "cxmisc.h"
4 5
5 using namespace std; 6 using namespace std;
@@ -16,9 +17,6 @@ logRatio( double val ) @@ -16,9 +17,6 @@ logRatio( double val )
16 return log( val/(1. - val) ); 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 #define CV_CMP_NUM_IDX(i,j) (aux[i] < aux[j]) 20 #define CV_CMP_NUM_IDX(i,j) (aux[i] < aux[j])
23 static CV_IMPLEMENT_QSORT_EX( icvSortIntAux, int, CV_CMP_NUM_IDX, const float* ) 21 static CV_IMPLEMENT_QSORT_EX( icvSortIntAux, int, CV_CMP_NUM_IDX, const float* )
24 static CV_IMPLEMENT_QSORT_EX( icvSortUShAux, unsigned short, CV_CMP_NUM_IDX, const float* ) 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,7 +143,7 @@ void FeatureEvaluator::init(Representation *_representation, int _maxSampleCount
145 143
146 int dx, dy; 144 int dx, dy;
147 Size windowSize = representation->windowSize(&dx, &dy); 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 cls.create( (int)_maxSampleCount, 1, CV_32FC1 ); 147 cls.create( (int)_maxSampleCount, 1, CV_32FC1 );
150 } 148 }
151 149
@@ -153,10 +151,9 @@ void FeatureEvaluator::setImage(const Mat &amp;img, uchar clsLabel, int idx) @@ -153,10 +151,9 @@ void FeatureEvaluator::setImage(const Mat &amp;img, uchar clsLabel, int idx)
153 { 151 {
154 cls.ptr<float>(idx)[0] = clsLabel; 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 representation->preprocess(img, pp); 155 representation->preprocess(img, pp);
  156 + pp.reshape(0, 1).copyTo(data.row(idx));
160 } 157 }
161 158
162 //----------------------------- CascadeBoostParams ------------------------------------------------- 159 //----------------------------- CascadeBoostParams -------------------------------------------------
@@ -1031,27 +1028,22 @@ void CascadeBoostTree::split_node_data( CvDTreeNode* node ) @@ -1031,27 +1028,22 @@ void CascadeBoostTree::split_node_data( CvDTreeNode* node )
1031 1028
1032 //----------------------------------- CascadeBoost -------------------------------------- 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 clear(); 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 data->do_responses_copy(); 1044 data->do_responses_copy();
1053 1045
1054 - update_weights( 0 ); 1046 + update_weights(0);
1055 1047
1056 cout << "+----+---------+---------+" << endl; 1048 cout << "+----+---------+---------+" << endl;
1057 cout << "| N | HR | FA |" << endl; 1049 cout << "| N | HR | FA |" << endl;
@@ -1060,63 +1052,43 @@ bool CascadeBoost::train( const FeatureEvaluator* _featureEvaluator, @@ -1060,63 +1052,43 @@ bool CascadeBoost::train( const FeatureEvaluator* _featureEvaluator,
1060 do 1052 do
1061 { 1053 {
1062 CascadeBoostTree* tree = new CascadeBoostTree; 1054 CascadeBoostTree* tree = new CascadeBoostTree;
1063 - if( !tree->train( data, subsample_mask, this ) )  
1064 - { 1055 + if (!tree->train( data, subsample_mask, this)) {
1065 delete tree; 1056 delete tree;
1066 - break; 1057 + return;
1067 } 1058 }
1068 1059
1069 classifiers.append(tree); 1060 classifiers.append(tree);
1070 - cvSeqPush( weak, &tree );  
1071 - update_weights( tree ); 1061 + update_weights(tree);
1072 trim_weights(); 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 double sum = 0; 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 sum = sum < threshold - CV_THRESHOLD_EPS ? 0.0 : 1.0; 1078 sum = sum < threshold - CV_THRESHOLD_EPS ? 0.0 : 1.0;
1107 return (float)sum; 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 minHitRate = ((CascadeBoostParams&)_params).minHitRate; 1084 minHitRate = ((CascadeBoostParams&)_params).minHitRate;
1113 maxFalseAlarm = ((CascadeBoostParams&)_params).maxFalseAlarm; 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 int n = data->sample_count; 1093 int n = data->sample_count;
1122 double sumW = 0.; 1094 double sumW = 0.;
@@ -1359,34 +1331,33 @@ void CascadeBoost::update_weights( CvBoostTree* tree ) @@ -1359,34 +1331,33 @@ void CascadeBoost::update_weights( CvBoostTree* tree )
1359 1331
1360 bool CascadeBoost::isErrDesired() 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 numPosTrue++; 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 numNeg++; 1353 numNeg++;
1383 - if( predict( i ) ) 1354 + if (predict(i))
1384 numFalse++; 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 cout << "|"; cout.width(9); cout << right << hitRate; 1361 cout << "|"; cout.width(9); cout << right << hitRate;
1391 cout << "|"; cout.width(9); cout << right << falseAlarm; 1362 cout << "|"; cout.width(9); cout << right << falseAlarm;
1392 cout << "|" << endl; 1363 cout << "|" << endl;
openbr/core/boost.h
@@ -82,7 +82,7 @@ protected: @@ -82,7 +82,7 @@ protected:
82 class CascadeBoost : public CvBoost 82 class CascadeBoost : public CvBoost
83 { 83 {
84 public: 84 public:
85 - virtual bool train(const FeatureEvaluator *_featureEvaluator, 85 + virtual void train(const FeatureEvaluator *_featureEvaluator,
86 int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize, 86 int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize,
87 const CascadeBoostParams &_params=CascadeBoostParams()); 87 const CascadeBoostParams &_params=CascadeBoostParams());
88 virtual float predict( int sampleIdx, bool returnSum = false ) const; 88 virtual float predict( int sampleIdx, bool returnSum = false ) const;