inline int predictOrderedStump( CascadeClassifier& cascade, Ptr<FeatureEvaluator> &_featureEvaluator, double& sum ) { int nodeOfs = 0, leafOfs = 0; FEval& featureEvaluator = (FEval&)*_featureEvaluator; float* cascadeLeaves = &cascade.data.leaves[0]; CascadeClassifier::Data::DTreeNode* cascadeNodes = &cascade.data.nodes[0]; CascadeClassifier::Data::Stage* cascadeStages = &cascade.data.stages[0]; int nstages = (int)cascade.data.stages.size(); for( int stageIdx = 0; stageIdx < nstages; stageIdx++ ) { CascadeClassifier::Data::Stage& stage = cascadeStages[stageIdx]; sum = 0.0; int ntrees = stage.ntrees; for( int i = 0; i < ntrees; i++, nodeOfs++, leafOfs+= 2 ) { CascadeClassifier::Data::DTreeNode& node = cascadeNodes[nodeOfs]; double value = featureEvaluator(node.featureIdx); sum += cascadeLeaves[ value < node.threshold ? leafOfs : leafOfs + 1 ]; } if( sum < stage.threshold ) return -stageIdx; } return 1; }
inline int predictOrderedStump( CascadeClassifierImpl& cascade, Ptr<FeatureEvaluator> &_featureEvaluator, double& sum ) { CV_Assert(!cascade.data.stumps.empty()); FEval& featureEvaluator = (FEval&)*_featureEvaluator; const CascadeClassifierImpl::Data::Stump* cascadeStumps = &cascade.data.stumps[0]; const CascadeClassifierImpl::Data::Stage* cascadeStages = &cascade.data.stages[0]; int nstages = (int)cascade.data.stages.size(); double tmp = 0; for( int stageIdx = 0; stageIdx < nstages; stageIdx++ ) { const CascadeClassifierImpl::Data::Stage& stage = cascadeStages[stageIdx]; tmp = 0; int ntrees = stage.ntrees; for( int i = 0; i < ntrees; i++ ) { const CascadeClassifierImpl::Data::Stump& stump = cascadeStumps[i]; double value = featureEvaluator(stump.featureIdx); tmp += value < stump.threshold ? stump.left : stump.right; } if( tmp < stage.threshold ) { sum = (double)tmp; return -stageIdx; } cascadeStumps += ntrees; } sum = (double)tmp; return 1; }
inline int predictCategoricalStump( CascadeClassifier& cascade, Ptr<FeatureEvaluator> &_featureEvaluator, double& sum ) { int nstages = (int)cascade.data.stages.size(); int nodeOfs = 0, leafOfs = 0; FEval& featureEvaluator = (FEval&)*_featureEvaluator; size_t subsetSize = (cascade.data.ncategories + 31)/32; int* cascadeSubsets = &cascade.data.subsets[0]; float* cascadeLeaves = &cascade.data.leaves[0]; CascadeClassifier::Data::DTreeNode* cascadeNodes = &cascade.data.nodes[0]; CascadeClassifier::Data::Stage* cascadeStages = &cascade.data.stages[0]; #ifdef HAVE_TEGRA_OPTIMIZATION float tmp = 0; // float accumulator -- float operations are quicker #endif for( int si = 0; si < nstages; si++ ) { CascadeClassifier::Data::Stage& stage = cascadeStages[si]; int wi, ntrees = stage.ntrees; #ifdef HAVE_TEGRA_OPTIMIZATION tmp = 0; #else sum = 0; #endif for( wi = 0; wi < ntrees; wi++ ) { CascadeClassifier::Data::DTreeNode& node = cascadeNodes[nodeOfs]; int c = featureEvaluator(node.featureIdx); const int* subset = &cascadeSubsets[nodeOfs*subsetSize]; #ifdef HAVE_TEGRA_OPTIMIZATION tmp += cascadeLeaves[ subset[c>>5] & (1 << (c & 31)) ? leafOfs : leafOfs+1]; #else sum += cascadeLeaves[ subset[c>>5] & (1 << (c & 31)) ? leafOfs : leafOfs+1]; #endif nodeOfs++; leafOfs += 2; } #ifdef HAVE_TEGRA_OPTIMIZATION if( tmp < stage.threshold ) { sum = (double)tmp; return -si; } #else if( sum < stage.threshold ) return -si; #endif } #ifdef HAVE_TEGRA_OPTIMIZATION sum = (double)tmp; #endif return 1; }
inline int predictCategoricalStump( CascadeClassifierImpl& cascade, Ptr<FeatureEvaluator> &_featureEvaluator, double& sum ) { CV_Assert(!cascade.data.stumps.empty()); int nstages = (int)cascade.data.stages.size(); FEval& featureEvaluator = (FEval&)*_featureEvaluator; size_t subsetSize = (cascade.data.ncategories + 31)/32; const int* cascadeSubsets = &cascade.data.subsets[0]; const CascadeClassifierImpl::Data::Stump* cascadeStumps = &cascade.data.stumps[0]; const CascadeClassifierImpl::Data::Stage* cascadeStages = &cascade.data.stages[0]; #ifdef HAVE_TEGRA_OPTIMIZATION float tmp = 0; // float accumulator -- float operations are quicker #else double tmp = 0; #endif for( int si = 0; si < nstages; si++ ) { const CascadeClassifierImpl::Data::Stage& stage = cascadeStages[si]; int wi, ntrees = stage.ntrees; tmp = 0; for( wi = 0; wi < ntrees; wi++ ) { const CascadeClassifierImpl::Data::Stump& stump = cascadeStumps[wi]; int c = featureEvaluator(stump.featureIdx); const int* subset = &cascadeSubsets[wi*subsetSize]; tmp += (subset[c>>5] & (1 << (c & 31))) ? stump.left : stump.right; } if( tmp < stage.threshold ) { sum = (double)tmp; return -si; } cascadeStumps += ntrees; cascadeSubsets += ntrees*subsetSize; } sum = (double)tmp; return 1; }
inline int predictCategorical( CascadeClassifierImpl& cascade, Ptr<FeatureEvaluator> &_featureEvaluator, double& sum ) { int nstages = (int)cascade.data.stages.size(); int nodeOfs = 0, leafOfs = 0; FEval& featureEvaluator = (FEval&)*_featureEvaluator; size_t subsetSize = (cascade.data.ncategories + 31)/32; int* cascadeSubsets = &cascade.data.subsets[0]; float* cascadeLeaves = &cascade.data.leaves[0]; CascadeClassifierImpl::Data::DTreeNode* cascadeNodes = &cascade.data.nodes[0]; CascadeClassifierImpl::Data::DTree* cascadeWeaks = &cascade.data.classifiers[0]; CascadeClassifierImpl::Data::Stage* cascadeStages = &cascade.data.stages[0]; for(int si = 0; si < nstages; si++ ) { CascadeClassifierImpl::Data::Stage& stage = cascadeStages[si]; int wi, ntrees = stage.ntrees; sum = 0; for( wi = 0; wi < ntrees; wi++ ) { CascadeClassifierImpl::Data::DTree& weak = cascadeWeaks[stage.first + wi]; int idx = 0, root = nodeOfs; do { CascadeClassifierImpl::Data::DTreeNode& node = cascadeNodes[root + idx]; int c = featureEvaluator(node.featureIdx); const int* subset = &cascadeSubsets[(root + idx)*subsetSize]; idx = (subset[c>>5] & (1 << (c & 31))) ? node.left : node.right; } while( idx > 0 ); sum += cascadeLeaves[leafOfs - idx]; nodeOfs += weak.nodeCount; leafOfs += weak.nodeCount + 1; } if( sum < stage.threshold ) return -si; } return 1; }
inline int predictOrdered( CascadeClassifierImpl& cascade, Ptr<FeatureEvaluator> &_featureEvaluator, double& sum ) { int nstages = (int)cascade.data.stages.size(); int nodeOfs = 0, leafOfs = 0; FEval& featureEvaluator = (FEval&)*_featureEvaluator; float* cascadeLeaves = &cascade.data.leaves[0]; CascadeClassifierImpl::Data::DTreeNode* cascadeNodes = &cascade.data.nodes[0]; CascadeClassifierImpl::Data::DTree* cascadeWeaks = &cascade.data.classifiers[0]; CascadeClassifierImpl::Data::Stage* cascadeStages = &cascade.data.stages[0]; for( int si = 0; si < nstages; si++ ) { CascadeClassifierImpl::Data::Stage& stage = cascadeStages[si]; int wi, ntrees = stage.ntrees; sum = 0; for( wi = 0; wi < ntrees; wi++ ) { CascadeClassifierImpl::Data::DTree& weak = cascadeWeaks[stage.first + wi]; int idx = 0, root = nodeOfs; do { CascadeClassifierImpl::Data::DTreeNode& node = cascadeNodes[root + idx]; double val = featureEvaluator(node.featureIdx); idx = val < node.threshold ? node.left : node.right; } while( idx > 0 ); sum += cascadeLeaves[leafOfs - idx]; nodeOfs += weak.nodeCount; leafOfs += weak.nodeCount + 1; } if( sum < stage.threshold ) return -si; } return 1; }
inline int predictForkCategoricalStump( CascadeClassifierImpl& cascade, Ptr<FeatureEvaluator> &_featureEvaluator, double& sum, int numChain ) { CV_Assert(!cascade.data.stumps.empty()); int nstages = (int)cascade.data.stages.size(), chainlong=nstages/numChain; FEval& featureEvaluator = (FEval&)*_featureEvaluator; size_t subsetSize = (cascade.data.ncategories + 31)/32; const int* cascadeSubsets = &cascade.data.subsets[0]; const CascadeClassifierImpl::Data::Stump* cascadeStumps = &cascade.data.stumps[0]; const CascadeClassifierImpl::Data::Stage* cascadeStages = &cascade.data.stages[0]; double tmp; //-------------------STRONG------------------------------------------------------ for( int si = 0; si < chainlong; si++ ) { const CascadeClassifierImpl::Data::Stage& stage = cascadeStages[si]; int wi, ntrees = stage.ntrees; tmp = 0; for( wi = 0; wi < ntrees; wi++ ) { const CascadeClassifierImpl::Data::Stump& stump = cascadeStumps[wi]; int c = featureEvaluator(stump.featureIdx); const int* subset = &cascadeSubsets[wi*subsetSize]; tmp += (subset[c>>5] & (1 << (c & 31))) ? stump.left : stump.right; } if( tmp < stage.threshold ) { sum = tmp; return -si; } cascadeStumps += ntrees; cascadeSubsets += ntrees*subsetSize; } //-----------------GROUP-------------------------------------------------------- int chainCount; for(int chain=1; chain<numChain; chain++) { chainCount=0; for(int si = chainlong*chain; si < chainlong*(chain+1); si++ ) { const CascadeClassifierImpl::Data::Stage& stage = cascadeStages[si]; int wi, ntrees = stage.ntrees; tmp = 0; for( wi = 0; wi < ntrees; wi++ ) { const CascadeClassifierImpl::Data::Stump& stump = cascadeStumps[wi]; int c = featureEvaluator(stump.featureIdx); const int* subset = &cascadeSubsets[wi*subsetSize]; tmp += (subset[c>>5] & (1 << (c & 31))) ? stump.left : stump.right; } if( tmp < stage.threshold ) { sum = tmp; for(int i=si; i<chainlong*(chain+1); i++) { stage = cascadeStages[si]; ntrees = stage.ntrees; cascadeStumps += ntrees; cascadeSubsets += ntrees*subsetSize; } break; } chainCount++; cascadeStumps += ntrees; cascadeSubsets += ntrees*subsetSize; } if(chainCount==chainlong) return 1; } sum = (double)tmp; return -nstages; }