]> rtime.felk.cvut.cz Git - opencv.git/blobdiff - opencv/apps/traincascade/boost.cpp
converted traincascade from OpenMP to TBB
[opencv.git] / opencv / apps / traincascade / boost.cpp
index 09ae6bd35507463397b249cc843a20c929ba9b34..c4bc82899faa338747d10ec5706eef74ee3e2e7c 100755 (executable)
@@ -1,6 +1,7 @@
 #include "boost.h"
 #include "cascadeclassifier.h"
 #include <queue>
+
 using namespace std;
 
 static inline double
@@ -29,7 +30,8 @@ static const int BlockSizeDelta = 1 << 10;
 
 CvCascadeBoostParams::CvCascadeBoostParams() : minHitRate( 0.995F), maxFalseAlarm( 0.5F )
 {  
-    boost_type = CvBoost::GENTLE; 
+    boost_type = CvBoost::GENTLE;
+    use_surrogates = use_1se_rule = truncate_pruned_tree = false;
 }
 
 CvCascadeBoostParams::CvCascadeBoostParams( int _boostType,
@@ -40,6 +42,7 @@ CvCascadeBoostParams::CvCascadeBoostParams( int _boostType,
     boost_type = CvBoost::GENTLE;
     minHitRate = _minHitRate;
     maxFalseAlarm = _maxFalseAlarm;
+    use_surrogates = use_1se_rule = truncate_pruned_tree = false;
 }
 
 void CvCascadeBoostParams::write( FileStorage &fs ) const
@@ -194,15 +197,15 @@ CvCascadeBoostTrainData::CvCascadeBoostTrainData( const CvFeatureEvaluator* _fea
 
 CvCascadeBoostTrainData::CvCascadeBoostTrainData( const CvFeatureEvaluator* _featureEvaluator,
                                                  int _numSamples,
-                                                 int _numPrecalcVal, int _numPrecalcIdx,
+                                                 int _precalcValBufSize, int _precalcIdxBufSize,
                                                  const CvDTreeParams& _params )
 {
-    setData( _featureEvaluator, _numSamples, _numPrecalcVal, _numPrecalcIdx, _params );
+    setData( _featureEvaluator, _numSamples, _precalcValBufSize, _precalcIdxBufSize, _params );
 }
  
 void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluator,
                                       int _numSamples,
-                                      int _numPrecalcVal, int _numPrecalcIdx,
+                                      int _precalcValBufSize, int _precalcIdxBufSize,
                                                                          const CvDTreeParams& _params )
 {    
     int* idst = 0;
@@ -226,19 +229,21 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat
     responses = &_resp;
     // TODO: check responses: elements must be 0 or 1
     
-       if( _numPrecalcVal < 0 || _numPrecalcIdx < 0)
+       if( _precalcValBufSize < 0 || _precalcIdxBufSize < 0)
         CV_Error( CV_StsOutOfRange, "_numPrecalcVal and _numPrecalcIdx must be positive or 0" );
 
        var_count = var_all = featureEvaluator->getNumFeatures();
     sample_count = _numSamples;
-       numPrecalcVal = min( _numPrecalcVal, var_count );
-       numPrecalcIdx = min( _numPrecalcIdx, var_count );
     
     is_buf_16u = false;     
     if (sample_count < 65536) 
-        is_buf_16u = true;                               
+        is_buf_16u = true; 
+
+       numPrecalcVal = min( (_precalcValBufSize*1048576) / int(sizeof(float)*sample_count), var_count );
+    numPrecalcIdx = min( (_precalcIdxBufSize*1048576) /
+                int((is_buf_16u ? sizeof(unsigned short) : sizeof (int))*sample_count), var_count );
 
-    valCache.create( numPrecalcVal ? numPrecalcVal : 1, sample_count, CV_32FC1 );
+    valCache.create( numPrecalcVal, sample_count, CV_32FC1 );
     var_type = cvCreateMat( 1, var_count + 2, CV_32SC1 );
     
     if ( featureEvaluator->getMaxCatCount() > 0 ) 
@@ -262,7 +267,7 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat
     }
     var_type->data.i[var_count] = cat_var_count;
     var_type->data.i[var_count+1] = cat_var_count+1;
-    work_var_count = ( cat_var_count ? var_count : numPrecalcIdx ) + 1;
+    work_var_count = ( cat_var_count ? 0 : numPrecalcIdx ) + 1;
     buf_size = (work_var_count + 1) * sample_count;
     buf_count = 2;
     
@@ -272,12 +277,6 @@ void CvCascadeBoostTrainData::setData( const CvFeatureEvaluator* _featureEvaluat
         buf = cvCreateMat( buf_count, buf_size, CV_32SC1 );
 
     cat_count = cvCreateMat( 1, cat_var_count + 1, CV_32SC1 );
-    pred_float_buf = (float*)cvAlloc(sample_count*sizeof(pred_float_buf[0]));
-    pred_int_buf = (int*)cvAlloc(sample_count*sizeof(pred_int_buf[0]));
-    resp_float_buf = (float*)cvAlloc(sample_count*sizeof(resp_float_buf[0]));
-    resp_int_buf = (int*)cvAlloc(sample_count*sizeof(resp_int_buf[0]));
-    cv_lables_buf = (int*)cvAlloc(sample_count*sizeof(cv_lables_buf[0]));
-    sample_idx_buf = (int*)cvAlloc(sample_count*sizeof(sample_idx_buf[0]));
 
     // precalculate valCache and set indices in buf
        precalculate();
@@ -339,59 +338,55 @@ void CvCascadeBoostTrainData::free_train_data()
     valCache.release();
 }
 
-void CvCascadeBoostTrainData::get_class_labels( CvDTreeNode* n, int* labelsBuf, const int** labels )
+const int* CvCascadeBoostTrainData::get_class_labels( CvDTreeNode* n, int* labelsBuf)
 {
     int nodeSampleCount = n->sample_count; 
-    int* sampleIndicesBuf = sample_idx_buf;
-    const int* sampleIndices = 0;
     int rStep = CV_IS_MAT_CONT( responses->type ) ? 1 : responses->step / CV_ELEM_SIZE( responses->type );
 
-    get_sample_indices(n, sampleIndicesBuf, &sampleIndices);
-
+    int* sampleIndicesBuf = labelsBuf; //
+    const int* sampleIndices = get_sample_indices(n, sampleIndicesBuf);
     for( int si = 0; si < nodeSampleCount; si++ )
     {
         int sidx = sampleIndices[si];
         labelsBuf[si] = (int)responses->data.fl[sidx*rStep];
     }    
-    *labels = labelsBuf;
+    return labelsBuf;
 }
 
-void CvCascadeBoostTrainData::get_sample_indices( CvDTreeNode* n, int* indicesBuf, const int** indices )
+const int* CvCascadeBoostTrainData::get_sample_indices( CvDTreeNode* n, int* indicesBuf )
 {
-    CvDTreeTrainData::get_cat_var_data( n, get_work_var_count(), indicesBuf, indices );
+    return CvDTreeTrainData::get_cat_var_data( n, get_work_var_count(), indicesBuf );
 }
 
-void CvCascadeBoostTrainData::get_cv_labels( CvDTreeNode* n, int* labels_buf, const int** labels )
+const int* CvCascadeBoostTrainData::get_cv_labels( CvDTreeNode* n, int* labels_buf )
 {
-    CvDTreeTrainData::get_cat_var_data( n, get_work_var_count()- 1, labels_buf, labels );
+    return CvDTreeTrainData::get_cat_var_data( n, get_work_var_count() - 1, labels_buf );
 }
 
-int CvCascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ordValuesBuf, int* indicesBuf,
-        const float** ordValues, const int** indices )
+void CvCascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ordValuesBuf, int* sortedIndicesBuf,
+        const float** ordValues, const int** sortedIndices, int* sampleIndicesBuf )
 {
     int nodeSampleCount = n->sample_count; 
-    int* sampleIndicesBuf = sample_idx_buf;
-    const int* sampleIndices = 0;
-    get_sample_indices(n, sampleIndicesBuf, &sampleIndices);
+    const int* sampleIndices = get_sample_indices(n, sampleIndicesBuf);
     
        if ( vi < numPrecalcIdx )
        {
                if( !is_buf_16u )
-               *indices = buf->data.i + n->buf_idx*buf->cols + vi*sample_count + n->offset;
+            *sortedIndices = buf->data.i + n->buf_idx*buf->cols + vi*sample_count + n->offset;
            else 
         {
                const unsigned short* shortIndices = (const unsigned short*)(buf->data.s + n->buf_idx*buf->cols + 
                                                      vi*sample_count + n->offset );
                for( int i = 0; i < nodeSampleCount; i++ )
-                   indicesBuf[i] = shortIndices[i];
-               *indices = indicesBuf;
+                sortedIndicesBuf[i] = shortIndices[i];
+            *sortedIndices = sortedIndicesBuf;
            }
                
                if ( vi < numPrecalcVal )
                {
                        for( int i = 0; i < nodeSampleCount; i++ )
                {
-                   int idx = (*indices)[i];
+                int idx = (*sortedIndices)[i];
                    idx = sampleIndices[idx];
                    ordValuesBuf[i] =  valCache.at<float>( vi, idx);
                }
@@ -400,7 +395,7 @@ int CvCascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* or
                {
                        for( int i = 0; i < nodeSampleCount; i++ )
                {
-                   int idx = (*indices)[i];
+                int idx = (*sortedIndices)[i];
                    idx = sampleIndices[idx];
                                ordValuesBuf[i] = (*featureEvaluator)( vi, idx);
                        }
@@ -413,34 +408,32 @@ int CvCascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* or
                {
                        for( int i = 0; i < nodeSampleCount; i++ )
                {
-                               indicesBuf[i] = i;
+                sortedIndicesBuf[i] = i;
                    ((float*)sampleIndices)[i] = valCache.at<float>( vi, sampleIndices[i] );
                }
                }
                else
                {
-                       for( int i = 0; i < nodeSampleCount; i++ )
+            for( int i = 0; i < nodeSampleCount; i++ )
                {
-                               indicesBuf[i] = i;
+                sortedIndicesBuf[i] = i;
                                ((float*)sampleIndices)[i] = (*featureEvaluator)( vi, sampleIndices[i]);
                        }
                }
-               icvSortIntAux( indicesBuf, sample_count, (float *)sampleIndices );
+        icvSortIntAux( sortedIndicesBuf, sample_count, (float *)sampleIndices );
                for( int i = 0; i < nodeSampleCount; i++ )
-               ordValuesBuf[i] = ((float*)sampleIndices)[indicesBuf[i]];
-               *indices = indicesBuf;
+            ordValuesBuf[i] = ((float*)sampleIndices)[sortedIndicesBuf[i]];
+        *sortedIndices = sortedIndicesBuf;
        }
        
     *ordValues = ordValuesBuf;
-    return 0;
 }
  
-int CvCascadeBoostTrainData::get_cat_var_data( CvDTreeNode* n, int vi, int* catValuesBuf, const int** catValues )
+const int* CvCascadeBoostTrainData::get_cat_var_data( CvDTreeNode* n, int vi, int* catValuesBuf)
 {
     int nodeSampleCount = n->sample_count; 
-    int* sampleIndicesBuf = sample_idx_buf;
-    const int* sampleIndices = 0;
-    get_sample_indices(n, sampleIndicesBuf, &sampleIndices);
+    int* sampleIndicesBuf = catValuesBuf; //
+    const int* sampleIndices = get_sample_indices(n, sampleIndicesBuf);
 
     if ( vi < numPrecalcVal )
        {
@@ -452,9 +445,7 @@ int CvCascadeBoostTrainData::get_cat_var_data( CvDTreeNode* n, int vi, int* catV
                for( int i = 0; i < nodeSampleCount; i++ )
                        catValuesBuf[i] = (int)(*featureEvaluator)( vi, sampleIndices[i] );
        }
-    *catValues = catValuesBuf;
-    
-    return 0;
+    return catValuesBuf;
 }
 
 float CvCascadeBoostTrainData::getVarValue( int vi, int si )
@@ -464,51 +455,112 @@ float CvCascadeBoostTrainData::getVarValue( int vi, int si )
        return (*featureEvaluator)( vi, si );
 }
 
-void CvCascadeBoostTrainData::precalculate()
+
+struct FeatureIdxOnlyPrecalc
 {
-    int minNum = MIN( numPrecalcVal, numPrecalcIdx);
-    unsigned short* udst = (unsigned short*)buf->data.s;
-    int* idst = buf->data.i;
-    
-    CV_DbgAssert( !valCache.empty() );
-    double proctime = -TIME( 0 );
-       
-    for ( int fi = numPrecalcVal; fi < numPrecalcIdx; fi++)
+    FeatureIdxOnlyPrecalc( const CvFeatureEvaluator* _feval, CvMat* _buf, int _sample_count, bool _is_buf_16u )
+    {
+        feval = _feval;
+        sample_count = _sample_count;
+        udst = (unsigned short*)_buf->data.s;
+        idst = _buf->data.i;
+        is_buf_16u = _is_buf_16u;
+    }
+    void operator()( const BlockedRange& range ) const
     {
-        for( int si = 0; si < sample_count; si++ )
+        cv::AutoBuffer<float> valCache(sample_count);
+        float* valCachePtr = (float*)valCache;
+        for ( int fi = range.begin(); fi < range.end(); fi++)
         {
-            valCache.ptr<float>(0)[si] = (*featureEvaluator)( fi, si );
+            for( int si = 0; si < sample_count; si++ )
+            {
+                valCachePtr[si] = (*feval)( fi, si );
+                if ( is_buf_16u )
+                    *(udst + fi*sample_count + si) = (unsigned short)si;
+                else
+                    *(idst + fi*sample_count + si) = si;
+            }
             if ( is_buf_16u )
-                *(udst + fi*sample_count + si) = (unsigned short)si;
+                icvSortUShAux( udst + fi*sample_count, sample_count, valCachePtr );
             else
-                *(idst + fi*sample_count + si) = si;
+                icvSortIntAux( idst + fi*sample_count, sample_count, valCachePtr );
         }
-        if ( is_buf_16u )
-            icvSortUShAux( udst + fi*sample_count, sample_count, (float*)valCache.data );
-        else
-            icvSortIntAux( idst + fi*sample_count, sample_count, (float*)valCache.data );
     }
-
-    for ( int fi = 0; fi < minNum; fi++)
+    const CvFeatureEvaluator* feval;
+    int sample_count;
+    int* idst;
+    unsigned short* udst;
+    bool is_buf_16u;
+};
+
+struct FeatureValAndIdxPrecalc
+{
+    FeatureValAndIdxPrecalc( const CvFeatureEvaluator* _feval, CvMat* _buf, Mat* _valCache, int _sample_count, bool _is_buf_16u )
+    {
+        feval = _feval;
+        valCache = _valCache;
+        sample_count = _sample_count;
+        udst = (unsigned short*)_buf->data.s;
+        idst = _buf->data.i;
+        is_buf_16u = _is_buf_16u;
+    }
+    void operator()( const BlockedRange& range ) const
     {
-        for( int si = 0; si < sample_count; si++ )
+        for ( int fi = range.begin(); fi < range.end(); fi++)
         {
-            valCache.ptr<float>(fi)[si] = (*featureEvaluator)( fi, si );
+            for( int si = 0; si < sample_count; si++ )
+            {
+                valCache->at<float>(fi,si) = (*feval)( fi, si );
+                if ( is_buf_16u )
+                    *(udst + fi*sample_count + si) = (unsigned short)si;
+                else
+                    *(idst + fi*sample_count + si) = si;
+            }
             if ( is_buf_16u )
-                *(udst + fi*sample_count + si) = (unsigned short)si;
+                icvSortUShAux( udst + fi*sample_count, sample_count, valCache->ptr<float>(fi) );
             else
-                *(idst + fi*sample_count + si) = si;
+                icvSortIntAux( idst + fi*sample_count, sample_count, valCache->ptr<float>(fi) );
         }
-        if ( is_buf_16u )
-            icvSortUShAux( udst + fi*sample_count, sample_count, (float*)valCache.data );
-        else
-            icvSortIntAux( idst + fi*sample_count, sample_count, (float*)valCache.data );
     }
+    const CvFeatureEvaluator* feval;
+    Mat* valCache;
+    int sample_count;
+    int* idst;
+    unsigned short* udst;
+    bool is_buf_16u;
+};
+
+struct FeatureValOnlyPrecalc
+{
+    FeatureValOnlyPrecalc( const CvFeatureEvaluator* _feval, Mat* _valCache, int _sample_count )
+    {
+        feval = _feval;
+        valCache = _valCache;
+        sample_count = _sample_count;
+    }
+    void operator()( const BlockedRange& range ) const
+    {
+        for ( int fi = range.begin(); fi < range.end(); fi++)
+            for( int si = 0; si < sample_count; si++ )
+                valCache->at<float>(fi,si) = (*feval)( fi, si );
+    }
+    const CvFeatureEvaluator* feval;
+    Mat* valCache;
+    int sample_count;
+};
 
-    for ( int fi = minNum; fi < numPrecalcVal; fi++)
-        for( int si = 0; si < sample_count; si++ )
-            valCache.ptr<float>(fi)[si] = (*featureEvaluator)( fi, si );
+void CvCascadeBoostTrainData::precalculate()
+{
+    int minNum = MIN( numPrecalcVal, numPrecalcIdx);
+    CV_DbgAssert( !valCache.empty() );
 
+    double proctime = -TIME( 0 );
+    parallel_for( BlockedRange(numPrecalcVal, numPrecalcIdx),
+                  FeatureIdxOnlyPrecalc(featureEvaluator, buf, sample_count, is_buf_16u) );
+    parallel_for( BlockedRange(0, minNum),
+                  FeatureValAndIdxPrecalc(featureEvaluator, buf, &valCache, sample_count, is_buf_16u) );
+    parallel_for( BlockedRange(minNum, numPrecalcVal),
+                  FeatureValOnlyPrecalc(featureEvaluator, &valCache, sample_count) );
     cout << "Precalculation time: " << (proctime + TIME( 0 )) << endl;
 }
 
@@ -630,23 +682,23 @@ void CvCascadeBoostTree::read( const FileNode &node, CvBoost* _ensemble,
             prntNode->split = data->new_split_cat( 0, 0 );
             for( int j = subsetN-1; j>=0; j--)
             {
-                internalNodesIt >> prntNode->split->subset[j]; internalNodesIt -=2;
+                *internalNodesIt >> prntNode->split->subset[j]; internalNodesIt--;
             }
         }
         else
         {
             float split_value;
-            internalNodesIt >> split_value; internalNodesIt -=2;
+            *internalNodesIt >> split_value; internalNodesIt--;
             prntNode->split = data->new_split_ord( 0, split_value, 0, 0, 0);
         }
-        internalNodesIt >> prntNode->split->var_idx; internalNodesIt -=2;
+        *internalNodesIt >> prntNode->split->var_idx; internalNodesIt--;
         int ridx, lidx;
-        internalNodesIt >> ridx; internalNodesIt -=2;
-        internalNodesIt >> lidx;internalNodesIt -=2;
+        *internalNodesIt >> ridx; internalNodesIt--;
+        *internalNodesIt >> lidx;internalNodesIt--;
         if ( ridx <= 0)
         {
             prntNode->right = cldNode = data->new_node( 0, 0, 0, 0 );
-            leafValsuesIt >> cldNode->value; leafValsuesIt-=2;
+            *leafValsuesIt >> cldNode->value; leafValsuesIt--;
             cldNode->parent = prntNode;            
         }
         else
@@ -659,7 +711,7 @@ void CvCascadeBoostTree::read( const FileNode &node, CvBoost* _ensemble,
         if ( lidx <= 0)
         {
             prntNode->left = cldNode = data->new_node( 0, 0, 0, 0 );
-            leafValsuesIt >> cldNode->value; leafValsuesIt-=2;
+            *leafValsuesIt >> cldNode->value; leafValsuesIt--;
             cldNode->parent = prntNode;            
         }
         else
@@ -685,7 +737,8 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
     int newBufIdx = data->get_child_buf_idx( node );
     int workVarCount = data->get_work_var_count();
     CvMat* buf = data->buf;
-    int* tempBuf = (int*)cvStackAlloc(n*sizeof(tempBuf[0]));
+    cv::AutoBuffer<uchar> inn_buf(n*(3*sizeof(int)+sizeof(float)));
+    int* tempBuf = (int*)(uchar*)inn_buf;
     bool splitInputData;
 
     complete_node_dir(node);
@@ -706,23 +759,23 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
         (node->left->sample_count > data->params.min_sample_count ||
         node->right->sample_count > data->params.min_sample_count);
 
-       // split ordered variables, keep both halves sorted.
+    // split ordered variables, keep both halves sorted.
     for( int vi = 0; vi < ((CvCascadeBoostTrainData*)data)->numPrecalcIdx; vi++ )
     {
         int ci = data->get_var_type(vi);
-        int n1 = node->get_num_valid(vi);
-        int *src_idx_buf = data->pred_int_buf;
-        const int* src_idx = 0;
-        float *src_val_buf = data->pred_float_buf;
-        const float* src_val = 0;
-        
         if( ci >= 0 || !splitInputData )
             continue;
 
-        data->get_ord_var_data(node, vi, src_val_buf, src_idx_buf, &src_val, &src_idx);
+        int n1 = node->get_num_valid(vi);
+        float *src_val_buf = (float*)(tempBuf + n);
+        int *src_sorted_idx_buf = (int*)(src_val_buf + n);
+        int *src_sample_idx_buf = src_sorted_idx_buf + n;
+        const int* src_sorted_idx = 0;
+        const float* src_val = 0;
+        data->get_ord_var_data(node, vi, src_val_buf, src_sorted_idx_buf, &src_val, &src_sorted_idx, src_sample_idx_buf);
 
         for(int i = 0; i < n; i++)
-            tempBuf[i] = src_idx[i];
+            tempBuf[i] = src_sorted_idx[i];
 
         if (data->is_buf_16u)
         {
@@ -786,9 +839,8 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
     }
 
     // split cv_labels using newIdx relocation table
-    int *src_lbls_buf = data->pred_int_buf;
-    const int* src_lbls = 0;
-    data->get_cv_labels(node, src_lbls_buf, &src_lbls);
+    int *src_lbls_buf = tempBuf + n;
+    const int* src_lbls = data->get_cv_labels(node, src_lbls_buf);
 
     for(int i = 0; i < n; i++)
         tempBuf[i] = src_lbls[i];
@@ -845,9 +897,8 @@ void CvCascadeBoostTree::split_node_data( CvDTreeNode* node )
     }
 
     // split sample indices
-    int *sampleIdx_src_buf = data->sample_idx_buf;
-    const int* sampleIdx_src = 0;
-    data->get_sample_indices(node, sampleIdx_src_buf, &sampleIdx_src);
+    int *sampleIdx_src_buf = tempBuf + n;
+    const int* sampleIdx_src = data->get_sample_indices(node, sampleIdx_src_buf);
 
     for(int i = 0; i < n; i++)
         tempBuf[i] = sampleIdx_src[i];
@@ -918,13 +969,13 @@ void CvCascadeBoostTree::markFeaturesInMap( Mat& featureMap )
 
 bool CvCascadeBoost::train( const CvFeatureEvaluator* _featureEvaluator,
                            int _numSamples,
-                           int _numPrecalcVal, int _numPrecalcIdx,
+                           int _precalcValBufSize, int _precalcIdxBufSize,
                            const CvCascadeBoostParams& _params )
 {
     CV_Assert( !data );
     clear();
     data = new CvCascadeBoostTrainData( _featureEvaluator, _numSamples,
-                                        _numPrecalcVal, _numPrecalcIdx, _params );
+                                        _precalcValBufSize, _precalcIdxBufSize, _params );
     CvMemStorage *storage = cvCreateMemStorage();
     weak = cvCreateSeq( 0, sizeof(CvSeq), sizeof(CvBoostTree*), storage );
     storage = 0;
@@ -995,26 +1046,25 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree )
     float* fdata = 0;
     int *sampleIdxBuf;
     const int* sampleIdx = 0;
+    int inn_buf_size = ((params.boost_type == LOGIT) || (params.boost_type == GENTLE) ? n*sizeof(int) : 0) +
+                       ( !tree ? n*sizeof(int) : 0 );
+    cv::AutoBuffer<uchar> inn_buf(inn_buf_size);
+    uchar* cur_inn_buf_pos = (uchar*)inn_buf;
     if ( (params.boost_type == LOGIT) || (params.boost_type == GENTLE) )
     {
         step = CV_IS_MAT_CONT(data->responses_copy->type) ?
             1 : data->responses_copy->step / CV_ELEM_SIZE(data->responses_copy->type);
         fdata = data->responses_copy->data.fl;
-        sampleIdxBuf = (int*)cvStackAlloc(data->sample_count*sizeof(sampleIdxBuf[0]));
-        data->get_sample_indices( data->data_root, sampleIdxBuf, &sampleIdx );    
+        sampleIdxBuf = (int*)cur_inn_buf_pos; cur_inn_buf_pos = (uchar*)(sampleIdxBuf + n);
+        sampleIdx = data->get_sample_indices( data->data_root, sampleIdxBuf );
     }
     CvMat* buf = data->buf;
     if( !tree ) // before training the first tree, initialize weights and other parameters
     {
-        int* classLabelsBuf = data->resp_int_buf;
-        const int* classLabels = 0;
-        data->get_class_labels(data->data_root, classLabelsBuf, &classLabels);
+        int* classLabelsBuf = (int*)cur_inn_buf_pos; cur_inn_buf_pos = (uchar*)(classLabelsBuf + n);
+        const int* classLabels = data->get_class_labels(data->data_root, classLabelsBuf);
         // in case of logitboost and gentle adaboost each weak tree is a regression tree,
         // so we need to convert class labels to floating-point values
-        float* responses_buf = data->resp_float_buf;
-        const float* responses = 0;
-        data->get_ord_responses(data->data_root, responses_buf, &responses);
-        
         double w0 = 1./n;
         double p[2] = { 1, 1 };
 
@@ -1169,9 +1219,6 @@ void CvCascadeBoost::update_weights( CvBoostTree* tree )
 
             const double lbWeightThresh = FLT_EPSILON;
             const double lbZMax = 10.;
-            float* responsesBuf = data->resp_float_buf;
-            const float* responses = 0;
-            data->get_ord_responses(data->data_root, responsesBuf, &responses);
 
             for( int i = 0; i < n; i++ )
             {
@@ -1316,4 +1363,4 @@ void CvCascadeBoost::markUsedFeaturesInMap( Mat& featureMap )
         CvCascadeBoostTree* weakTree = *((CvCascadeBoostTree**) cvGetSeqElem( weak, wi ));
         weakTree->markFeaturesInMap( featureMap );
     }
-}
\ No newline at end of file
+}