Commit a3840e5469edd4b10a3ef5eb3cf303482568ce32

Authored by Scott Klum
1 parent 4f46567a

Cleaning

Showing 1 changed file with 199 additions and 235 deletions
openbr/core/boost.cpp
... ... @@ -181,6 +181,7 @@ struct CascadeBoostTrainData : CvDTreeTrainData
181 181  
182 182 virtual CvDTreeNode* subsample_data(const CvMat* _subsample_idx);
183 183  
  184 + virtual const int* getBufferValues(CvDTreeNode* n, int* labelsBuf, uint64_t vi);
184 185 virtual const int* get_class_labels(CvDTreeNode* n, int* labelsBuf);
185 186 virtual const int* get_cv_labels(CvDTreeNode* n, int* labelsBuf);
186 187 virtual const int* get_sample_indices(CvDTreeNode* n, int* indicesBuf);
... ... @@ -192,8 +193,10 @@ struct CascadeBoostTrainData : CvDTreeTrainData
192 193 virtual void free_train_data();
193 194  
194 195 const FeatureEvaluator* featureEvaluator;
  196 +
195 197 cv::Mat valCache; // precalculated feature values (CV_32FC1)
196 198 CvMat _resp; // for casting
  199 +
197 200 int numPrecalcVal, numPrecalcIdx, channels;
198 201 };
199 202  
... ... @@ -461,7 +464,10 @@ void CascadeBoostTrainData::setData( const FeatureEvaluator* _featureEvaluator,
461 464  
462 465 // 1048576 is the number of bytes in a megabyte
463 466 numPrecalcVal = min( cvRound((double)_precalcValBufSize*1048576. / (sizeof(float)*sample_count)), var_count );
  467 + qDebug("Features Cached: %f", float(numPrecalcVal)/var_count);
  468 +
464 469 numPrecalcIdx = min( cvRound((double)_precalcIdxBufSize*1048576. / ((is_buf_16u ? sizeof(unsigned short) : sizeof (int))*sample_count)), var_count );
  470 + qDebug("Indices Cached: %f", float(numPrecalcIdx)/var_count);
465 471  
466 472 assert( numPrecalcIdx >= 0 && numPrecalcVal >= 0 );
467 473  
... ... @@ -523,8 +529,7 @@ void CascadeBoostTrainData::setData( const FeatureEvaluator* _featureEvaluator,
523 529 // now calculate the maximum size of split,
524 530 // create memory storage that will keep nodes and splits of the decision tree
525 531 // allocate root node and the buffer for the whole training data
526   - int maxSplitSize = cvAlign(sizeof(CvDTreeSplit) +
527   - (MAX(0,sample_count - 33)/32)*sizeof(int),sizeof(void*));
  532 + int maxSplitSize = cvAlign(sizeof(CvDTreeSplit) + (MAX(0,sample_count - 33)/32)*sizeof(int),sizeof(void*));
528 533 int treeBlockSize = MAX((int)sizeof(CvDTreeNode)*8, maxSplitSize);
529 534 treeBlockSize = MAX(treeBlockSize + BlockSizeDelta, MinBlockSize);
530 535 tree_storage = cvCreateMemStorage( treeBlockSize );
... ... @@ -592,9 +597,8 @@ const int* CascadeBoostTrainData::get_class_labels( CvDTreeNode* n, int* labelsB
592 597 return labelsBuf;
593 598 }
594 599  
595   -const int* CascadeBoostTrainData::get_sample_indices( CvDTreeNode* n, int* indicesBuf )
  600 +const int* CascadeBoostTrainData::getBufferValues(CvDTreeNode* n, int* indicesBuf, uint64_t vi)
596 601 {
597   - const uint64 vi = get_work_var_count();
598 602 const int* cat_values = 0;
599 603 if (!is_buf_16u)
600 604 cat_values = buf->data.i + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset;
... ... @@ -608,84 +612,70 @@ const int* CascadeBoostTrainData::get_sample_indices( CvDTreeNode* n, int* indic
608 612 return cat_values;
609 613 }
610 614  
  615 +const int* CascadeBoostTrainData::get_sample_indices( CvDTreeNode* n, int* indicesBuf )
  616 +{
  617 + return getBufferValues(n,indicesBuf,get_work_var_count());
  618 +}
  619 +
611 620 const int* CascadeBoostTrainData::get_cv_labels( CvDTreeNode* n, int* indicesBuf )
612 621 {
613   - const uint64 vi = get_work_var_count()-1;
614   - const int* cat_values = 0;
615   - if (!is_buf_16u)
616   - cat_values = buf->data.i + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset;
617   - else {
618   - const unsigned short* short_values = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset);
619   - for (int i = 0; i < n->sample_count; i++)
620   - indicesBuf[i] = short_values[i];
621   - cat_values = indicesBuf;
622   - }
623   - return cat_values;
  622 + return getBufferValues(n,indicesBuf,get_work_var_count()-1);
624 623 }
625 624  
626   -void CascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ordValuesBuf, int* sortedIndicesBuf,
627   - const float** ordValues, const int** sortedIndices, int* sampleIndicesBuf )
  625 +void CascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ordValuesBuf, int* sortedIndicesBuf, const float** ordValues, const int** sortedIndices, int* sampleIndicesBuf )
628 626 {
629 627 int nodeSampleCount = n->sample_count;
  628 +
  629 + // For this node, get our sample indices
630 630 const int* sampleIndices = get_sample_indices(n, sampleIndicesBuf);
631 631  
632   - if ( vi < numPrecalcIdx )
633   - {
634   - if( !is_buf_16u )
  632 + // For this feature (this code refers to features as values, hence vi == value index),
  633 + // have we precalculated (presorted) the training samples by their feature response?
  634 + if (vi < numPrecalcIdx) {
  635 + if (!is_buf_16u)
635 636 *sortedIndices = buf->data.i + n->buf_idx*get_length_subbuf() + (uint64)vi*sample_count + n->offset;
636   - else
637   - {
638   - const unsigned short* shortIndices = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() +
639   - vi*sample_count + n->offset );
640   - for( int i = 0; i < nodeSampleCount; i++ )
  637 + else {
  638 + const unsigned short* shortIndices = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + (uint64)vi*sample_count + n->offset );
  639 + for (int i = 0; i < nodeSampleCount; i++)
641 640 sortedIndicesBuf[i] = shortIndices[i];
642   -
643 641 *sortedIndices = sortedIndicesBuf;
644 642 }
645 643  
646   - if( vi < numPrecalcVal )
647   - {
648   - for( int i = 0; i < nodeSampleCount; i++ )
649   - {
  644 + // For this feature, have we precalculated all of the feature responses?
  645 + if (vi < numPrecalcVal) {
  646 + for (int i = 0; i < nodeSampleCount; i++) {
650 647 int idx = (*sortedIndices)[i];
651 648 idx = sampleIndices[idx];
652   - ordValuesBuf[i] = valCache.at<float>( vi, idx);
  649 + ordValuesBuf[i] = valCache.at<float>(vi, idx);
653 650 }
654   - }
655   - else
656   - {
657   - for( int i = 0; i < nodeSampleCount; i++ )
658   - {
  651 + } else {
  652 + for (int i = 0; i < nodeSampleCount; i++) {
659 653 int idx = (*sortedIndices)[i];
660 654 idx = sampleIndices[idx];
661   - ordValuesBuf[i] = (*featureEvaluator)( vi, idx);
  655 + ordValuesBuf[i] = (*featureEvaluator)(vi, idx);
662 656 }
663 657 }
664   - }
665   - else // vi >= numPrecalcIdx
666   - {
  658 + } else {
667 659 cv::AutoBuffer<float> abuf(nodeSampleCount);
668 660 float* sampleValues = &abuf[0];
669 661  
670   - if ( vi < numPrecalcVal )
671   - {
672   - for( int i = 0; i < nodeSampleCount; i++ )
673   - {
  662 + if (vi < numPrecalcVal) {
  663 + for (int i = 0; i < nodeSampleCount; i++) {
674 664 sortedIndicesBuf[i] = i;
675 665 sampleValues[i] = valCache.at<float>( vi, sampleIndices[i] );
676 666 }
677   - }
678   - else
679   - {
680   - for( int i = 0; i < nodeSampleCount; i++ )
681   - {
  667 + } else {
  668 + for (int i = 0; i < nodeSampleCount; i++) {
682 669 sortedIndicesBuf[i] = i;
683 670 sampleValues[i] = (*featureEvaluator)( vi, sampleIndices[i]);
684 671 }
685 672 }
  673 +
686 674 icvSortIntAux( sortedIndicesBuf, nodeSampleCount, &sampleValues[0] );
687   - for( int i = 0; i < nodeSampleCount; i++ )
  675 +
  676 + for (int i = 0; i < nodeSampleCount; i++)
688 677 ordValuesBuf[i] = (&sampleValues[0])[sortedIndicesBuf[i]];
  678 +
689 679 *sortedIndices = sortedIndicesBuf;
690 680 }
691 681  
... ... @@ -727,114 +717,117 @@ float CascadeBoostTrainData::getVarValue( int vi, int si )
727 717 return (*featureEvaluator)( vi, si );
728 718 }
729 719  
730   -struct FeatureIdxOnlyPrecalc : ParallelLoopBody
  720 +struct Precalc : ParallelLoopBody
731 721 {
732   - FeatureIdxOnlyPrecalc( const FeatureEvaluator* _featureEvaluator, CvMat* _buf, int _sample_count, bool _is_buf_16u )
  722 + const FeatureEvaluator* featureEvaluator;
  723 + int sampleCount;
  724 +
  725 + Precalc(const FeatureEvaluator* featureEvaluator, int sampleCount) :
  726 + featureEvaluator(featureEvaluator),
  727 + sampleCount(sampleCount)
  728 + {}
  729 +
  730 + virtual void operator()(const Range& range) const = 0;
  731 +};
  732 +
  733 +struct IndexPrecalc : Precalc
  734 +{
  735 + int* idst;
  736 + unsigned short* udst;
  737 + bool isBufShort;
  738 +
  739 + IndexPrecalc(const FeatureEvaluator* featureEvaluator, CvMat* buf, int sampleCount, bool isBufShort) :
  740 + Precalc(featureEvaluator, sampleCount),
  741 + isBufShort(isBufShort)
  742 + {
  743 + udst = (unsigned short*)buf->data.s;
  744 + idst = buf->data.i;
  745 + }
  746 +
  747 + void setBuffer(int fi, int si) const
733 748 {
734   - featureEvaluator = _featureEvaluator;
735   - sample_count = _sample_count;
736   - udst = (unsigned short*)_buf->data.s;
737   - idst = _buf->data.i;
738   - is_buf_16u = _is_buf_16u;
  749 + if (isBufShort) *(udst + (uint64)fi*sampleCount + si) = (unsigned short)si;
  750 + else *(idst + (uint64)fi*sampleCount + si) = si;
739 751 }
740   - void operator()( const Range& range ) const
  752 +
  753 + void sortBuffer(int fi, float *valCachePtr) const
  754 + {
  755 + if (isBufShort) icvSortUShAux(udst + (uint64)fi*sampleCount, sampleCount, valCachePtr);
  756 + else icvSortIntAux(idst + (uint64)fi*sampleCount, sampleCount, valCachePtr);
  757 + }
  758 +
  759 + virtual void operator()(const Range& range) const
741 760 {
742   - cv::AutoBuffer<float> valCache(sample_count);
  761 + cv::AutoBuffer<float> valCache(sampleCount);
743 762 float* valCachePtr = (float*)valCache;
744   - for ( int fi = range.start; fi < range.end; fi++)
745   - {
746   - for( int si = 0; si < sample_count; si++ )
747   - {
748   - valCachePtr[si] = (*featureEvaluator)( fi, si );
749   - if ( is_buf_16u )
750   - *(udst + fi*sample_count + si) = (unsigned short)si;
751   - else
752   - *(idst + fi*sample_count + si) = si;
  763 + for (int fi = range.start; fi < range.end; fi++) {
  764 + for (int si = 0; si < sampleCount; si++) {
  765 + valCachePtr[si] = (*featureEvaluator)(fi, si);
  766 + setBuffer(fi, si);
753 767 }
754   - if ( is_buf_16u )
755   - icvSortUShAux( udst + (uint64)fi*sample_count, sample_count, valCachePtr );
756   - else
757   - icvSortIntAux( idst + (uint64)fi*sample_count, sample_count, valCachePtr );
  768 + sortBuffer(fi, valCachePtr);
758 769 }
759 770 }
760   - const FeatureEvaluator* featureEvaluator;
761   - int sample_count;
762   - int* idst;
763   - unsigned short* udst;
764   - bool is_buf_16u;
765 771 };
766 772  
767   -struct FeatureValAndIdxPrecalc : ParallelLoopBody
  773 +struct FeatureAndIndexPrecalc : IndexPrecalc
768 774 {
769   - FeatureValAndIdxPrecalc( const FeatureEvaluator* _featureEvaluator, CvMat* _buf, Mat* _valCache, int _sample_count, bool _is_buf_16u )
770   - {
771   - featureEvaluator = _featureEvaluator;
772   - valCache = _valCache;
773   - sample_count = _sample_count;
774   - udst = (unsigned short*)_buf->data.s;
775   - idst = _buf->data.i;
776   - is_buf_16u = _is_buf_16u;
777   - }
778   - void operator()( const Range& range ) const
  775 + Mat *valCache;
  776 +
  777 + FeatureAndIndexPrecalc(const FeatureEvaluator* featureEvaluator, CvMat* buf, Mat* valCache, int sampleCount, bool isBufShort) :
  778 + IndexPrecalc(featureEvaluator, buf, sampleCount, isBufShort),
  779 + valCache(valCache)
  780 + {}
  781 +
  782 + virtual void operator()(const Range& range) const
779 783 {
780   - for ( int fi = range.start; fi < range.end; fi++)
781   - {
782   - for( int si = 0; si < sample_count; si++ )
783   - {
784   - valCache->at<float>(fi,si) = (*featureEvaluator)( fi, si );
785   - if ( is_buf_16u )
786   - *(udst + (uint64)fi*sample_count + si) = (unsigned short)si;
787   - else
788   - *(idst + (uint64)fi*sample_count + si) = si;
  784 + for (int fi = range.start; fi < range.end; fi++) {
  785 + for (int si = 0; si < sampleCount; si++) {
  786 + valCache->at<float>(fi,si) = (*featureEvaluator)(fi, si);
  787 + setBuffer(fi, si);
789 788 }
790   - if ( is_buf_16u )
791   - icvSortUShAux( udst + (uint64)fi*sample_count, sample_count, valCache->ptr<float>(fi) );
792   - else
793   - icvSortIntAux( idst + (uint64)fi*sample_count, sample_count, valCache->ptr<float>(fi) );
  789 + sortBuffer(fi, valCache->ptr<float>(fi));
794 790 }
795 791 }
796   - const FeatureEvaluator* featureEvaluator;
797   - Mat* valCache;
798   - int sample_count;
799   - int* idst;
800   - unsigned short* udst;
801   - bool is_buf_16u;
802 792 };
803 793  
804   -struct FeatureValOnlyPrecalc : ParallelLoopBody
  794 +struct FeaturePrecalc : Precalc
805 795 {
806   - FeatureValOnlyPrecalc( const FeatureEvaluator* _featureEvaluator, Mat* _valCache, int _sample_count )
807   - {
808   - featureEvaluator = _featureEvaluator;
809   - valCache = _valCache;
810   - sample_count = _sample_count;
811   - }
812   - void operator()( const Range& range ) const
  796 + Mat *valCache;
  797 +
  798 + FeaturePrecalc(const FeatureEvaluator* featureEvaluator, Mat* valCache, int sampleCount) :
  799 + Precalc(featureEvaluator, sampleCount),
  800 + valCache(valCache)
  801 + {}
  802 +
  803 + virtual void operator()(const Range& range) const
813 804 {
814   - for ( int fi = range.start; fi < range.end; fi++)
815   - for( int si = 0; si < sample_count; si++ )
816   - valCache->at<float>(fi,si) = (*featureEvaluator)( fi, si );
  805 + for (int fi = range.start; fi < range.end; fi++)
  806 + for (int si = 0; si < sampleCount; si++)
  807 + valCache->at<float>(fi,si) = (*featureEvaluator)(fi, si);
817 808 }
818   - const FeatureEvaluator* featureEvaluator;
819   - Mat* valCache;
820   - int sample_count;
821 809 };
822 810  
823 811 void CascadeBoostTrainData::precalculate()
824 812 {
825   - int minNum = MIN( numPrecalcVal, numPrecalcIdx);
  813 + int minPrecalc = std::min(numPrecalcVal, numPrecalcIdx);
826 814  
827 815 qDebug() << "Starting precalculation...";
828 816  
829 817 QTime time;
830 818 time.start();
831 819  
832   - parallel_for_( Range(numPrecalcVal, numPrecalcIdx),
833   - FeatureIdxOnlyPrecalc(featureEvaluator, buf, sample_count, is_buf_16u!=0) );
834   - parallel_for_( Range(0, minNum),
835   - FeatureValAndIdxPrecalc(featureEvaluator, buf, &valCache, sample_count, is_buf_16u!=0) );
836   - parallel_for_( Range(minNum, numPrecalcVal),
837   - FeatureValOnlyPrecalc(featureEvaluator, &valCache, sample_count) );
  820 + // Compute features and sort training samples for feature indices we are not going to cache
  821 + parallel_for_(Range(numPrecalcVal, numPrecalcIdx),
  822 + IndexPrecalc(featureEvaluator, buf, sample_count, is_buf_16u!=0));
  823 +
  824 + // Compute features and sort training samples for features indices we are going to cache
  825 + parallel_for_(Range(0, minPrecalc),
  826 + FeatureAndIndexPrecalc(featureEvaluator, buf, &valCache, sample_count, is_buf_16u!=0));
  827 +
  828 + // Compute feature values for feature indices for which we are not going to sort training samples
  829 + parallel_for_(Range(minPrecalc, numPrecalcVal),
  830 + FeaturePrecalc(featureEvaluator, &valCache, sample_count));
838 831  
839 832 cout << "Precalculation time (ms): " << time.elapsed() << endl;
840 833 }
... ... @@ -868,87 +861,85 @@ CvDTreeNode* CascadeBoostTree::predict( int sampleIdx ) const
868 861 return node;
869 862 }
870 863  
  864 +// This function splits the training data from the parent node into training
  865 +// data for both child nodes
871 866 void CascadeBoostTree::split_node_data( CvDTreeNode* node )
872 867 {
873   - int n = node->sample_count, nl, nr, scount = data->sample_count;
874   - char* dir = (char*)data->direction->data.ptr;
875 868 CvDTreeNode *left = 0, *right = 0;
  869 +
  870 + uint64_t nodeSampleCount = node->sample_count;
  871 + uint64_t sampleCount = data->sample_count;
  872 + uint64_t nLeft, nRight;
  873 +
  874 + int workVarCount = data->get_work_var_count();
  875 +
  876 + char* dir = (char*)data->direction->data.ptr;
876 877 int* newIdx = data->split_buf->data.i;
877 878 int newBufIdx = data->get_child_buf_idx( node );
878   - int workVarCount = data->get_work_var_count();
879 879 CvMat* buf = data->buf;
880 880 size_t length_buf_row = data->get_length_subbuf();
881   - cv::AutoBuffer<uchar> inn_buf(n*(3*sizeof(int)+sizeof(float)));
  881 + cv::AutoBuffer<uchar> inn_buf(nodeSampleCount*(3*sizeof(int)+sizeof(float)));
882 882 int* tempBuf = (int*)(uchar*)inn_buf;
883   - bool splitInputData;
884 883  
885 884 complete_node_dir(node);
886 885  
887   - for( int i = nl = nr = 0; i < n; i++ )
  886 + for (int i = nLeft = nRight = 0; i < nodeSampleCount; i++)
888 887 {
889 888 int d = dir[i];
890 889 // initialize new indices for splitting ordered variables
891   - newIdx[i] = (nl & (d-1)) | (nr & -d); // d ? ri : li
892   - nr += d;
893   - nl += d^1;
  890 + newIdx[i] = (nLeft & (d-1)) | (nRight & -d); // d ? ri : li
  891 + nRight += d;
  892 + nLeft += d^1;
894 893 }
895 894  
896   - node->left = left = data->new_node( node, nl, newBufIdx, node->offset );
897   - node->right = right = data->new_node( node, nr, newBufIdx, node->offset + nl );
  895 + node->left = left = data->new_node( node, nLeft, newBufIdx, node->offset );
  896 + node->right = right = data->new_node( node, nRight, newBufIdx, node->offset + nLeft );
898 897  
899   - splitInputData = node->depth + 1 < data->params.max_depth &&
900   - (node->left->sample_count > data->params.min_sample_count ||
901   - node->right->sample_count > data->params.min_sample_count);
  898 + bool splitInputData = node->depth + 1 < data->params.max_depth && (node->left->sample_count > data->params.min_sample_count || node->right->sample_count > data->params.min_sample_count);
902 899  
903   - // split ordered variables, keep both halves sorted.
904   - for( int vi = 0; vi < ((CascadeBoostTrainData*)data)->numPrecalcIdx; vi++ )
905   - {
  900 + const int numPreculatedIndices = ((CascadeBoostTrainData*)data)->numPrecalcIdx;
  901 + for (int vi = 0; vi < numPreculatedIndices; vi++) {
906 902 int ci = data->get_var_type(vi);
907 903 if( ci >= 0 || !splitInputData )
908 904 continue;
909 905  
910 906 int n1 = node->get_num_valid(vi);
911   - float *src_val_buf = (float*)(tempBuf + n);
912   - int *src_sorted_idx_buf = (int*)(src_val_buf + n);
913   - int *src_sample_idx_buf = src_sorted_idx_buf + n;
  907 + float *src_val_buf = (float*)(tempBuf + nodeSampleCount);
  908 + int *src_sorted_idx_buf = (int*)(src_val_buf + nodeSampleCount);
  909 + int *src_sample_idx_buf = src_sorted_idx_buf + nodeSampleCount;
914 910 const int* src_sorted_idx = 0;
915 911 const float* src_val = 0;
  912 +
916 913 data->get_ord_var_data(node, vi, src_val_buf, src_sorted_idx_buf, &src_val, &src_sorted_idx, src_sample_idx_buf);
917 914  
918   - for(int i = 0; i < n; i++)
  915 + for(int i = 0; i < nodeSampleCount; i++)
919 916 tempBuf[i] = src_sorted_idx[i];
920 917  
921   - if (data->is_buf_16u)
922   - {
  918 + if (data->is_buf_16u) {
923 919 ushort *ldst, *rdst;
924   - ldst = (ushort*)(buf->data.s + left->buf_idx*length_buf_row +
925   - vi*scount + left->offset);
926   - rdst = (ushort*)(ldst + nl);
  920 + ldst = (ushort*)(buf->data.s + left->buf_idx*length_buf_row + vi*sampleCount + left->offset);
  921 + rdst = (ushort*)(ldst + nLeft);
927 922  
928 923 // split sorted
929   - for( int i = 0; i < n1; i++ )
930   - {
  924 + for (int i = 0; i < n1; i++) {
931 925 int idx = tempBuf[i];
932 926 int d = dir[idx];
933 927 idx = newIdx[idx];
934   - if (d)
935   - {
  928 + if (d) {
936 929 *rdst = (ushort)idx;
937 930 rdst++;
938   - }
939   - else
940   - {
  931 + } else {
941 932 *ldst = (ushort)idx;
942 933 ldst++;
943 934 }
944 935 }
945   - CV_Assert( n1 == n );
  936 + CV_Assert( n1 == nodeSampleCount );
946 937 }
947 938 else
948 939 {
949 940 int *ldst, *rdst;
950   - ldst = buf->data.i + left->buf_idx*length_buf_row + (uint64)(vi*scount) + left->offset;
951   - rdst = buf->data.i + right->buf_idx*length_buf_row + (uint64)(vi*scount) + right->offset;
  941 + ldst = buf->data.i + left->buf_idx*length_buf_row + vi*sampleCount + left->offset;
  942 + rdst = buf->data.i + right->buf_idx*length_buf_row + vi*sampleCount + right->offset;
952 943  
953 944 // split sorted
954 945 for( int i = 0; i < n1; i++ )
... ... @@ -967,34 +958,27 @@ void CascadeBoostTree::split_node_data( CvDTreeNode* node )
967 958 ldst++;
968 959 }
969 960 }
970   - CV_Assert( n1 == n );
  961 + CV_Assert( n1 == nodeSampleCount );
971 962 }
972 963 }
973 964  
974 965 // split cv_labels using newIdx relocation table
975   - int *src_lbls_buf = tempBuf + n;
  966 + int *src_lbls_buf = tempBuf + nodeSampleCount;
976 967 const int* src_lbls = data->get_cv_labels(node, src_lbls_buf);
977 968  
978   - for(int i = 0; i < n; i++)
  969 + for(int i = 0; i < nodeSampleCount; i++)
979 970 tempBuf[i] = src_lbls[i];
980 971  
981   - if (data->is_buf_16u)
982   - {
983   - unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*length_buf_row +
984   - (workVarCount-1)*scount + left->offset);
985   - unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*length_buf_row +
986   - (workVarCount-1)*scount + right->offset);
  972 + if (data->is_buf_16u) {
  973 + unsigned short *ldst = (unsigned short *)(buf->data.s + left->buf_idx*length_buf_row + (workVarCount-1)*sampleCount + left->offset);
  974 + unsigned short *rdst = (unsigned short *)(buf->data.s + right->buf_idx*length_buf_row + (workVarCount-1)*sampleCount + right->offset);
987 975  
988   - for( int i = 0; i < n; i++ )
989   - {
  976 + for( int i = 0; i < nodeSampleCount; i++ ) {
990 977 int idx = tempBuf[i];
991   - if (dir[i])
992   - {
  978 + if (dir[i]) {
993 979 *rdst = (unsigned short)idx;
994 980 rdst++;
995   - }
996   - else
997   - {
  981 + } else {
998 982 *ldst = (unsigned short)idx;
999 983 ldst++;
1000 984 }
... ... @@ -1003,10 +987,10 @@ void CascadeBoostTree::split_node_data( CvDTreeNode* node )
1003 987 }
1004 988 else
1005 989 {
1006   - int *ldst = buf->data.i + left->buf_idx*length_buf_row + (uint64)(workVarCount-1)*scount + left->offset;
1007   - int *rdst = buf->data.i + right->buf_idx*length_buf_row + (uint64)(workVarCount-1)*scount + right->offset;
  990 + int *ldst = buf->data.i + left->buf_idx*length_buf_row + (workVarCount-1)*sampleCount + left->offset;
  991 + int *rdst = buf->data.i + right->buf_idx*length_buf_row + (workVarCount-1)*sampleCount + right->offset;
1008 992  
1009   - for( int i = 0; i < n; i++ )
  993 + for( int i = 0; i < nodeSampleCount; i++ )
1010 994 {
1011 995 int idx = tempBuf[i];
1012 996 if (dir[i])
... ... @@ -1023,28 +1007,21 @@ void CascadeBoostTree::split_node_data( CvDTreeNode* node )
1023 1007 }
1024 1008  
1025 1009 // split sample indices
1026   - int *sampleIdx_src_buf = tempBuf + n;
  1010 + int *sampleIdx_src_buf = tempBuf + nodeSampleCount;
1027 1011 const int* sampleIdx_src = data->get_sample_indices(node, sampleIdx_src_buf);
1028 1012  
1029   - for(int i = 0; i < n; i++)
  1013 + for(int i = 0; i < nodeSampleCount; i++)
1030 1014 tempBuf[i] = sampleIdx_src[i];
1031 1015  
1032   - if (data->is_buf_16u)
1033   - {
1034   - unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*length_buf_row +
1035   - workVarCount*scount + left->offset);
1036   - unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*length_buf_row +
1037   - workVarCount*scount + right->offset);
1038   - for (int i = 0; i < n; i++)
1039   - {
  1016 + if (data->is_buf_16u) {
  1017 + unsigned short* ldst = (unsigned short*)(buf->data.s + left->buf_idx*length_buf_row + workVarCount*sampleCount + left->offset);
  1018 + unsigned short* rdst = (unsigned short*)(buf->data.s + right->buf_idx*length_buf_row + workVarCount*sampleCount + right->offset);
  1019 + for (int i = 0; i < nodeSampleCount; i++) {
1040 1020 unsigned short idx = (unsigned short)tempBuf[i];
1041   - if (dir[i])
1042   - {
  1021 + if (dir[i]) {
1043 1022 *rdst = idx;
1044 1023 rdst++;
1045   - }
1046   - else
1047   - {
  1024 + } else {
1048 1025 *ldst = idx;
1049 1026 ldst++;
1050 1027 }
... ... @@ -1052,9 +1029,9 @@ void CascadeBoostTree::split_node_data( CvDTreeNode* node )
1052 1029 }
1053 1030 else
1054 1031 {
1055   - int* ldst = buf->data.i + left->buf_idx*length_buf_row + (uint64)workVarCount*scount + left->offset;
1056   - int* rdst = buf->data.i + right->buf_idx*length_buf_row + (uint64)workVarCount*scount + right->offset;
1057   - for (int i = 0; i < n; i++)
  1032 + int* ldst = buf->data.i + left->buf_idx*length_buf_row + workVarCount*sampleCount + left->offset;
  1033 + int* rdst = buf->data.i + right->buf_idx*length_buf_row + workVarCount*sampleCount + right->offset;
  1034 + for (int i = 0; i < nodeSampleCount; i++)
1058 1035 {
1059 1036 int idx = tempBuf[i];
1060 1037 if (dir[i])
... ... @@ -1070,10 +1047,10 @@ void CascadeBoostTree::split_node_data( CvDTreeNode* node )
1070 1047 }
1071 1048 }
1072 1049  
1073   - for( int vi = 0; vi < data->var_count; vi++ )
1074   - {
1075   - left->set_num_valid(vi, (int)(nl));
1076   - right->set_num_valid(vi, (int)(nr));
  1050 + const int variableCount = data->var_count;
  1051 + for (int vi = 0; vi < variableCount; vi++) {
  1052 + left->set_num_valid(vi, nLeft);
  1053 + right->set_num_valid(vi, nRight);
1077 1054 }
1078 1055  
1079 1056 // deallocate the parent node data that is not needed anymore
... ... @@ -1106,11 +1083,9 @@ void CascadeBoost::train(const FeatureEvaluator* _featureEvaluator,
1106 1083 cout << "| N | HR | FA |" << endl;
1107 1084 cout << "+----+---------+---------+" << endl;
1108 1085  
1109   - do
1110   - {
  1086 + do {
1111 1087 CascadeBoostTree* tree = new CascadeBoostTree;
1112 1088 if (!tree->train( data, subsample_mask, this)) {
1113   - qDebug() << "Deleting tree!";
1114 1089 delete tree;
1115 1090 return;
1116 1091 }
... ... @@ -1119,9 +1094,8 @@ void CascadeBoost::train(const FeatureEvaluator* _featureEvaluator,
1119 1094 update_weights(tree);
1120 1095 trim_weights();
1121 1096 if (cvCountNonZero(subsample_mask) == 0) {
1122   - qDebug() << "Subsample mask is empty!";
1123 1097 return;
1124   - }
  1098 + }
1125 1099 }
1126 1100 while (!isErrDesired() && (classifiers.size() < params.weak_count));
1127 1101  
... ... @@ -1194,35 +1168,26 @@ void CascadeBoost::update_weights(CvBoostTree* tree)
1194 1168 weights = cvCreateMat( 1, n, CV_64F );
1195 1169 subtree_weights = cvCreateMat( 1, n + 2, CV_64F );
1196 1170  
1197   - if (data->is_buf_16u)
1198   - {
  1171 + // set the labels to find (from within weak tree learning proc)
  1172 + // the particular sample weight, and where to store the response.
  1173 + if (data->is_buf_16u) {
1199 1174 unsigned short* labels = (unsigned short*)(buf->data.s + data->data_root->buf_idx*length_buf_row + data->data_root->offset + (uint64)(data->work_var_count-1)*data->sample_count);
1200   - for( int i = 0; i < n; i++ )
1201   - {
1202   - // save original categorical responses {0,1}, convert them to {-1,1}
1203   - orig_response->data.i[i] = classLabels[i]*2 - 1;
1204   - // make all the samples active at start.
1205   - // later, in trim_weights() deactivate/reactive again some, if need
1206   - subsample_mask->data.ptr[i] = (uchar)1;
1207   - // make all the initial weights the same.
1208   - weights->data.db[i] = w0*p[classLabels[i]];
1209   - // set the labels to find (from within weak tree learning proc)
1210   - // the particular sample weight, and where to store the response.
  1175 + for (int i = 0; i < n; i++)
1211 1176 labels[i] = (unsigned short)i;
1212   - }
1213   - }
1214   - else
1215   - {
  1177 + } else {
1216 1178 int* labels = buf->data.i + data->data_root->buf_idx*length_buf_row + data->data_root->offset + (uint64)(data->work_var_count-1)*data->sample_count;
1217   -
1218 1179 for( int i = 0; i < n; i++ )
1219   - {
1220   - // save original categorical responses {0,1}, convert them to {-1,1}
1221   - orig_response->data.i[i] = classLabels[i]*2 - 1;
1222   - subsample_mask->data.ptr[i] = (uchar)1;
1223   - weights->data.db[i] = w0*p[classLabels[i]];
1224 1180 labels[i] = i;
1225   - }
  1181 + }
  1182 +
  1183 + for (int i = 0; i < n; i++) {
  1184 + // save original categorical responses {0,1}, convert them to {-1,1}
  1185 + orig_response->data.i[i] = classLabels[i]*2 - 1;
  1186 + // make all the samples active at start.
  1187 + // later, in trim_weights() deactivate/reactive again some, if need
  1188 + subsample_mask->data.ptr[i] = (uchar)1;
  1189 + // make all the initial weights the same.
  1190 + weights->data.db[i] = w0*p[classLabels[i]];
1226 1191 }
1227 1192  
1228 1193 if( params.boost_type == LOGIT )
... ... @@ -1424,6 +1389,5 @@ bool CascadeBoost::isErrDesired()
1424 1389 cout << "|" << endl;
1425 1390 cout << "+----+---------+---------+" << endl;
1426 1391  
1427   - qDebug() << falseAlarm << maxFalseAlarm;
1428 1392 return falseAlarm <= maxFalseAlarm;
1429 1393 }
... ...