Commit 74cfaa03328e572247d385c437a44e9ddb94efb4

Authored by Scott Klum
1 parent 08b73def

Started

Showing 1 changed file with 47 additions and 20 deletions
openbr/core/boost.cpp
1 #include <opencv2/imgproc/imgproc.hpp> 1 #include <opencv2/imgproc/imgproc.hpp>
  2 +#include <QDebug>
2 3
3 #include "boost.h" 4 #include "boost.h"
4 #include "cxmisc.h" 5 #include "cxmisc.h"
@@ -457,6 +458,7 @@ void CascadeBoostTrainData::setData( const FeatureEvaluator* _featureEvaluator, @@ -457,6 +458,7 @@ void CascadeBoostTrainData::setData( const FeatureEvaluator* _featureEvaluator,
457 458
458 valCache.create( numPrecalcVal, sample_count, CV_32FC1 ); 459 valCache.create( numPrecalcVal, sample_count, CV_32FC1 );
459 var_type = cvCreateMat( 1, var_count + 2, CV_32SC(channels) ); 460 var_type = cvCreateMat( 1, var_count + 2, CV_32SC(channels) );
  461 +
460 if ( featureEvaluator->getMaxCatCount() > 0 ) 462 if ( featureEvaluator->getMaxCatCount() > 0 )
461 { 463 {
462 numPrecalcIdx = 0; 464 numPrecalcIdx = 0;
@@ -484,9 +486,9 @@ void CascadeBoostTrainData::setData( const FeatureEvaluator* _featureEvaluator, @@ -484,9 +486,9 @@ void CascadeBoostTrainData::setData( const FeatureEvaluator* _featureEvaluator,
484 buf_size = -1; // the member buf_size is obsolete 486 buf_size = -1; // the member buf_size is obsolete
485 487
486 effective_buf_size = (uint64)(work_var_count + 1)*(uint64)sample_count * buf_count; // this is the total size of "CvMat buf" to be allocated 488 effective_buf_size = (uint64)(work_var_count + 1)*(uint64)sample_count * buf_count; // this is the total size of "CvMat buf" to be allocated
  489 +
487 effective_buf_width = sample_count; 490 effective_buf_width = sample_count;
488 effective_buf_height = work_var_count+1; 491 effective_buf_height = work_var_count+1;
489 -  
490 if (effective_buf_width >= effective_buf_height) 492 if (effective_buf_width >= effective_buf_height)
491 effective_buf_height *= buf_count; 493 effective_buf_height *= buf_count;
492 else 494 else
@@ -527,9 +529,9 @@ void CascadeBoostTrainData::setData( const FeatureEvaluator* _featureEvaluator, @@ -527,9 +529,9 @@ void CascadeBoostTrainData::setData( const FeatureEvaluator* _featureEvaluator,
527 529
528 // set sample labels 530 // set sample labels
529 if (is_buf_16u) 531 if (is_buf_16u)
530 - udst = (unsigned short*)(buf->data.s + work_var_count*sample_count); 532 + udst = (unsigned short*)(buf->data.s + (uint64)work_var_count*sample_count);
531 else 533 else
532 - idst = buf->data.i + work_var_count*sample_count; 534 + idst = buf->data.i + (uint64)work_var_count*sample_count;
533 535
534 for (int si = 0; si < sample_count; si++) 536 for (int si = 0; si < sample_count; si++)
535 { 537 {
@@ -568,7 +570,7 @@ const int* CascadeBoostTrainData::get_class_labels( CvDTreeNode* n, int* labelsB @@ -568,7 +570,7 @@ const int* CascadeBoostTrainData::get_class_labels( CvDTreeNode* n, int* labelsB
568 int nodeSampleCount = n->sample_count; 570 int nodeSampleCount = n->sample_count;
569 int rStep = CV_IS_MAT_CONT( responses->type ) ? 1 : responses->step / CV_ELEM_SIZE( responses->type ); 571 int rStep = CV_IS_MAT_CONT( responses->type ) ? 1 : responses->step / CV_ELEM_SIZE( responses->type );
570 572
571 - int* sampleIndicesBuf = labelsBuf; // 573 + int* sampleIndicesBuf = labelsBuf;
572 const int* sampleIndices = get_sample_indices(n, sampleIndicesBuf); 574 const int* sampleIndices = get_sample_indices(n, sampleIndicesBuf);
573 for( int si = 0; si < nodeSampleCount; si++ ) 575 for( int si = 0; si < nodeSampleCount; si++ )
574 { 576 {
@@ -580,12 +582,32 @@ const int* CascadeBoostTrainData::get_class_labels( CvDTreeNode* n, int* labelsB @@ -580,12 +582,32 @@ const int* CascadeBoostTrainData::get_class_labels( CvDTreeNode* n, int* labelsB
580 582
581 const int* CascadeBoostTrainData::get_sample_indices( CvDTreeNode* n, int* indicesBuf ) 583 const int* CascadeBoostTrainData::get_sample_indices( CvDTreeNode* n, int* indicesBuf )
582 { 584 {
583 - return CvDTreeTrainData::get_cat_var_data( n, get_work_var_count(), indicesBuf ); 585 + const uint64 vi = get_work_var_count();
  586 + const int* cat_values = 0;
  587 + if (!is_buf_16u)
  588 + cat_values = buf->data.i + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset;
  589 + else {
  590 + const unsigned short* short_values = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset);
  591 + for (int i = 0; i < n->sample_count; i++)
  592 + indicesBuf[i] = short_values[i];
  593 + cat_values = indicesBuf;
  594 + }
  595 + return cat_values;
584 } 596 }
585 597
586 -const int* CascadeBoostTrainData::get_cv_labels( CvDTreeNode* n, int* labels_buf ) 598 +const int* CascadeBoostTrainData::get_cv_labels( CvDTreeNode* n, int* indicesBuf )
587 { 599 {
588 - return CvDTreeTrainData::get_cat_var_data( n, get_work_var_count() - 1, labels_buf ); 600 + const uint64 vi = get_work_var_count()-1;
  601 + const int* cat_values = 0;
  602 + if (!is_buf_16u)
  603 + cat_values = buf->data.i + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset;
  604 + else {
  605 + const unsigned short* short_values = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset);
  606 + for (int i = 0; i < n->sample_count; i++)
  607 + indicesBuf[i] = short_values[i];
  608 + cat_values = indicesBuf;
  609 + }
  610 + return cat_values;
589 } 611 }
590 612
591 void CascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ordValuesBuf, int* sortedIndicesBuf, 613 void CascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ordValuesBuf, int* sortedIndicesBuf,
@@ -597,7 +619,7 @@ void CascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ord @@ -597,7 +619,7 @@ void CascadeBoostTrainData::get_ord_var_data( CvDTreeNode* n, int vi, float* ord
597 if ( vi < numPrecalcIdx ) 619 if ( vi < numPrecalcIdx )
598 { 620 {
599 if( !is_buf_16u ) 621 if( !is_buf_16u )
600 - *sortedIndices = buf->data.i + n->buf_idx*get_length_subbuf() + vi*sample_count + n->offset; 622 + *sortedIndices = buf->data.i + n->buf_idx*get_length_subbuf() + (uint64)vi*sample_count + n->offset;
601 else 623 else
602 { 624 {
603 const unsigned short* shortIndices = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() + 625 const unsigned short* shortIndices = (const unsigned short*)(buf->data.s + n->buf_idx*get_length_subbuf() +
@@ -744,17 +766,17 @@ struct FeatureValAndIdxPrecalc : ParallelLoopBody @@ -744,17 +766,17 @@ struct FeatureValAndIdxPrecalc : ParallelLoopBody
744 for ( int fi = range.start; fi < range.end; fi++) 766 for ( int fi = range.start; fi < range.end; fi++)
745 { 767 {
746 for( int si = 0; si < sample_count; si++ ) 768 for( int si = 0; si < sample_count; si++ )
747 - { 769 + {
748 valCache->at<float>(fi,si) = (*featureEvaluator)( fi, si ); 770 valCache->at<float>(fi,si) = (*featureEvaluator)( fi, si );
749 - if ( is_buf_16u )  
750 - *(udst + fi*sample_count + si) = (unsigned short)si; 771 + if ( is_buf_16u )
  772 + *(udst + (uint64)fi*sample_count + si) = (unsigned short)si;
751 else 773 else
752 - *(idst + fi*sample_count + si) = si; 774 + *(idst + (uint64)fi*sample_count + si) = si;
753 } 775 }
754 if ( is_buf_16u ) 776 if ( is_buf_16u )
755 - icvSortUShAux( udst + fi*sample_count, sample_count, valCache->ptr<float>(fi) ); 777 + icvSortUShAux( udst + (uint64)fi*sample_count, sample_count, valCache->ptr<float>(fi) );
756 else 778 else
757 - icvSortIntAux( idst + fi*sample_count, sample_count, valCache->ptr<float>(fi) ); 779 + icvSortIntAux( idst + (uint64)fi*sample_count, sample_count, valCache->ptr<float>(fi) );
758 } 780 }
759 } 781 }
760 const FeatureEvaluator* featureEvaluator; 782 const FeatureEvaluator* featureEvaluator;
@@ -1078,6 +1100,7 @@ void CascadeBoost::train(const FeatureEvaluator* _featureEvaluator, @@ -1078,6 +1100,7 @@ void CascadeBoost::train(const FeatureEvaluator* _featureEvaluator,
1078 { 1100 {
1079 CascadeBoostTree* tree = new CascadeBoostTree; 1101 CascadeBoostTree* tree = new CascadeBoostTree;
1080 if (!tree->train( data, subsample_mask, this)) { 1102 if (!tree->train( data, subsample_mask, this)) {
  1103 + qDebug() << "Deleting tree!";
1081 delete tree; 1104 delete tree;
1082 return; 1105 return;
1083 } 1106 }
@@ -1085,12 +1108,14 @@ void CascadeBoost::train(const FeatureEvaluator* _featureEvaluator, @@ -1085,12 +1108,14 @@ void CascadeBoost::train(const FeatureEvaluator* _featureEvaluator,
1085 classifiers.append(tree); 1108 classifiers.append(tree);
1086 update_weights(tree); 1109 update_weights(tree);
1087 trim_weights(); 1110 trim_weights();
1088 - if (cvCountNonZero(subsample_mask) == 0) 1111 + if (cvCountNonZero(subsample_mask) == 0) {
  1112 + qDebug() << "Subsample mask is empty!";
1089 return; 1113 return;
  1114 + }
1090 } 1115 }
1091 while (!isErrDesired() && (classifiers.size() < params.weak_count)); 1116 while (!isErrDesired() && (classifiers.size() < params.weak_count));
1092 1117
1093 - clear(); 1118 + //clear();
1094 } 1119 }
1095 1120
1096 float CascadeBoost::predict(int sampleIdx, bool returnSum) const 1121 float CascadeBoost::predict(int sampleIdx, bool returnSum) const
@@ -1101,6 +1126,7 @@ float CascadeBoost::predict(int sampleIdx, bool returnSum) const @@ -1101,6 +1126,7 @@ float CascadeBoost::predict(int sampleIdx, bool returnSum) const
1101 1126
1102 if (!returnSum) 1127 if (!returnSum)
1103 sum = sum < threshold - CV_THRESHOLD_EPS ? 0.0 : 1.0; 1128 sum = sum < threshold - CV_THRESHOLD_EPS ? 0.0 : 1.0;
  1129 +
1104 return (float)sum; 1130 return (float)sum;
1105 } 1131 }
1106 1132
@@ -1125,6 +1151,7 @@ void CascadeBoost::update_weights(CvBoostTree* tree) @@ -1125,6 +1151,7 @@ void CascadeBoost::update_weights(CvBoostTree* tree)
1125 ( !tree ? n*sizeof(int) : 0 ); 1151 ( !tree ? n*sizeof(int) : 0 );
1126 cv::AutoBuffer<uchar> inn_buf(inn_buf_size); 1152 cv::AutoBuffer<uchar> inn_buf(inn_buf_size);
1127 uchar* cur_inn_buf_pos = (uchar*)inn_buf; 1153 uchar* cur_inn_buf_pos = (uchar*)inn_buf;
  1154 +
1128 if ( (params.boost_type == LOGIT) || (params.boost_type == GENTLE) ) 1155 if ( (params.boost_type == LOGIT) || (params.boost_type == GENTLE) )
1129 { 1156 {
1130 step = CV_IS_MAT_CONT(data->responses_copy->type) ? 1157 step = CV_IS_MAT_CONT(data->responses_copy->type) ?
@@ -1133,6 +1160,7 @@ void CascadeBoost::update_weights(CvBoostTree* tree) @@ -1133,6 +1160,7 @@ void CascadeBoost::update_weights(CvBoostTree* tree)
1133 sampleIdxBuf = (int*)cur_inn_buf_pos; cur_inn_buf_pos = (uchar*)(sampleIdxBuf + n); 1160 sampleIdxBuf = (int*)cur_inn_buf_pos; cur_inn_buf_pos = (uchar*)(sampleIdxBuf + n);
1134 sampleIdx = data->get_sample_indices( data->data_root, sampleIdxBuf ); 1161 sampleIdx = data->get_sample_indices( data->data_root, sampleIdxBuf );
1135 } 1162 }
  1163 +
1136 CvMat* buf = data->buf; 1164 CvMat* buf = data->buf;
1137 size_t length_buf_row = data->get_length_subbuf(); 1165 size_t length_buf_row = data->get_length_subbuf();
1138 if( !tree ) // before training the first tree, initialize weights and other parameters 1166 if( !tree ) // before training the first tree, initialize weights and other parameters
@@ -1158,8 +1186,7 @@ void CascadeBoost::update_weights(CvBoostTree* tree) @@ -1158,8 +1186,7 @@ void CascadeBoost::update_weights(CvBoostTree* tree)
1158 1186
1159 if (data->is_buf_16u) 1187 if (data->is_buf_16u)
1160 { 1188 {
1161 - unsigned short* labels = (unsigned short*)(buf->data.s + data->data_root->buf_idx*length_buf_row +  
1162 - data->data_root->offset + (data->work_var_count-1)*data->sample_count); 1189 + 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);
1163 for( int i = 0; i < n; i++ ) 1190 for( int i = 0; i < n; i++ )
1164 { 1191 {
1165 // save original categorical responses {0,1}, convert them to {-1,1} 1192 // save original categorical responses {0,1}, convert them to {-1,1}
@@ -1176,8 +1203,7 @@ void CascadeBoost::update_weights(CvBoostTree* tree) @@ -1176,8 +1203,7 @@ void CascadeBoost::update_weights(CvBoostTree* tree)
1176 } 1203 }
1177 else 1204 else
1178 { 1205 {
1179 - int* labels = buf->data.i + data->data_root->buf_idx*length_buf_row +  
1180 - data->data_root->offset + (data->work_var_count-1)*data->sample_count; 1206 + 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;
1181 1207
1182 for( int i = 0; i < n; i++ ) 1208 for( int i = 0; i < n; i++ )
1183 { 1209 {
@@ -1388,5 +1414,6 @@ bool CascadeBoost::isErrDesired() @@ -1388,5 +1414,6 @@ bool CascadeBoost::isErrDesired()
1388 cout << "|" << endl; 1414 cout << "|" << endl;
1389 cout << "+----+---------+---------+" << endl; 1415 cout << "+----+---------+---------+" << endl;
1390 1416
  1417 + qDebug() << falseAlarm << maxFalseAlarm;
1391 return falseAlarm <= maxFalseAlarm; 1418 return falseAlarm <= maxFalseAlarm;
1392 } 1419 }