Commit 74cfaa03328e572247d385c437a44e9ddb94efb4
1 parent
08b73def
Started
Showing
1 changed file
with
47 additions
and
20 deletions
openbr/core/boost.cpp
| 1 | 1 | #include <opencv2/imgproc/imgproc.hpp> |
| 2 | +#include <QDebug> | |
| 2 | 3 | |
| 3 | 4 | #include "boost.h" |
| 4 | 5 | #include "cxmisc.h" |
| ... | ... | @@ -457,6 +458,7 @@ void CascadeBoostTrainData::setData( const FeatureEvaluator* _featureEvaluator, |
| 457 | 458 | |
| 458 | 459 | valCache.create( numPrecalcVal, sample_count, CV_32FC1 ); |
| 459 | 460 | var_type = cvCreateMat( 1, var_count + 2, CV_32SC(channels) ); |
| 461 | + | |
| 460 | 462 | if ( featureEvaluator->getMaxCatCount() > 0 ) |
| 461 | 463 | { |
| 462 | 464 | numPrecalcIdx = 0; |
| ... | ... | @@ -484,9 +486,9 @@ void CascadeBoostTrainData::setData( const FeatureEvaluator* _featureEvaluator, |
| 484 | 486 | buf_size = -1; // the member buf_size is obsolete |
| 485 | 487 | |
| 486 | 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 | 490 | effective_buf_width = sample_count; |
| 488 | 491 | effective_buf_height = work_var_count+1; |
| 489 | - | |
| 490 | 492 | if (effective_buf_width >= effective_buf_height) |
| 491 | 493 | effective_buf_height *= buf_count; |
| 492 | 494 | else |
| ... | ... | @@ -527,9 +529,9 @@ void CascadeBoostTrainData::setData( const FeatureEvaluator* _featureEvaluator, |
| 527 | 529 | |
| 528 | 530 | // set sample labels |
| 529 | 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 | 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 | 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 | 570 | int nodeSampleCount = n->sample_count; |
| 569 | 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 | 574 | const int* sampleIndices = get_sample_indices(n, sampleIndicesBuf); |
| 573 | 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 | 582 | |
| 581 | 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 | 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 | 619 | if ( vi < numPrecalcIdx ) |
| 598 | 620 | { |
| 599 | 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 | 623 | else |
| 602 | 624 | { |
| 603 | 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 | 766 | for ( int fi = range.start; fi < range.end; fi++) |
| 745 | 767 | { |
| 746 | 768 | for( int si = 0; si < sample_count; si++ ) |
| 747 | - { | |
| 769 | + { | |
| 748 | 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 | 773 | else |
| 752 | - *(idst + fi*sample_count + si) = si; | |
| 774 | + *(idst + (uint64)fi*sample_count + si) = si; | |
| 753 | 775 | } |
| 754 | 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 | 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 | 782 | const FeatureEvaluator* featureEvaluator; |
| ... | ... | @@ -1078,6 +1100,7 @@ void CascadeBoost::train(const FeatureEvaluator* _featureEvaluator, |
| 1078 | 1100 | { |
| 1079 | 1101 | CascadeBoostTree* tree = new CascadeBoostTree; |
| 1080 | 1102 | if (!tree->train( data, subsample_mask, this)) { |
| 1103 | + qDebug() << "Deleting tree!"; | |
| 1081 | 1104 | delete tree; |
| 1082 | 1105 | return; |
| 1083 | 1106 | } |
| ... | ... | @@ -1085,12 +1108,14 @@ void CascadeBoost::train(const FeatureEvaluator* _featureEvaluator, |
| 1085 | 1108 | classifiers.append(tree); |
| 1086 | 1109 | update_weights(tree); |
| 1087 | 1110 | trim_weights(); |
| 1088 | - if (cvCountNonZero(subsample_mask) == 0) | |
| 1111 | + if (cvCountNonZero(subsample_mask) == 0) { | |
| 1112 | + qDebug() << "Subsample mask is empty!"; | |
| 1089 | 1113 | return; |
| 1114 | + } | |
| 1090 | 1115 | } |
| 1091 | 1116 | while (!isErrDesired() && (classifiers.size() < params.weak_count)); |
| 1092 | 1117 | |
| 1093 | - clear(); | |
| 1118 | + //clear(); | |
| 1094 | 1119 | } |
| 1095 | 1120 | |
| 1096 | 1121 | float CascadeBoost::predict(int sampleIdx, bool returnSum) const |
| ... | ... | @@ -1101,6 +1126,7 @@ float CascadeBoost::predict(int sampleIdx, bool returnSum) const |
| 1101 | 1126 | |
| 1102 | 1127 | if (!returnSum) |
| 1103 | 1128 | sum = sum < threshold - CV_THRESHOLD_EPS ? 0.0 : 1.0; |
| 1129 | + | |
| 1104 | 1130 | return (float)sum; |
| 1105 | 1131 | } |
| 1106 | 1132 | |
| ... | ... | @@ -1125,6 +1151,7 @@ void CascadeBoost::update_weights(CvBoostTree* tree) |
| 1125 | 1151 | ( !tree ? n*sizeof(int) : 0 ); |
| 1126 | 1152 | cv::AutoBuffer<uchar> inn_buf(inn_buf_size); |
| 1127 | 1153 | uchar* cur_inn_buf_pos = (uchar*)inn_buf; |
| 1154 | + | |
| 1128 | 1155 | if ( (params.boost_type == LOGIT) || (params.boost_type == GENTLE) ) |
| 1129 | 1156 | { |
| 1130 | 1157 | step = CV_IS_MAT_CONT(data->responses_copy->type) ? |
| ... | ... | @@ -1133,6 +1160,7 @@ void CascadeBoost::update_weights(CvBoostTree* tree) |
| 1133 | 1160 | sampleIdxBuf = (int*)cur_inn_buf_pos; cur_inn_buf_pos = (uchar*)(sampleIdxBuf + n); |
| 1134 | 1161 | sampleIdx = data->get_sample_indices( data->data_root, sampleIdxBuf ); |
| 1135 | 1162 | } |
| 1163 | + | |
| 1136 | 1164 | CvMat* buf = data->buf; |
| 1137 | 1165 | size_t length_buf_row = data->get_length_subbuf(); |
| 1138 | 1166 | if( !tree ) // before training the first tree, initialize weights and other parameters |
| ... | ... | @@ -1158,8 +1186,7 @@ void CascadeBoost::update_weights(CvBoostTree* tree) |
| 1158 | 1186 | |
| 1159 | 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 | 1190 | for( int i = 0; i < n; i++ ) |
| 1164 | 1191 | { |
| 1165 | 1192 | // save original categorical responses {0,1}, convert them to {-1,1} |
| ... | ... | @@ -1176,8 +1203,7 @@ void CascadeBoost::update_weights(CvBoostTree* tree) |
| 1176 | 1203 | } |
| 1177 | 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 | 1208 | for( int i = 0; i < n; i++ ) |
| 1183 | 1209 | { |
| ... | ... | @@ -1388,5 +1414,6 @@ bool CascadeBoost::isErrDesired() |
| 1388 | 1414 | cout << "|" << endl; |
| 1389 | 1415 | cout << "+----+---------+---------+" << endl; |
| 1390 | 1416 | |
| 1417 | + qDebug() << falseAlarm << maxFalseAlarm; | |
| 1391 | 1418 | return falseAlarm <= maxFalseAlarm; |
| 1392 | 1419 | } | ... | ... |