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 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 &amp;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;
... ...