Commit edcbc8b8fbb3e66c4e46c654d101e49e212a700d

Authored by Jordan Cheney
1 parent e4a5aed6

Clean-up and steps towards incorparting representations in the backend

openbr/core/boost.cpp
@@ -171,29 +171,6 @@ void CascadeBoostParams::write( FileStorage &fs ) const @@ -171,29 +171,6 @@ void CascadeBoostParams::write( FileStorage &fs ) const
171 fs << CC_WEAK_COUNT << weak_count; 171 fs << CC_WEAK_COUNT << weak_count;
172 } 172 }
173 173
174 -// ----------------------------- Compatibility ----------------------------------  
175 -  
176 -BoostBRCompatibility::BoostBRCompatibility(Representation *_representation, int _numSamples)  
177 -{  
178 - representation = _representation;  
179 - data.create(_numSamples, representation->windowSize().area(), CV_32SC1);  
180 - cls.create(_numSamples, 1, CV_32FC1);  
181 -}  
182 -  
183 -void BoostBRCompatibility::setImage(const Mat &img, uchar clsLabel, int idx)  
184 -{  
185 - cls.ptr<float>(idx)[0] = clsLabel;  
186 - Mat preprocessed = representation->preprocess(img);  
187 - Mat copier(representation->windowSize(), CV_32FC1, data.ptr<int>(idx));  
188 - preprocessed.copyTo(copier);  
189 -}  
190 -  
191 -float BoostBRCompatibility::operator ()(int featureIdx, int sampleIdx) const  
192 -{  
193 - return representation->evaluate(data.row(sampleIdx).reshape(0, representation->windowSize().height),  
194 - QList<int>() << featureIdx).ptr<float>()[0];  
195 -}  
196 -  
197 //---------------------------- CascadeBoostTrainData ----------------------------- 174 //---------------------------- CascadeBoostTrainData -----------------------------
198 175
199 CvDTreeNode* CascadeBoostTrainData::subsample_data( const CvMat* _subsample_idx ) 176 CvDTreeNode* CascadeBoostTrainData::subsample_data( const CvMat* _subsample_idx )
@@ -361,18 +338,18 @@ CvDTreeNode* CascadeBoostTrainData::subsample_data( const CvMat* _subsample_idx @@ -361,18 +338,18 @@ CvDTreeNode* CascadeBoostTrainData::subsample_data( const CvMat* _subsample_idx
361 return root; 338 return root;
362 } 339 }
363 340
364 -CascadeBoostTrainData::CascadeBoostTrainData( const BoostBRCompatibility* _compat, 341 +CascadeBoostTrainData::CascadeBoostTrainData( const FeatureEvaluator* _featureEvaluator,
365 const CvDTreeParams& _params ) 342 const CvDTreeParams& _params )
366 { 343 {
367 is_classifier = true; 344 is_classifier = true;
368 - var_all = var_count = _compat->numFeatures(); 345 + var_all = var_count = (int)_featureEvaluator->getNumFeatures();
369 346
370 - compat = _compat; 347 + featureEvaluator = _featureEvaluator;
371 shared = true; 348 shared = true;
372 set_params( _params ); 349 set_params( _params );
373 - max_c_count = MAX( 2, compat->maxCatCount() ); 350 + max_c_count = MAX( 2, featureEvaluator->getMaxCatCount() );
374 var_type = cvCreateMat( 1, var_count + 2, CV_32SC1 ); 351 var_type = cvCreateMat( 1, var_count + 2, CV_32SC1 );
375 - if ( compat->maxCatCount() > 0 ) 352 + if ( featureEvaluator->getMaxCatCount() > 0 )
376 { 353 {
377 numPrecalcIdx = 0; 354 numPrecalcIdx = 0;
378 cat_var_count = var_count; 355 cat_var_count = var_count;
@@ -402,15 +379,15 @@ CascadeBoostTrainData::CascadeBoostTrainData( const BoostBRCompatibility* _compa @@ -402,15 +379,15 @@ CascadeBoostTrainData::CascadeBoostTrainData( const BoostBRCompatibility* _compa
402 split_heap = cvCreateSet( 0, sizeof(split_heap[0]), maxSplitSize, tree_storage ); 379 split_heap = cvCreateSet( 0, sizeof(split_heap[0]), maxSplitSize, tree_storage );
403 } 380 }
404 381
405 -CascadeBoostTrainData::CascadeBoostTrainData( const BoostBRCompatibility* _compat, 382 +CascadeBoostTrainData::CascadeBoostTrainData( const FeatureEvaluator* _featureEvaluator,
406 int _numSamples, 383 int _numSamples,
407 int _precalcValBufSize, int _precalcIdxBufSize, 384 int _precalcValBufSize, int _precalcIdxBufSize,
408 const CvDTreeParams& _params ) 385 const CvDTreeParams& _params )
409 { 386 {
410 - setData( _compat, _numSamples, _precalcValBufSize, _precalcIdxBufSize, _params ); 387 + setData( _featureEvaluator, _numSamples, _precalcValBufSize, _precalcIdxBufSize, _params );
411 } 388 }
412 389
413 -void CascadeBoostTrainData::setData( const BoostBRCompatibility* _compat, 390 +void CascadeBoostTrainData::setData( const FeatureEvaluator* _featureEvaluator,
414 int _numSamples, 391 int _numSamples,
415 int _precalcValBufSize, int _precalcIdxBufSize, 392 int _precalcValBufSize, int _precalcIdxBufSize,
416 const CvDTreeParams& _params ) 393 const CvDTreeParams& _params )
@@ -421,7 +398,6 @@ void CascadeBoostTrainData::setData( const BoostBRCompatibility* _compat, @@ -421,7 +398,6 @@ void CascadeBoostTrainData::setData( const BoostBRCompatibility* _compat,
421 uint64 effective_buf_size = 0; 398 uint64 effective_buf_size = 0;
422 int effective_buf_height = 0, effective_buf_width = 0; 399 int effective_buf_height = 0, effective_buf_width = 0;
423 400
424 -  
425 clear(); 401 clear();
426 shared = true; 402 shared = true;
427 have_labels = true; 403 have_labels = true;
@@ -432,17 +408,18 @@ void CascadeBoostTrainData::setData( const BoostBRCompatibility* _compat, @@ -432,17 +408,18 @@ void CascadeBoostTrainData::setData( const BoostBRCompatibility* _compat,
432 408
433 set_params( _params ); 409 set_params( _params );
434 410
435 - compat = _compat; 411 + CV_Assert( _featureEvaluator );
  412 + featureEvaluator = _featureEvaluator;
436 413
437 - max_c_count = MAX( 2, compat->maxCatCount() );  
438 - _resp = compat->getCls(); 414 + max_c_count = MAX( 2, featureEvaluator->getMaxCatCount() );
  415 + _resp = featureEvaluator->getCls();
439 responses = &_resp; 416 responses = &_resp;
440 // TODO: check responses: elements must be 0 or 1 417 // TODO: check responses: elements must be 0 or 1
441 418
442 if( _precalcValBufSize < 0 || _precalcIdxBufSize < 0) 419 if( _precalcValBufSize < 0 || _precalcIdxBufSize < 0)
443 CV_Error( CV_StsOutOfRange, "_numPrecalcVal and _numPrecalcIdx must be positive or 0" ); 420 CV_Error( CV_StsOutOfRange, "_numPrecalcVal and _numPrecalcIdx must be positive or 0" );
444 421
445 - var_count = var_all = compat->numFeatures(); 422 + var_count = var_all = featureEvaluator->getNumFeatures() * featureEvaluator->getFeatureSize();
446 sample_count = _numSamples; 423 sample_count = _numSamples;
447 424
448 is_buf_16u = false; 425 is_buf_16u = false;
@@ -457,7 +434,7 @@ void CascadeBoostTrainData::setData( const BoostBRCompatibility* _compat, @@ -457,7 +434,7 @@ void CascadeBoostTrainData::setData( const BoostBRCompatibility* _compat,
457 434
458 valCache.create( numPrecalcVal, sample_count, CV_32FC1 ); 435 valCache.create( numPrecalcVal, sample_count, CV_32FC1 );
459 var_type = cvCreateMat( 1, var_count + 2, CV_32SC1 ); 436 var_type = cvCreateMat( 1, var_count + 2, CV_32SC1 );
460 - if ( compat->maxCatCount() > 0 ) 437 + if ( featureEvaluator->getMaxCatCount() > 0 )
461 { 438 {
462 numPrecalcIdx = 0; 439 numPrecalcIdx = 0;
463 cat_var_count = var_count; 440 cat_var_count = var_count;
@@ -623,7 +600,7 @@ void CascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ord @@ -623,7 +600,7 @@ void CascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ord
623 { 600 {
624 int idx = (*sortedIndices)[i]; 601 int idx = (*sortedIndices)[i];
625 idx = sampleIndices[idx]; 602 idx = sampleIndices[idx];
626 - ordValuesBuf[i] = (*compat)( vi, idx); 603 + ordValuesBuf[i] = (*featureEvaluator)( vi, idx);
627 } 604 }
628 } 605 }
629 } 606 }
@@ -645,7 +622,7 @@ void CascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ord @@ -645,7 +622,7 @@ void CascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ord
645 for( int i = 0; i < nodeSampleCount; i++ ) 622 for( int i = 0; i < nodeSampleCount; i++ )
646 { 623 {
647 sortedIndicesBuf[i] = i; 624 sortedIndicesBuf[i] = i;
648 - sampleValues[i] = (*compat)( vi, sampleIndices[i]); 625 + sampleValues[i] = (*featureEvaluator)( vi, sampleIndices[i]);
649 } 626 }
650 } 627 }
651 icvSortIntAux( sortedIndicesBuf, nodeSampleCount, &sampleValues[0] ); 628 icvSortIntAux( sortedIndicesBuf, nodeSampleCount, &sampleValues[0] );
@@ -673,7 +650,7 @@ const int* CascadeBoostTrainData::get_cat_var_data( CvDTreeNode* n, int vi, int* @@ -673,7 +650,7 @@ const int* CascadeBoostTrainData::get_cat_var_data( CvDTreeNode* n, int vi, int*
673 if( vi >= numPrecalcVal && vi < var_count ) 650 if( vi >= numPrecalcVal && vi < var_count )
674 { 651 {
675 for( int i = 0; i < nodeSampleCount; i++ ) 652 for( int i = 0; i < nodeSampleCount; i++ )
676 - catValuesBuf[i] = (int)(*compat)( vi, sampleIndices[i] ); 653 + catValuesBuf[i] = (int)(*featureEvaluator)( vi, sampleIndices[i] );
677 } 654 }
678 else 655 else
679 { 656 {
@@ -688,15 +665,14 @@ float CascadeBoostTrainData::getVarValue( int vi, int si ) @@ -688,15 +665,14 @@ float CascadeBoostTrainData::getVarValue( int vi, int si )
688 { 665 {
689 if ( vi < numPrecalcVal && !valCache.empty() ) 666 if ( vi < numPrecalcVal && !valCache.empty() )
690 return valCache.at<float>( vi, si ); 667 return valCache.at<float>( vi, si );
691 - return (*compat)( vi, si ); 668 + return (*featureEvaluator)( vi, si );
692 } 669 }
693 670
694 -  
695 struct FeatureIdxOnlyPrecalc : ParallelLoopBody 671 struct FeatureIdxOnlyPrecalc : ParallelLoopBody
696 { 672 {
697 - FeatureIdxOnlyPrecalc( const BoostBRCompatibility* _compat, CvMat* _buf, int _sample_count, bool _is_buf_16u ) 673 + FeatureIdxOnlyPrecalc( const FeatureEvaluator* _featureEvaluator, CvMat* _buf, int _sample_count, bool _is_buf_16u )
698 { 674 {
699 - compat = _compat; 675 + featureEvaluator = _featureEvaluator;
700 sample_count = _sample_count; 676 sample_count = _sample_count;
701 udst = (unsigned short*)_buf->data.s; 677 udst = (unsigned short*)_buf->data.s;
702 idst = _buf->data.i; 678 idst = _buf->data.i;
@@ -710,7 +686,7 @@ struct FeatureIdxOnlyPrecalc : ParallelLoopBody @@ -710,7 +686,7 @@ struct FeatureIdxOnlyPrecalc : ParallelLoopBody
710 { 686 {
711 for( int si = 0; si < sample_count; si++ ) 687 for( int si = 0; si < sample_count; si++ )
712 { 688 {
713 - valCachePtr[si] = (*compat)( fi, si ); 689 + valCachePtr[si] = (*featureEvaluator)( fi, si );
714 if ( is_buf_16u ) 690 if ( is_buf_16u )
715 *(udst + fi*sample_count + si) = (unsigned short)si; 691 *(udst + fi*sample_count + si) = (unsigned short)si;
716 else 692 else
@@ -722,7 +698,7 @@ struct FeatureIdxOnlyPrecalc : ParallelLoopBody @@ -722,7 +698,7 @@ struct FeatureIdxOnlyPrecalc : ParallelLoopBody
722 icvSortIntAux( idst + fi*sample_count, sample_count, valCachePtr ); 698 icvSortIntAux( idst + fi*sample_count, sample_count, valCachePtr );
723 } 699 }
724 } 700 }
725 - const BoostBRCompatibility* compat; 701 + const FeatureEvaluator* featureEvaluator;
726 int sample_count; 702 int sample_count;
727 int* idst; 703 int* idst;
728 unsigned short* udst; 704 unsigned short* udst;
@@ -731,9 +707,9 @@ struct FeatureIdxOnlyPrecalc : ParallelLoopBody @@ -731,9 +707,9 @@ struct FeatureIdxOnlyPrecalc : ParallelLoopBody
731 707
732 struct FeatureValAndIdxPrecalc : ParallelLoopBody 708 struct FeatureValAndIdxPrecalc : ParallelLoopBody
733 { 709 {
734 - FeatureValAndIdxPrecalc( const BoostBRCompatibility* _compat, CvMat* _buf, Mat* _valCache, int _sample_count, bool _is_buf_16u ) 710 + FeatureValAndIdxPrecalc( const FeatureEvaluator* _featureEvaluator, CvMat* _buf, Mat* _valCache, int _sample_count, bool _is_buf_16u )
735 { 711 {
736 - compat = _compat; 712 + featureEvaluator = _featureEvaluator;
737 valCache = _valCache; 713 valCache = _valCache;
738 sample_count = _sample_count; 714 sample_count = _sample_count;
739 udst = (unsigned short*)_buf->data.s; 715 udst = (unsigned short*)_buf->data.s;
@@ -746,7 +722,7 @@ struct FeatureValAndIdxPrecalc : ParallelLoopBody @@ -746,7 +722,7 @@ struct FeatureValAndIdxPrecalc : ParallelLoopBody
746 { 722 {
747 for( int si = 0; si < sample_count; si++ ) 723 for( int si = 0; si < sample_count; si++ )
748 { 724 {
749 - valCache->at<float>(fi,si) = (*compat)( fi, si ); 725 + valCache->at<float>(fi,si) = (*featureEvaluator)( fi, si );
750 if ( is_buf_16u ) 726 if ( is_buf_16u )
751 *(udst + fi*sample_count + si) = (unsigned short)si; 727 *(udst + fi*sample_count + si) = (unsigned short)si;
752 else 728 else
@@ -758,7 +734,7 @@ struct FeatureValAndIdxPrecalc : ParallelLoopBody @@ -758,7 +734,7 @@ struct FeatureValAndIdxPrecalc : ParallelLoopBody
758 icvSortIntAux( idst + fi*sample_count, sample_count, valCache->ptr<float>(fi) ); 734 icvSortIntAux( idst + fi*sample_count, sample_count, valCache->ptr<float>(fi) );
759 } 735 }
760 } 736 }
761 - const BoostBRCompatibility* compat; 737 + const FeatureEvaluator* featureEvaluator;
762 Mat* valCache; 738 Mat* valCache;
763 int sample_count; 739 int sample_count;
764 int* idst; 740 int* idst;
@@ -768,9 +744,9 @@ struct FeatureValAndIdxPrecalc : ParallelLoopBody @@ -768,9 +744,9 @@ struct FeatureValAndIdxPrecalc : ParallelLoopBody
768 744
769 struct FeatureValOnlyPrecalc : ParallelLoopBody 745 struct FeatureValOnlyPrecalc : ParallelLoopBody
770 { 746 {
771 - FeatureValOnlyPrecalc( const BoostBRCompatibility* _compat, Mat* _valCache, int _sample_count ) 747 + FeatureValOnlyPrecalc( const FeatureEvaluator* _featureEvaluator, Mat* _valCache, int _sample_count )
772 { 748 {
773 - compat = _compat; 749 + featureEvaluator = _featureEvaluator;
774 valCache = _valCache; 750 valCache = _valCache;
775 sample_count = _sample_count; 751 sample_count = _sample_count;
776 } 752 }
@@ -778,9 +754,9 @@ struct FeatureValOnlyPrecalc : ParallelLoopBody @@ -778,9 +754,9 @@ struct FeatureValOnlyPrecalc : ParallelLoopBody
778 { 754 {
779 for ( int fi = range.start; fi < range.end; fi++) 755 for ( int fi = range.start; fi < range.end; fi++)
780 for( int si = 0; si < sample_count; si++ ) 756 for( int si = 0; si < sample_count; si++ )
781 - valCache->at<float>(fi,si) = (*compat)( fi, si ); 757 + valCache->at<float>(fi,si) = (*featureEvaluator)( fi, si );
782 } 758 }
783 - const BoostBRCompatibility* compat; 759 + const FeatureEvaluator* featureEvaluator;
784 Mat* valCache; 760 Mat* valCache;
785 int sample_count; 761 int sample_count;
786 }; 762 };
@@ -791,11 +767,11 @@ void CascadeBoostTrainData::precalculate() @@ -791,11 +767,11 @@ void CascadeBoostTrainData::precalculate()
791 767
792 double proctime = -TIME( 0 ); 768 double proctime = -TIME( 0 );
793 parallel_for_( Range(numPrecalcVal, numPrecalcIdx), 769 parallel_for_( Range(numPrecalcVal, numPrecalcIdx),
794 - FeatureIdxOnlyPrecalc(compat, buf, sample_count, is_buf_16u!=0) ); 770 + FeatureIdxOnlyPrecalc(featureEvaluator, buf, sample_count, is_buf_16u!=0) );
795 parallel_for_( Range(0, minNum), 771 parallel_for_( Range(0, minNum),
796 - FeatureValAndIdxPrecalc(compat, buf, &valCache, sample_count, is_buf_16u!=0) ); 772 + FeatureValAndIdxPrecalc(featureEvaluator, buf, &valCache, sample_count, is_buf_16u!=0) );
797 parallel_for_( Range(minNum, numPrecalcVal), 773 parallel_for_( Range(minNum, numPrecalcVal),
798 - FeatureValOnlyPrecalc(compat, &valCache, sample_count) ); 774 + FeatureValOnlyPrecalc(featureEvaluator, &valCache, sample_count) );
799 cout << "Precalculation time: " << (proctime + TIME( 0 )) << endl; 775 cout << "Precalculation time: " << (proctime + TIME( 0 )) << endl;
800 } 776 }
801 777
@@ -807,7 +783,7 @@ CvDTreeNode* CascadeBoostTree::predict( int sampleIdx ) const @@ -807,7 +783,7 @@ CvDTreeNode* CascadeBoostTree::predict( int sampleIdx ) const
807 if( !node ) 783 if( !node )
808 CV_Error( CV_StsError, "The tree has not been trained yet" ); 784 CV_Error( CV_StsError, "The tree has not been trained yet" );
809 785
810 - if ( ((CascadeBoostTrainData*)data)->compat->maxCatCount() == 0 ) // ordered 786 + if ( ((CascadeBoostTrainData*)data)->featureEvaluator->getMaxCatCount() == 0 ) // ordered
811 { 787 {
812 while( node->left ) 788 while( node->left )
813 { 789 {
@@ -830,7 +806,7 @@ CvDTreeNode* CascadeBoostTree::predict( int sampleIdx ) const @@ -830,7 +806,7 @@ CvDTreeNode* CascadeBoostTree::predict( int sampleIdx ) const
830 806
831 void CascadeBoostTree::write( FileStorage &fs, const Mat& featureMap ) 807 void CascadeBoostTree::write( FileStorage &fs, const Mat& featureMap )
832 { 808 {
833 - int maxCatCount = ((CascadeBoostTrainData*)data)->compat->maxCatCount(); 809 + int maxCatCount = ((CascadeBoostTrainData*)data)->featureEvaluator->getMaxCatCount();
834 int subsetN = (maxCatCount + 31)/32; 810 int subsetN = (maxCatCount + 31)/32;
835 queue<CvDTreeNode*> internalNodesQueue; 811 queue<CvDTreeNode*> internalNodesQueue;
836 int size = (int)pow( 2.f, (float)ensemble->get_params().max_depth); 812 int size = (int)pow( 2.f, (float)ensemble->get_params().max_depth);
@@ -1123,7 +1099,7 @@ void CascadeBoostTree::markFeaturesInMap( Mat&amp; featureMap ) @@ -1123,7 +1099,7 @@ void CascadeBoostTree::markFeaturesInMap( Mat&amp; featureMap )
1123 1099
1124 //----------------------------------- CascadeBoost -------------------------------------- 1100 //----------------------------------- CascadeBoost --------------------------------------
1125 1101
1126 -bool CascadeBoost::train( const BoostBRCompatibility* _compat, 1102 +bool CascadeBoost::train( const FeatureEvaluator* _featureEvaluator,
1127 int _numSamples, 1103 int _numSamples,
1128 int _precalcValBufSize, int _precalcIdxBufSize, 1104 int _precalcValBufSize, int _precalcIdxBufSize,
1129 const CascadeBoostParams& _params ) 1105 const CascadeBoostParams& _params )
@@ -1132,7 +1108,7 @@ bool CascadeBoost::train( const BoostBRCompatibility* _compat, @@ -1132,7 +1108,7 @@ bool CascadeBoost::train( const BoostBRCompatibility* _compat,
1132 CV_Assert( !data ); 1108 CV_Assert( !data );
1133 clear(); 1109 clear();
1134 1110
1135 - data = new CascadeBoostTrainData( _compat, _numSamples, 1111 + data = new CascadeBoostTrainData( _featureEvaluator, _numSamples,
1136 _precalcValBufSize, _precalcIdxBufSize, _params ); 1112 _precalcValBufSize, _precalcIdxBufSize, _params );
1137 1113
1138 CvMemStorage *storage = cvCreateMemStorage(); 1114 CvMemStorage *storage = cvCreateMemStorage();
@@ -1154,7 +1130,6 @@ bool CascadeBoost::train( const BoostBRCompatibility* _compat, @@ -1154,7 +1130,6 @@ bool CascadeBoost::train( const BoostBRCompatibility* _compat,
1154 CascadeBoostTree* tree = new CascadeBoostTree; 1130 CascadeBoostTree* tree = new CascadeBoostTree;
1155 if( !tree->train( data, subsample_mask, this ) ) 1131 if( !tree->train( data, subsample_mask, this ) )
1156 { 1132 {
1157 - qDebug("Couldn't train tree");  
1158 delete tree; 1133 delete tree;
1159 break; 1134 break;
1160 } 1135 }
@@ -1454,7 +1429,7 @@ bool CascadeBoost::isErrDesired() @@ -1454,7 +1429,7 @@ bool CascadeBoost::isErrDesired()
1454 vector<float> eval(sCount); 1429 vector<float> eval(sCount);
1455 1430
1456 for( int i = 0; i < sCount; i++ ) 1431 for( int i = 0; i < sCount; i++ )
1457 - if( ((CascadeBoostTrainData*)data)->compat->getCls( i ) == 1.0F ) 1432 + if( ((CascadeBoostTrainData*)data)->featureEvaluator->getCls( i ) == 1.0F )
1458 eval[numPos++] = predict( i, true ); 1433 eval[numPos++] = predict( i, true );
1459 icvSortFlt( &eval[0], numPos, 0 ); 1434 icvSortFlt( &eval[0], numPos, 0 );
1460 int thresholdIdx = (int)((1.0F - minHitRate) * numPos); 1435 int thresholdIdx = (int)((1.0F - minHitRate) * numPos);
@@ -1467,7 +1442,7 @@ bool CascadeBoost::isErrDesired() @@ -1467,7 +1442,7 @@ bool CascadeBoost::isErrDesired()
1467 1442
1468 for( int i = 0; i < sCount; i++ ) 1443 for( int i = 0; i < sCount; i++ )
1469 { 1444 {
1470 - if( ((CascadeBoostTrainData*)data)->compat->getCls( i ) == 0.0F ) 1445 + if( ((CascadeBoostTrainData*)data)->featureEvaluator->getCls( i ) == 0.0F )
1471 { 1446 {
1472 numNeg++; 1447 numNeg++;
1473 if( predict( i ) ) 1448 if( predict( i ) )
openbr/core/boost.h
@@ -13,52 +13,36 @@ struct CascadeBoostParams : CvBoostParams @@ -13,52 +13,36 @@ struct CascadeBoostParams : CvBoostParams
13 float maxFalseAlarm; 13 float maxFalseAlarm;
14 14
15 CascadeBoostParams(); 15 CascadeBoostParams();
16 - CascadeBoostParams( int _boostType, float _minHitRate, float _maxFalseAlarm,  
17 - double _weightTrimRate, int _maxDepth, int _maxWeakCount ); 16 + CascadeBoostParams(int _boostType, float _minHitRate, float _maxFalseAlarm,
  17 + double _weightTrimRate, int _maxDepth, int _maxWeakCount);
18 virtual ~CascadeBoostParams() {} 18 virtual ~CascadeBoostParams() {}
19 void write( cv::FileStorage &fs ) const; 19 void write( cv::FileStorage &fs ) const;
20 }; 20 };
21 21
22 -struct BoostBRCompatibility  
23 -{  
24 - BoostBRCompatibility(Representation *_representation, int _numSamples);  
25 - void setImage(const cv::Mat &img, uchar clsLabel, int idx);  
26 - float operator()(int featureIdx, int sampleIdx) const;  
27 - const cv::Mat &getCls() const { return cls; }  
28 - float getCls(int idx) const { return cls.at<float>(idx, 0); }  
29 -  
30 - int numFeatures() const { return representation->numFeatures(); }  
31 - int maxCatCount() const { return 256; }  
32 -  
33 - Representation *representation;  
34 - cv::Mat data, cls;  
35 -};  
36 -  
37 struct CascadeBoostTrainData : CvDTreeTrainData 22 struct CascadeBoostTrainData : CvDTreeTrainData
38 { 23 {
39 - CascadeBoostTrainData( const BoostBRCompatibility* _compat,  
40 - const CvDTreeParams& _params );  
41 - CascadeBoostTrainData( const BoostBRCompatibility* _compat,  
42 - int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize,  
43 - const CvDTreeParams& _params = CvDTreeParams() );  
44 - virtual void setData( const BoostBRCompatibility* _compat, 24 + CascadeBoostTrainData(const FeatureEvaluator* _featureEvaluator, const CvDTreeParams& _params);
  25 + CascadeBoostTrainData(const FeatureEvaluator* _featureEvaluator,
45 int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize, 26 int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize,
46 - const CvDTreeParams& _params=CvDTreeParams() ); 27 + const CvDTreeParams& _params = CvDTreeParams());
  28 + virtual void setData(const FeatureEvaluator* _featureEvaluator,
  29 + int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize,
  30 + const CvDTreeParams& _params=CvDTreeParams());
47 void precalculate(); 31 void precalculate();
48 32
49 - virtual CvDTreeNode* subsample_data( const CvMat* _subsample_idx ); 33 + virtual CvDTreeNode* subsample_data(const CvMat* _subsample_idx);
50 34
51 - virtual const int* get_class_labels( CvDTreeNode* n, int* labelsBuf );  
52 - virtual const int* get_cv_labels( CvDTreeNode* n, int* labelsBuf);  
53 - virtual const int* get_sample_indices( CvDTreeNode* n, int* indicesBuf ); 35 + virtual const int* get_class_labels(CvDTreeNode* n, int* labelsBuf);
  36 + virtual const int* get_cv_labels(CvDTreeNode* n, int* labelsBuf);
  37 + virtual const int* get_sample_indices(CvDTreeNode* n, int* indicesBuf);
54 38
55 - virtual void get_ord_var_data( CvDTreeNode* n, int vi, float* ordValuesBuf, int* sortedIndicesBuf,  
56 - const float** ordValues, const int** sortedIndices, int* sampleIndicesBuf );  
57 - virtual const int* get_cat_var_data( CvDTreeNode* n, int vi, int* catValuesBuf );  
58 - virtual float getVarValue( int vi, int si ); 39 + virtual void get_ord_var_data(CvDTreeNode* n, int vi, float* ordValuesBuf, int* sortedIndicesBuf,
  40 + const float** ordValues, const int** sortedIndices, int* sampleIndicesBuf);
  41 + virtual const int* get_cat_var_data(CvDTreeNode* n, int vi, int* catValuesBuf);
  42 + virtual float getVarValue(int vi, int si);
59 virtual void free_train_data(); 43 virtual void free_train_data();
60 44
61 - const BoostBRCompatibility* compat; 45 + const FeatureEvaluator* featureEvaluator;
62 cv::Mat valCache; // precalculated feature values (CV_32FC1) 46 cv::Mat valCache; // precalculated feature values (CV_32FC1)
63 CvMat _resp; // for casting 47 CvMat _resp; // for casting
64 int numPrecalcVal, numPrecalcIdx; 48 int numPrecalcVal, numPrecalcIdx;
@@ -67,27 +51,29 @@ struct CascadeBoostTrainData : CvDTreeTrainData @@ -67,27 +51,29 @@ struct CascadeBoostTrainData : CvDTreeTrainData
67 class CascadeBoostTree : public CvBoostTree 51 class CascadeBoostTree : public CvBoostTree
68 { 52 {
69 public: 53 public:
70 - virtual CvDTreeNode* predict( int sampleIdx ) const;  
71 - void write( cv::FileStorage &fs, const cv::Mat& featureMap );  
72 - void markFeaturesInMap( cv::Mat& featureMap ); 54 + virtual CvDTreeNode* predict(int sampleIdx) const;
  55 + void write(cv::FileStorage &fs, const cv::Mat& featureMap);
  56 + void markFeaturesInMap(cv::Mat& featureMap);
  57 +
73 protected: 58 protected:
74 - virtual void split_node_data( CvDTreeNode* n ); 59 + virtual void split_node_data(CvDTreeNode* n);
75 }; 60 };
76 61
77 class CascadeBoost : public CvBoost 62 class CascadeBoost : public CvBoost
78 { 63 {
79 public: 64 public:
80 - virtual bool train( const BoostBRCompatibility* _compat,  
81 - int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize,  
82 - const CascadeBoostParams& _params=CascadeBoostParams() ); 65 + virtual bool train(const FeatureEvaluator *_featureEvaluator,
  66 + int _numSamples, int _precalcValBufSize, int _precalcIdxBufSize,
  67 + const CascadeBoostParams &_params=CascadeBoostParams());
83 virtual float predict( int sampleIdx, bool returnSum = false ) const; 68 virtual float predict( int sampleIdx, bool returnSum = false ) const;
84 69
85 float getThreshold() const { return threshold; } 70 float getThreshold() const { return threshold; }
86 - void write( cv::FileStorage &fs, const cv::Mat& featureMap ) const;  
87 - void markUsedFeaturesInMap( cv::Mat& featureMap ); 71 + void write(cv::FileStorage &fs, const cv::Mat& featureMap) const;
  72 + void markUsedFeaturesInMap(cv::Mat& featureMap);
  73 +
88 protected: 74 protected:
89 - virtual bool set_params( const CvBoostParams& _params );  
90 - virtual void update_weights( CvBoostTree* tree ); 75 + virtual bool set_params(const CvBoostParams& _params);
  76 + virtual void update_weights(CvBoostTree* tree);
91 virtual bool isErrDesired(); 77 virtual bool isErrDesired();
92 78
93 float threshold; 79 float threshold;
openbr/core/cascade.cpp
@@ -3,17 +3,17 @@ @@ -3,17 +3,17 @@
3 #include <iostream> 3 #include <iostream>
4 #include <fstream> 4 #include <fstream>
5 5
  6 +using namespace std;
6 using namespace br; 7 using namespace br;
7 using namespace cv; 8 using namespace cv;
8 9
9 -bool CascadeImageReader::create( const QList<Mat> &_posImages, const QList<Mat> &_negImages, Size _winSize ) 10 +bool CascadeImageReader::create(const QList<Mat> &_posImages, const QList<Mat> &_negImages, Size _winSize)
10 { 11 {
11 posImages = _posImages; 12 posImages = _posImages;
12 negImages = _negImages; 13 negImages = _negImages;
13 winSize = _winSize; 14 winSize = _winSize;
14 15
15 - posIdx = 0; negIdx = 0;  
16 - round = 0; 16 + posIdx = negIdx = 0;
17 17
18 src.create( 0, 0 , CV_8UC1 ); 18 src.create( 0, 0 , CV_8UC1 );
19 img.create( 0, 0, CV_8UC1 ); 19 img.create( 0, 0, CV_8UC1 );
@@ -21,22 +21,32 @@ bool CascadeImageReader::create( const QList&lt;Mat&gt; &amp;_posImages, const QList&lt;Mat&gt; @@ -21,22 +21,32 @@ bool CascadeImageReader::create( const QList&lt;Mat&gt; &amp;_posImages, const QList&lt;Mat&gt;
21 scale = 1.0F; 21 scale = 1.0F;
22 scaleFactor = 1.4142135623730950488016887242097F; 22 scaleFactor = 1.4142135623730950488016887242097F;
23 stepFactor = 0.5F; 23 stepFactor = 0.5F;
  24 + round = 0;
24 25
25 return true; 26 return true;
26 } 27 }
27 28
28 bool CascadeImageReader::nextNeg() 29 bool CascadeImageReader::nextNeg()
29 { 30 {
30 - src = negImages[negIdx++];  
31 -  
32 - round += negIdx / negImages.size();  
33 - round = round % (winSize.width * winSize.height);  
34 - negIdx %= negImages.size();  
35 -  
36 - offset.x = std::min( (int)round % winSize.width, src.cols - winSize.width );  
37 - offset.y = std::min( (int)round / winSize.width, src.rows - winSize.height ); 31 + Point _offset = Point(0,0);
  32 + size_t count = negImages.size();
  33 + for (size_t i = 0; i < count; i++) {
  34 + src = negImages[negIdx++];
  35 + if( src.empty() )
  36 + continue;
  37 + round += negIdx / count;
  38 + round = round % (winSize.width * winSize.height);
  39 + negIdx %= count;
  40 +
  41 + _offset.x = std::min( (int)round % winSize.width, src.cols - winSize.width );
  42 + _offset.y = std::min( (int)round / winSize.width, src.rows - winSize.height );
  43 + if( !src.empty() && src.type() == CV_8UC1 && _offset.x >= 0 && _offset.y >= 0 )
  44 + break;
  45 + }
38 46
39 - point = offset; 47 + if( src.empty() )
  48 + return false; // no appropriate image
  49 + point = offset = _offset;
40 scale = max( ((float)winSize.width + point.x) / ((float)src.cols), 50 scale = max( ((float)winSize.width + point.x) / ((float)src.cols),
41 ((float)winSize.height + point.y) / ((float)src.rows) ); 51 ((float)winSize.height + point.y) / ((float)src.rows) );
42 52
@@ -56,7 +66,8 @@ bool CascadeImageReader::getNeg( Mat&amp; _img ) @@ -56,7 +66,8 @@ bool CascadeImageReader::getNeg( Mat&amp; _img )
56 if ( !nextNeg() ) 66 if ( !nextNeg() )
57 return false; 67 return false;
58 68
59 - Mat mat( winSize.height, winSize.width, CV_8UC1, (void*)(img.data + point.y * img.step + point.x * img.elemSize()), img.step ); 69 + Mat mat( winSize.height, winSize.width, CV_8UC1,
  70 + (void*)(img.data + point.y * img.step + point.x * img.elemSize()), img.step );
60 mat.copyTo(_img); 71 mat.copyTo(_img);
61 72
62 if( (int)( point.x + (1.0F + stepFactor ) * winSize.width ) < img.cols ) 73 if( (int)( point.x + (1.0F + stepFactor ) * winSize.width ) < img.cols )
@@ -82,11 +93,10 @@ bool CascadeImageReader::getNeg( Mat&amp; _img ) @@ -82,11 +93,10 @@ bool CascadeImageReader::getNeg( Mat&amp; _img )
82 return true; 93 return true;
83 } 94 }
84 95
  96 +
85 bool CascadeImageReader::getPos(Mat &_img) 97 bool CascadeImageReader::getPos(Mat &_img)
86 { 98 {
87 - if (posIdx > (int)posImages.size())  
88 - CV_Error( CV_StsBadArg, "Can not get new positive sample. Not enough positive samples.\n");  
89 - _img = posImages[posIdx++]; 99 + posImages[posIdx++].copyTo(_img);
90 return true; 100 return true;
91 } 101 }
92 102
@@ -95,15 +105,16 @@ bool CascadeImageReader::getPos(Mat &amp;_img) @@ -95,15 +105,16 @@ bool CascadeImageReader::getPos(Mat &amp;_img)
95 bool BrCascadeClassifier::train(const string _cascadeDirName, 105 bool BrCascadeClassifier::train(const string _cascadeDirName,
96 const QList<Mat> &_posImages, 106 const QList<Mat> &_posImages,
97 const QList<Mat> &_negImages, 107 const QList<Mat> &_negImages,
  108 + int _numPos, int _numNeg,
98 int _precalcValBufSize, int _precalcIdxBufSize, 109 int _precalcValBufSize, int _precalcIdxBufSize,
99 - int _numPos, int _numNeg, int _numStages,  
100 - Representation *_representation, 110 + int _numStages,
  111 + Size _winSize,
101 const CascadeBoostParams& _stageParams) 112 const CascadeBoostParams& _stageParams)
102 { 113 {
103 // Start recording clock ticks for training time output 114 // Start recording clock ticks for training time output
104 const clock_t begin_time = clock(); 115 const clock_t begin_time = clock();
105 116
106 - if( _cascadeDirName.empty() ) 117 + if (_cascadeDirName.empty())
107 CV_Error( CV_StsBadArg, "_cascadeDirName is NULL" ); 118 CV_Error( CV_StsBadArg, "_cascadeDirName is NULL" );
108 119
109 string dirName; 120 string dirName;
@@ -112,14 +123,17 @@ bool BrCascadeClassifier::train(const string _cascadeDirName, @@ -112,14 +123,17 @@ bool BrCascadeClassifier::train(const string _cascadeDirName,
112 else 123 else
113 dirName = _cascadeDirName + '/'; 124 dirName = _cascadeDirName + '/';
114 125
115 - compat = new BoostBRCompatibility(_representation, _numPos + _numNeg); 126 + winSize = _winSize;
  127 +
116 numPos = _numPos; 128 numPos = _numPos;
117 numNeg = _numNeg; 129 numNeg = _numNeg;
118 numStages = _numStages; 130 numStages = _numStages;
119 - imgReader.create(_posImages, _negImages, _representation->windowSize()); 131 + imgReader.create(_posImages, _negImages, winSize);
120 132
121 stageParams = new CascadeBoostParams; 133 stageParams = new CascadeBoostParams;
122 *stageParams = _stageParams; 134 *stageParams = _stageParams;
  135 + featureEvaluator = new FeatureEvaluator;
  136 + featureEvaluator->init(numPos + numNeg, winSize);
123 stageClassifiers.reserve( numStages ); 137 stageClassifiers.reserve( numStages );
124 138
125 double requiredLeafFARate = pow( (double) stageParams->maxFalseAlarm, (double) numStages ) / 139 double requiredLeafFARate = pow( (double) stageParams->maxFalseAlarm, (double) numStages ) /
@@ -127,31 +141,29 @@ bool BrCascadeClassifier::train(const string _cascadeDirName, @@ -127,31 +141,29 @@ bool BrCascadeClassifier::train(const string _cascadeDirName,
127 double tempLeafFARate; 141 double tempLeafFARate;
128 142
129 for (int i = 0; i < numStages; i++) { 143 for (int i = 0; i < numStages; i++) {
130 - qDebug() << endl << "===== TRAINING " << i << "-stage =====";  
131 - qDebug() << "<BEGIN";  
132 - if ( !updateTrainingSet( tempLeafFARate ) )  
133 - {  
134 - qDebug() << "Train dataset for temp stage can not be filled. "  
135 - "Branch training terminated."; 144 + cout << endl << "===== TRAINING " << i << "-stage =====" << endl;
  145 + cout << "<BEGIN" << endl;
  146 + if (!updateTrainingSet(tempLeafFARate)) {
  147 + cout << "Train dataset for temp stage can not be filled. "
  148 + "Branch training terminated." << endl;
136 break; 149 break;
137 } 150 }
138 - if( tempLeafFARate <= requiredLeafFARate )  
139 - {  
140 - qDebug() << "Required leaf false alarm rate achieved. "  
141 - "Branch training terminated."; 151 + if (tempLeafFARate <= requiredLeafFARate) {
  152 + cout << "Required leaf false alarm rate achieved. "
  153 + "Branch training terminated." << endl;
142 break; 154 break;
143 } 155 }
144 156
145 CascadeBoost* tempStage = new CascadeBoost; 157 CascadeBoost* tempStage = new CascadeBoost;
146 - bool isStageTrained = tempStage->train( (BoostBRCompatibility*)compat, 158 + bool isStageTrained = tempStage->train( (FeatureEvaluator*)featureEvaluator,
147 curNumSamples, _precalcValBufSize, _precalcIdxBufSize, 159 curNumSamples, _precalcValBufSize, _precalcIdxBufSize,
148 *((CascadeBoostParams*)stageParams) ); 160 *((CascadeBoostParams*)stageParams) );
149 - qDebug() << "END>"; 161 + cout << "END>" << endl;
150 162
151 - if(!isStageTrained) 163 + if (!isStageTrained)
152 break; 164 break;
153 165
154 - stageClassifiers.push_back( tempStage ); 166 + stageClassifiers.push_back(tempStage);
155 167
156 // Output training time up till now 168 // Output training time up till now
157 float seconds = float( clock () - begin_time ) / CLOCKS_PER_SEC; 169 float seconds = float( clock () - begin_time ) / CLOCKS_PER_SEC;
@@ -159,12 +171,11 @@ bool BrCascadeClassifier::train(const string _cascadeDirName, @@ -159,12 +171,11 @@ bool BrCascadeClassifier::train(const string _cascadeDirName,
159 int hours = (int(seconds) / 60 / 60) % 24; 171 int hours = (int(seconds) / 60 / 60) % 24;
160 int minutes = (int(seconds) / 60) % 60; 172 int minutes = (int(seconds) / 60) % 60;
161 int seconds_left = int(seconds) % 60; 173 int seconds_left = int(seconds) % 60;
162 - qDebug() << "Training until now has taken " << days << " days " << hours << " hours " << minutes << " minutes " << seconds_left <<" seconds."; 174 + cout << "Training until now has taken " << days << " days " << hours << " hours " << minutes << " minutes " << seconds_left <<" seconds." << endl;
163 } 175 }
164 176
165 - if(stageClassifiers.size() == 0)  
166 - {  
167 - qDebug() << "Cascade classifier can't be trained. Check the used training parameters."; 177 + if (stageClassifiers.size() == 0) {
  178 + cout << "Cascade classifier can't be trained. Check the used training parameters." << endl;
168 return false; 179 return false;
169 } 180 }
170 181
@@ -193,7 +204,7 @@ bool BrCascadeClassifier::updateTrainingSet( double&amp; acceptanceRatio) @@ -193,7 +204,7 @@ bool BrCascadeClassifier::updateTrainingSet( double&amp; acceptanceRatio)
193 int posCount = fillPassedSamples( 0, numPos, true, posConsumed ); 204 int posCount = fillPassedSamples( 0, numPos, true, posConsumed );
194 if( !posCount ) 205 if( !posCount )
195 return false; 206 return false;
196 - qDebug() << "POS count : consumed " << posCount << " : " << (int)posConsumed; 207 + cout << "POS count : consumed " << posCount << " : " << (int)posConsumed << endl;
197 208
198 int proNumNeg = cvRound( ( ((double)numNeg) * ((double)posCount) ) / numPos ); // apply only a fraction of negative samples. double is required since overflow is possible 209 int proNumNeg = cvRound( ( ((double)numNeg) * ((double)posCount) ) / numPos ); // apply only a fraction of negative samples. double is required since overflow is possible
199 int negCount = fillPassedSamples( posCount, proNumNeg, false, negConsumed ); 210 int negCount = fillPassedSamples( posCount, proNumNeg, false, negConsumed );
@@ -202,14 +213,14 @@ bool BrCascadeClassifier::updateTrainingSet( double&amp; acceptanceRatio) @@ -202,14 +213,14 @@ bool BrCascadeClassifier::updateTrainingSet( double&amp; acceptanceRatio)
202 213
203 curNumSamples = posCount + negCount; 214 curNumSamples = posCount + negCount;
204 acceptanceRatio = negConsumed == 0 ? 0 : ( (double)negCount/(double)(int64)negConsumed ); 215 acceptanceRatio = negConsumed == 0 ? 0 : ( (double)negCount/(double)(int64)negConsumed );
205 - qDebug() << "NEG count : acceptanceRatio " << negCount << " : " << acceptanceRatio; 216 + cout << "NEG count : acceptanceRatio " << negCount << " : " << acceptanceRatio << endl;
206 return true; 217 return true;
207 } 218 }
208 219
209 int BrCascadeClassifier::fillPassedSamples( int first, int count, bool isPositive, int64& consumed ) 220 int BrCascadeClassifier::fillPassedSamples( int first, int count, bool isPositive, int64& consumed )
210 { 221 {
211 int getcount = 0; 222 int getcount = 0;
212 - Mat img(compat->representation->windowSize(), CV_8UC1); 223 + Mat img(winSize, CV_8UC1);
213 for( int i = first; i < first + count; i++ ) 224 for( int i = first; i < first + count; i++ )
214 { 225 {
215 for( ; ; ) 226 for( ; ; )
@@ -220,7 +231,7 @@ int BrCascadeClassifier::fillPassedSamples( int first, int count, bool isPositiv @@ -220,7 +231,7 @@ int BrCascadeClassifier::fillPassedSamples( int first, int count, bool isPositiv
220 return getcount; 231 return getcount;
221 consumed++; 232 consumed++;
222 233
223 - compat->setImage( img, isPositive ? 1 : 0, i ); 234 + featureEvaluator->setImage( img, isPositive ? 1 : 0, i );
224 if( predict( i ) == 1.0F ) 235 if( predict( i ) == 1.0F )
225 { 236 {
226 getcount++; 237 getcount++;
@@ -238,13 +249,18 @@ void BrCascadeClassifier::writeParams( FileStorage &amp;fs ) const @@ -238,13 +249,18 @@ void BrCascadeClassifier::writeParams( FileStorage &amp;fs ) const
238 fs << CC_FEATURE_TYPE << CC_LBP; 249 fs << CC_FEATURE_TYPE << CC_LBP;
239 fs << CC_HEIGHT << winSize.height; 250 fs << CC_HEIGHT << winSize.height;
240 fs << CC_WIDTH << winSize.width; 251 fs << CC_WIDTH << winSize.width;
  252 +
241 fs << CC_STAGE_PARAMS << "{"; stageParams->write( fs ); fs << "}"; 253 fs << CC_STAGE_PARAMS << "{"; stageParams->write( fs ); fs << "}";
242 - fs << CC_FEATURE_PARAMS << "{"; fs << CC_MAX_CAT_COUNT << 256; fs << CC_FEATURE_SIZE << 1; fs << "}"; 254 +
  255 + fs << CC_FEATURE_PARAMS << "{";
  256 + fs << CC_MAX_CAT_COUNT << featureEvaluator->getMaxCatCount();
  257 + fs << CC_FEATURE_SIZE << featureEvaluator->getFeatureSize();
  258 + fs << "}";
243 } 259 }
244 260
245 void BrCascadeClassifier::writeFeatures( FileStorage &fs, const Mat& featureMap ) const 261 void BrCascadeClassifier::writeFeatures( FileStorage &fs, const Mat& featureMap ) const
246 { 262 {
247 - compat->representation->write(fs, featureMap); 263 + ((FeatureEvaluator*)((Ptr<FeatureEvaluator>)featureEvaluator))->writeFeatures( fs, featureMap );
248 } 264 }
249 265
250 void BrCascadeClassifier::writeStages( FileStorage &fs, const Mat& featureMap ) const 266 void BrCascadeClassifier::writeStages( FileStorage &fs, const Mat& featureMap ) const
@@ -285,7 +301,7 @@ void BrCascadeClassifier::save(const string filename) @@ -285,7 +301,7 @@ void BrCascadeClassifier::save(const string filename)
285 301
286 void BrCascadeClassifier::getUsedFeaturesIdxMap( Mat& featureMap ) 302 void BrCascadeClassifier::getUsedFeaturesIdxMap( Mat& featureMap )
287 { 303 {
288 - int varCount = compat->numFeatures(); 304 + int varCount = featureEvaluator->getNumFeatures() * featureEvaluator->getFeatureSize();
289 featureMap.create( 1, varCount, CV_32SC1 ); 305 featureMap.create( 1, varCount, CV_32SC1 );
290 featureMap.setTo(Scalar(-1)); 306 featureMap.setTo(Scalar(-1));
291 307
@@ -298,4 +314,3 @@ void BrCascadeClassifier::getUsedFeaturesIdxMap( Mat&amp; featureMap ) @@ -298,4 +314,3 @@ void BrCascadeClassifier::getUsedFeaturesIdxMap( Mat&amp; featureMap )
298 featureMap.ptr<int>(0)[fi] = idx++; 314 featureMap.ptr<int>(0)[fi] = idx++;
299 } 315 }
300 316
301 -  
openbr/core/cascade.h
1 -#ifndef _CASCADE_H  
2 -#define _CASCADE_H 1 +#ifndef CASCADE_H
  2 +#define CASCADE_H
3 3
4 #include <openbr/openbr_plugin.h> 4 #include <openbr/openbr_plugin.h>
5 #include <opencv2/highgui/highgui.hpp> 5 #include <opencv2/highgui/highgui.hpp>
@@ -17,9 +17,6 @@ public: @@ -17,9 +17,6 @@ public:
17 bool getNeg(cv::Mat &_img); 17 bool getNeg(cv::Mat &_img);
18 bool getPos(cv::Mat &_img); 18 bool getPos(cv::Mat &_img);
19 19
20 -private:  
21 - bool nextNeg();  
22 -  
23 QList<cv::Mat> posImages, negImages; 20 QList<cv::Mat> posImages, negImages;
24 21
25 int posIdx, negIdx; 22 int posIdx, negIdx;
@@ -31,42 +28,45 @@ private: @@ -31,42 +28,45 @@ private:
31 float stepFactor; 28 float stepFactor;
32 size_t round; 29 size_t round;
33 cv::Size winSize; 30 cv::Size winSize;
  31 +
  32 +private:
  33 + bool nextNeg();
34 }; 34 };
35 35
  36 +
36 class BrCascadeClassifier 37 class BrCascadeClassifier
37 { 38 {
38 public: 39 public:
39 bool train(const std::string _cascadeDirName, 40 bool train(const std::string _cascadeDirName,
40 - const QList<cv::Mat> &_posImages,  
41 - const QList<cv::Mat> &_negImages,  
42 - int _precalcValBufSize, int _precalcIdxBufSize,  
43 - int _numPos, int _numNeg, int _numStages,  
44 - Representation *_representation,  
45 - const CascadeBoostParams& _stageParams); 41 + const QList<cv::Mat> &_posImages,
  42 + const QList<cv::Mat> &_negImages,
  43 + int _numPos, int _numNeg,
  44 + int _precalcValBufSize, int _precalcIdxBufSize,
  45 + int _numStages,
  46 + cv::Size _winSize,
  47 + const CascadeBoostParams& _stageParams);
46 private: 48 private:
47 - int predict( int sampleIdx ); 49 + int predict(int sampleIdx);
48 void save(const std::string cascadeDirName); 50 void save(const std::string cascadeDirName);
49 - bool updateTrainingSet( double& acceptanceRatio );  
50 - int fillPassedSamples( int first, int count, bool isPositive, int64& consumed ); 51 + bool updateTrainingSet(double& acceptanceRatio);
  52 + int fillPassedSamples(int first, int count, bool isPositive, int64& consumed);
51 53
52 - void writeParams( cv::FileStorage &fs ) const;  
53 - void writeStages( cv::FileStorage &fs, const cv::Mat& featureMap ) const;  
54 - void writeFeatures( cv::FileStorage &fs, const cv::Mat& featureMap ) const; 54 + void writeParams(cv::FileStorage &fs) const;
  55 + void writeStages(cv::FileStorage &fs, const cv::Mat& featureMap) const;
  56 + void writeFeatures(cv::FileStorage &fs, const cv::Mat& featureMap) const;
55 57
56 - void getUsedFeaturesIdxMap( cv::Mat& featureMap ); 58 + void getUsedFeaturesIdxMap(cv::Mat& featureMap);
57 59
58 cv::Ptr<CascadeBoostParams> stageParams; 60 cv::Ptr<CascadeBoostParams> stageParams;
59 61
60 - cv::Ptr<LBPTrainingEvaluator> featureEvaluator;  
61 - cv::Ptr<BoostBRCompatibility> compat; 62 + cv::Ptr<FeatureEvaluator> featureEvaluator;
62 std::vector< cv::Ptr<CascadeBoost> > stageClassifiers; 63 std::vector< cv::Ptr<CascadeBoost> > stageClassifiers;
63 CascadeImageReader imgReader; 64 CascadeImageReader imgReader;
64 - cv::Size winSize;  
65 int numStages, curNumSamples; 65 int numStages, curNumSamples;
66 int numPos, numNeg; 66 int numPos, numNeg;
  67 + cv::Size winSize;
67 }; 68 };
68 69
69 } // namespace br 70 } // namespace br
70 71
71 -#endif // _CASCADE_H  
72 - 72 +#endif // CASCADE_H
openbr/core/features.cpp
1 #include "features.h" 1 #include "features.h"
2 -#include "opencvutils.h"  
3 2
4 using namespace cv; 3 using namespace cv;
5 using namespace br; 4 using namespace br;
6 5
7 -// ------------------------------------ LBP Training ----------------------------------------------- 6 +//------------------------------------- FeatureEvaluator ---------------------------------------
8 7
9 -void LBPTrainingEvaluator::init(int _maxSampleCount, Size _winSize) 8 +void FeatureEvaluator::init(int _maxSampleCount, Size _winSize )
10 { 9 {
11 - CV_Assert( _maxSampleCount > 0);  
12 - sum.create((int)_maxSampleCount, (_winSize.width + 1) * (_winSize.height + 1), CV_32SC1);  
13 - 10 + CV_Assert(_maxSampleCount > 0);
14 winSize = _winSize; 11 winSize = _winSize;
15 numFeatures = 0; 12 numFeatures = 0;
16 - maxCatCount = 256; 13 + data.create((int)_maxSampleCount, (_winSize.width + 1) * (_winSize.height + 1), CV_32SC1);
17 cls.create( (int)_maxSampleCount, 1, CV_32FC1 ); 14 cls.create( (int)_maxSampleCount, 1, CV_32FC1 );
  15 +
  16 + maxCatCount = 256;
  17 + featSize = 1;
  18 +
18 generateFeatures(); 19 generateFeatures();
19 } 20 }
20 21
21 -void LBPTrainingEvaluator::setImage(const Mat &img, uchar clsLabel, int idx) 22 +void FeatureEvaluator::setImage(const Mat &img, uchar clsLabel, int idx)
22 { 23 {
23 - CV_DbgAssert( !sum.empty() ); 24 + CV_Assert(img.cols == winSize.width);
  25 + CV_Assert(img.rows == winSize.height);
  26 + CV_Assert(idx < cls.rows);
24 cls.ptr<float>(idx)[0] = clsLabel; 27 cls.ptr<float>(idx)[0] = clsLabel;
25 - Mat innSum(winSize.height + 1, winSize.width + 1, sum.type(), sum.ptr<int>((int)idx));  
26 - integral( img, innSum ); 28 + Mat integralImg(winSize.height + 1, winSize.width + 1, data.type(), data.ptr<int>(idx));
  29 + integral(img, integralImg);
27 } 30 }
28 31
29 -void LBPTrainingEvaluator::writeFeatures( FileStorage &fs, const Mat& featureMap ) const 32 +void FeatureEvaluator::writeFeatures(FileStorage &fs, const Mat &featureMap) const
30 { 33 {
31 _writeFeatures( features, fs, featureMap ); 34 _writeFeatures( features, fs, featureMap );
32 } 35 }
33 36
34 -void LBPTrainingEvaluator::generateFeatures() 37 +void FeatureEvaluator::generateFeatures()
35 { 38 {
36 int offset = winSize.width + 1; 39 int offset = winSize.width + 1;
37 - for( int x = 0; x < winSize.width; x++ )  
38 - for( int y = 0; y < winSize.height; y++ )  
39 - for( int w = 1; w <= winSize.width / 3; w++ )  
40 - for( int h = 1; h <= winSize.height / 3; h++ )  
41 - if ( (x+3*w <= winSize.width) && (y+3*h <= winSize.height) )  
42 - features.push_back( Feature(offset, x, y, w, h ) ); 40 + for (int x = 0; x < winSize.width; x++)
  41 + for (int y = 0; y < winSize.height; y++)
  42 + for (int w = 1; w <= winSize.width / 3; w++)
  43 + for (int h = 1; h <= winSize.height / 3; h++)
  44 + if ((x+3*w <= winSize.width) && (y+3*h <= winSize.height))
  45 + features.push_back(Feature(offset, x, y, w, h ));
43 numFeatures = (int)features.size(); 46 numFeatures = (int)features.size();
44 } 47 }
45 48
46 -LBPTrainingEvaluator::Feature::Feature() 49 +FeatureEvaluator::Feature::Feature()
47 { 50 {
48 rect = cvRect(0, 0, 0, 0); 51 rect = cvRect(0, 0, 0, 0);
49 } 52 }
50 53
51 -LBPTrainingEvaluator::Feature::Feature( int offset, int x, int y, int _blockWidth, int _blockHeight ) 54 +FeatureEvaluator::Feature::Feature( int offset, int x, int y, int _blockWidth, int _blockHeight )
52 { 55 {
53 Rect tr = rect = cvRect(x, y, _blockWidth, _blockHeight); 56 Rect tr = rect = cvRect(x, y, _blockWidth, _blockHeight);
54 CV_SUM_OFFSETS( p[0], p[1], p[4], p[5], tr, offset ) 57 CV_SUM_OFFSETS( p[0], p[1], p[4], p[5], tr, offset )
@@ -60,7 +63,7 @@ LBPTrainingEvaluator::Feature::Feature( int offset, int x, int y, int _blockWidt @@ -60,7 +63,7 @@ LBPTrainingEvaluator::Feature::Feature( int offset, int x, int y, int _blockWidt
60 CV_SUM_OFFSETS( p[8], p[9], p[12], p[13], tr, offset ) 63 CV_SUM_OFFSETS( p[8], p[9], p[12], p[13], tr, offset )
61 } 64 }
62 65
63 -void LBPTrainingEvaluator::Feature::write(FileStorage &fs) const 66 +void FeatureEvaluator::Feature::write(FileStorage &fs) const
64 { 67 {
65 fs << CC_RECT << "[:" << rect.x << rect.y << rect.width << rect.height << "]"; 68 fs << CC_RECT << "[:" << rect.x << rect.y << rect.width << rect.height << "]";
66 } 69 }
openbr/core/features.h
@@ -27,7 +27,7 @@ @@ -27,7 +27,7 @@
27 #define CC_MINHITRATE "minHitRate" 27 #define CC_MINHITRATE "minHitRate"
28 #define CC_MAXFALSEALARM "maxFalseAlarm" 28 #define CC_MAXFALSEALARM "maxFalseAlarm"
29 #define CC_TRIM_RATE "weightTrimRate" 29 #define CC_TRIM_RATE "weightTrimRate"
30 -#define CC_MAX_DEPTH "maxDepth" 30 +#define CC_MAX_DEPTH "maxDeptrh"
31 #define CC_WEAK_COUNT "maxWeakCount" 31 #define CC_WEAK_COUNT "maxWeakCount"
32 #define CC_STAGE_THRESHOLD "stageThreshold" 32 #define CC_STAGE_THRESHOLD "stageThreshold"
33 #define CC_WEAK_CLASSIFIERS "weakClassifiers" 33 #define CC_WEAK_CLASSIFIERS "weakClassifiers"
@@ -39,24 +39,9 @@ @@ -39,24 +39,9 @@
39 #define CC_MAX_CAT_COUNT "maxCatCount" 39 #define CC_MAX_CAT_COUNT "maxCatCount"
40 #define CC_FEATURE_SIZE "featSize" 40 #define CC_FEATURE_SIZE "featSize"
41 41
42 -#define CC_HAAR "HAAR"  
43 -#define CC_MODE "mode"  
44 -#define CC_MODE_BASIC "BASIC"  
45 -#define CC_MODE_CORE "CORE"  
46 -#define CC_MODE_ALL "ALL"  
47 -#define CC_RECTS "rects"  
48 -#define CC_TILTED "tilted"  
49 -  
50 #define CC_LBP "LBP" 42 #define CC_LBP "LBP"
51 #define CC_RECT "rect" 43 #define CC_RECT "rect"
52 44
53 -#define CC_HOG "HOG"  
54 -#define CC_HOGMULTI "HOGMulti"  
55 -  
56 -#define CC_NPD "NPD"  
57 -#define CC_POINTS "points"  
58 -#define CC_POINT "point"  
59 -  
60 #ifdef _WIN32 45 #ifdef _WIN32
61 #define TIME( arg ) (((double) clock()) / CLOCKS_PER_SEC) 46 #define TIME( arg ) (((double) clock()) / CLOCKS_PER_SEC)
62 #else 47 #else
@@ -73,43 +58,6 @@ @@ -73,43 +58,6 @@
73 /* (x + w, y + h) */ \ 58 /* (x + w, y + h) */ \
74 (p3) = (rect).x + (rect).width + (step) * ((rect).y + (rect).height); 59 (p3) = (rect).x + (rect).width + (step) * ((rect).y + (rect).height);
75 60
76 -#define CV_TILTED_OFFSETS( p0, p1, p2, p3, rect, step ) \  
77 - /* (x, y) */ \  
78 - (p0) = (rect).x + (step) * (rect).y; \  
79 - /* (x - h, y + h) */ \  
80 - (p1) = (rect).x - (rect).height + (step) * ((rect).y + (rect).height);\  
81 - /* (x + w, y + w) */ \  
82 - (p2) = (rect).x + (rect).width + (step) * ((rect).y + (rect).width); \  
83 - /* (x + w - h, y + w + h) */ \  
84 - (p3) = (rect).x + (rect).width - (rect).height \  
85 - + (step) * ((rect).y + (rect).width + (rect).height);  
86 -  
87 -#define CV_SUM_PTRS( p0, p1, p2, p3, sum, rect, step ) \  
88 - /* (x, y) */ \  
89 - (p0) = sum + (rect).x + (step) * (rect).y, \  
90 - /* (x + w, y) */ \  
91 - (p1) = sum + (rect).x + (rect).width + (step) * (rect).y, \  
92 - /* (x, y + h) */ \  
93 - (p2) = sum + (rect).x + (step) * ((rect).y + (rect).height), \  
94 - /* (x + w, y + h) */ \  
95 - (p3) = sum + (rect).x + (rect).width + (step) * ((rect).y + (rect).height)  
96 -  
97 -#define CV_TILTED_PTRS( p0, p1, p2, p3, tilted, rect, step ) \  
98 - /* (x, y) */ \  
99 - (p0) = tilted + (rect).x + (step) * (rect).y, \  
100 - /* (x - h, y + h) */ \  
101 - (p1) = tilted + (rect).x - (rect).height + (step) * ((rect).y + (rect).height), \  
102 - /* (x + w, y + w) */ \  
103 - (p2) = tilted + (rect).x + (rect).width + (step) * ((rect).y + (rect).width), \  
104 - /* (x + w - h, y + w + h) */ \  
105 - (p3) = tilted + (rect).x + (rect).width - (rect).height \  
106 - + (step) * ((rect).y + (rect).width + (rect).height)  
107 -  
108 -#define CALC_SUM_(p0, p1, p2, p3, offset) \  
109 - ((p0)[offset] - (p1)[offset] - (p2)[offset] + (p3)[offset])  
110 -  
111 -#define CALC_SUM(rect,offset) CALC_SUM_((rect)[0], (rect)[1], (rect)[2], (rect)[3], offset)  
112 -  
113 namespace br 61 namespace br
114 { 62 {
115 63
@@ -128,32 +76,30 @@ void _writeFeatures( const std::vector&lt;Feature&gt; features, cv::FileStorage &amp;fs, c @@ -128,32 +76,30 @@ void _writeFeatures( const std::vector&lt;Feature&gt; features, cv::FileStorage &amp;fs, c
128 fs << "]"; 76 fs << "]";
129 } 77 }
130 78
131 -//------------------------- LBP Feature ---------------------------------  
132 -  
133 -class LBPTrainingEvaluator 79 +class FeatureEvaluator
134 { 80 {
135 public: 81 public:
136 - virtual ~LBPTrainingEvaluator() {}  
137 - virtual void init(int _maxSampleCount, cv::Size _winSize );  
138 - virtual void setImage(const cv::Mat& img, uchar clsLabel, int idx);  
139 - virtual float operator()(int featureIdx, int sampleIdx) const { return (float)features[featureIdx].calc( sum, sampleIdx); }  
140 - virtual void writeFeatures( cv::FileStorage &fs, const cv::Mat& featureMap ) const; 82 + ~FeatureEvaluator() {}
  83 + void init(int _maxSampleCount, cv::Size _winSize);
  84 + void setImage(const cv::Mat& img, uchar clsLabel, int idx);
  85 + void writeFeatures(cv::FileStorage &fs, const cv::Mat& featureMap) const;
  86 + float operator()(int featureIdx, int sampleIdx) const { return (float)features[featureIdx].calc(data, sampleIdx); }
141 87
142 int getNumFeatures() const { return numFeatures; } 88 int getNumFeatures() const { return numFeatures; }
143 int getMaxCatCount() const { return maxCatCount; } 89 int getMaxCatCount() const { return maxCatCount; }
144 - int getFeatureSize() const { return 1; } 90 + int getFeatureSize() const { return featSize; }
145 const cv::Mat& getCls() const { return cls; } 91 const cv::Mat& getCls() const { return cls; }
146 float getCls(int si) const { return cls.at<float>(si, 0); } 92 float getCls(int si) const { return cls.at<float>(si, 0); }
147 93
148 protected: 94 protected:
149 - virtual void generateFeatures(); 95 + void generateFeatures();
150 96
151 class Feature 97 class Feature
152 { 98 {
153 public: 99 public:
154 Feature(); 100 Feature();
155 Feature( int offset, int x, int y, int _block_w, int _block_h ); 101 Feature( int offset, int x, int y, int _block_w, int _block_h );
156 - uchar calc( const cv::Mat& _sum, size_t y ) const; 102 + uchar calc( const cv::Mat &data, int y ) const;
157 void write( cv::FileStorage &fs ) const; 103 void write( cv::FileStorage &fs ) const;
158 104
159 cv::Rect rect; 105 cv::Rect rect;
@@ -161,26 +107,29 @@ protected: @@ -161,26 +107,29 @@ protected:
161 }; 107 };
162 std::vector<Feature> features; 108 std::vector<Feature> features;
163 109
  110 + cv::Mat data, cls;
  111 +
164 int npos, nneg; 112 int npos, nneg;
165 - int maxCatCount;  
166 int numFeatures; 113 int numFeatures;
  114 + int maxCatCount; // 0 in case of numerical features
  115 + int featSize; // 1 in case of simple features (HAAR, LBP) and N_BINS(9)*N_CELLS(4) in case of Dalal's HOG features
  116 +
167 cv::Size winSize; 117 cv::Size winSize;
168 - cv::Mat cls, sum;  
169 }; 118 };
170 119
171 -inline uchar LBPTrainingEvaluator::Feature::calc(const cv::Mat &_sum, size_t y) const 120 +inline uchar FeatureEvaluator::Feature::calc(const cv::Mat &data, int y) const
172 { 121 {
173 - const int* psum = _sum.ptr<int>((int)y);  
174 - int cval = psum[p[5]] - psum[p[6]] - psum[p[9]] + psum[p[10]];  
175 -  
176 - return (uchar)((psum[p[0]] - psum[p[1]] - psum[p[4]] + psum[p[5]] >= cval ? 128 : 0) | // 0  
177 - (psum[p[1]] - psum[p[2]] - psum[p[5]] + psum[p[6]] >= cval ? 64 : 0) | // 1  
178 - (psum[p[2]] - psum[p[3]] - psum[p[6]] + psum[p[7]] >= cval ? 32 : 0) | // 2  
179 - (psum[p[6]] - psum[p[7]] - psum[p[10]] + psum[p[11]] >= cval ? 16 : 0) | // 5  
180 - (psum[p[10]] - psum[p[11]] - psum[p[14]] + psum[p[15]] >= cval ? 8 : 0) | // 8  
181 - (psum[p[9]] - psum[p[10]] - psum[p[13]] + psum[p[14]] >= cval ? 4 : 0) | // 7  
182 - (psum[p[8]] - psum[p[9]] - psum[p[12]] + psum[p[13]] >= cval ? 2 : 0) | // 6  
183 - (psum[p[4]] - psum[p[5]] - psum[p[8]] + psum[p[9]] >= cval ? 1 : 0)); // 3 122 + const int* ptr = data.ptr<int>(y);
  123 + int cval = ptr[p[5]] - ptr[p[6]] - ptr[p[9]] + ptr[p[10]];
  124 +
  125 + return (uchar)((ptr[p[0]] - ptr[p[1]] - ptr[p[4]] + ptr[p[5]] >= cval ? 128 : 0) | // 0
  126 + (ptr[p[1]] - ptr[p[2]] - ptr[p[5]] + ptr[p[6]] >= cval ? 64 : 0) | // 1
  127 + (ptr[p[2]] - ptr[p[3]] - ptr[p[6]] + ptr[p[7]] >= cval ? 32 : 0) | // 2
  128 + (ptr[p[6]] - ptr[p[7]] - ptr[p[10]] + ptr[p[11]] >= cval ? 16 : 0) | // 5
  129 + (ptr[p[10]] - ptr[p[11]] - ptr[p[14]] + ptr[p[15]] >= cval ? 8 : 0) | // 8
  130 + (ptr[p[9]] - ptr[p[10]] - ptr[p[13]] + ptr[p[14]] >= cval ? 4 : 0) | // 7
  131 + (ptr[p[8]] - ptr[p[9]] - ptr[p[12]] + ptr[p[13]] >= cval ? 2 : 0) | // 6
  132 + (ptr[p[4]] - ptr[p[5]] - ptr[p[8]] + ptr[p[9]] >= cval ? 1 : 0)); // 3
184 } 133 }
185 134
186 } // namespace br 135 } // namespace br
openbr/plugins/metadata/cascade.cpp
@@ -80,20 +80,18 @@ class CascadeTransform : public MetaTransform @@ -80,20 +80,18 @@ class CascadeTransform : public MetaTransform
80 Q_PROPERTY(int winHeight READ get_winHeight WRITE set_winHeight RESET reset_winHeight STORED false) 80 Q_PROPERTY(int winHeight READ get_winHeight WRITE set_winHeight RESET reset_winHeight STORED false)
81 Q_PROPERTY(int numPos READ get_numPos WRITE set_numPos RESET reset_numPos STORED false) 81 Q_PROPERTY(int numPos READ get_numPos WRITE set_numPos RESET reset_numPos STORED false)
82 Q_PROPERTY(int numNeg READ get_numNeg WRITE set_numNeg RESET reset_numNeg STORED false) 82 Q_PROPERTY(int numNeg READ get_numNeg WRITE set_numNeg RESET reset_numNeg STORED false)
83 - Q_PROPERTY(int numStages READ get_numStages WRITE set_numStages RESET reset_numStages STORED false)  
84 83
85 BR_PROPERTY(QString, model, "FrontalFace") 84 BR_PROPERTY(QString, model, "FrontalFace")
86 BR_PROPERTY(int, minSize, 64) 85 BR_PROPERTY(int, minSize, 64)
87 BR_PROPERTY(int, minNeighbors, 5) 86 BR_PROPERTY(int, minNeighbors, 5)
88 BR_PROPERTY(bool, ROCMode, false) 87 BR_PROPERTY(bool, ROCMode, false)
89 88
90 - BR_PROPERTY(QString, vecFile, "vec.vec") 89 + BR_PROPERTY(QString, vecFile, "data.vec")
91 BR_PROPERTY(QString, negFile, "neg.txt") 90 BR_PROPERTY(QString, negFile, "neg.txt")
92 BR_PROPERTY(int, winWidth, 24) 91 BR_PROPERTY(int, winWidth, 24)
93 BR_PROPERTY(int, winHeight, 24) 92 BR_PROPERTY(int, winHeight, 24)
94 BR_PROPERTY(int, numPos, 1000) 93 BR_PROPERTY(int, numPos, 1000)
95 BR_PROPERTY(int, numNeg, 1000) 94 BR_PROPERTY(int, numNeg, 1000)
96 - BR_PROPERTY(int, numStages, 20)  
97 95
98 Resource<CascadeClassifier> cascadeResource; 96 Resource<CascadeClassifier> cascadeResource;
99 97
@@ -180,22 +178,21 @@ class CascadeTransform : public MetaTransform @@ -180,22 +178,21 @@ class CascadeTransform : public MetaTransform
180 // Train transform 178 // Train transform
181 void train(const TemplateList& data) 179 void train(const TemplateList& data)
182 { 180 {
183 - (void) data; 181 + (void)data;
  182 +
  183 + BrCascadeClassifier classifier;
184 184
185 QList<Mat> posImages = getPos(); 185 QList<Mat> posImages = getPos();
186 QList<Mat> negImages = getNeg(); 186 QList<Mat> negImages = getNeg();
187 187
188 - BrCascadeClassifier classifier;  
189 -  
190 CascadeBoostParams stageParams(CvBoost::GENTLE, 0.999, 0.5, 0.95, 1, 200); 188 CascadeBoostParams stageParams(CvBoost::GENTLE, 0.999, 0.5, 0.95, 1, 200);
191 189
192 - Representation *representation = Representation::make("MBLBP(24,24)", NULL);  
193 -  
194 QString cascadeDir = Globals->sdkPath + "/share/openbr/models/openbrcascades/" + model; 190 QString cascadeDir = Globals->sdkPath + "/share/openbr/models/openbrcascades/" + model;
195 classifier.train(cascadeDir.toStdString(), 191 classifier.train(cascadeDir.toStdString(),
196 posImages, negImages, 192 posImages, negImages,
197 - 1024, 1024, numPos, numNeg, numStages,  
198 - representation, stageParams); 193 + numPos, numNeg, 1024, 1024, 12,
  194 + Size(winWidth, winHeight),
  195 + stageParams);
199 } 196 }
200 197
201 void project(const Template &src, Template &dst) const 198 void project(const Template &src, Template &dst) const
openbr/plugins/representation/mblbp.cpp
1 #include <opencv2/imgproc/imgproc.hpp> 1 #include <opencv2/imgproc/imgproc.hpp>
2 2
3 #include <openbr/plugins/openbr_internal.h> 3 #include <openbr/plugins/openbr_internal.h>
  4 +#include <openbr/core/opencvutils.h>
4 5
5 using namespace cv; 6 using namespace cv;
6 7
@@ -29,12 +30,12 @@ class MBLBPRepresentation : public Representation @@ -29,12 +30,12 @@ class MBLBPRepresentation : public Representation
29 void init() 30 void init()
30 { 31 {
31 int offset = winWidth + 1; 32 int offset = winWidth + 1;
32 - for( int x = 0; x < winWidth; x++ )  
33 - for( int y = 0; y < winHeight; y++ )  
34 - for( int w = 1; w <= winWidth / 3; w++ )  
35 - for( int h = 1; h <= winHeight / 3; h++ )  
36 - if ( (x+3*w <= winWidth) && (y+3*h <= winHeight) )  
37 - features.push_back( Feature(offset, x, y, w, h ) ); 33 + for (int x = 0; x < winWidth; x++ )
  34 + for (int y = 0; y < winHeight; y++ )
  35 + for (int w = 1; w <= winWidth / 3; w++ )
  36 + for (int h = 1; h <= winHeight / 3; h++ )
  37 + if ((x+3*w <= winWidth) && (y+3*h <= winHeight) )
  38 + features.append(Feature(offset, x, y, w, h ) );
38 } 39 }
39 40
40 Mat preprocess(const Mat &image) const 41 Mat preprocess(const Mat &image) const