diff --git a/modules/xobjdetect/src/icfdetector.cpp b/modules/xobjdetect/src/icfdetector.cpp index d2f28c143..0154d5505 100644 --- a/modules/xobjdetect/src/icfdetector.cpp +++ b/modules/xobjdetect/src/icfdetector.cpp @@ -71,7 +71,7 @@ void ICFDetector::train(const String& pos_path, glob(pos_path + "/*.png", pos_filenames); vector bg_filenames; - glob(bg_path + "/*.png", bg_filenames); + glob(bg_path + "/*.jpg", bg_filenames); model_n_rows_ = params.model_n_rows; model_n_cols_ = params.model_n_cols; diff --git a/modules/xobjdetect/src/stump.cpp b/modules/xobjdetect/src/stump.cpp index d575d4c61..c9c9911d8 100644 --- a/modules/xobjdetect/src/stump.cpp +++ b/modules/xobjdetect/src/stump.cpp @@ -69,128 +69,115 @@ int Stump::train(const Mat& data, const Mat& labels, const Mat& weights) /* Assert that data and labels have int type */ /* Assert that weights have float type */ + Mat_ d = Mat_::zeros(1, data.cols); + const Mat_& l = labels; + const Mat_& w = weights; - /* Prepare labels for each feature rearranged according to sorted order */ - Mat sorted_labels(data.rows, data.cols, labels.type()); - Mat sorted_weights(data.rows, data.cols, weights.type()); - Mat indices; - sortIdx(data, indices, cv::SORT_EVERY_ROW | cv::SORT_ASCENDING); - for( int row = 0; row < indices.rows; ++row ) - { - for( int col = 0; col < indices.cols; ++col ) - { - sorted_labels.at(row, col) = - labels.at(0, indices.at(row, col)); - sorted_weights.at(row, col) = - weights.at(0, indices.at(row, col)); - } - } + Mat_ indices(1, l.cols); - /* Sort feature values */ - Mat sorted_data(data.rows, data.cols, data.type()); - sort(data, sorted_data, cv::SORT_EVERY_ROW | cv::SORT_ASCENDING); + Mat_ sorted_d(1, data.cols); + Mat_ sorted_l(1, l.cols); + Mat_ sorted_w(1, w.cols); - /* Split positive and negative weights */ - Mat pos_weights = Mat::zeros(sorted_weights.rows, sorted_weights.cols, - sorted_weights.type()); - Mat neg_weights = Mat::zeros(sorted_weights.rows, sorted_weights.cols, - sorted_weights.type()); + + Mat_ pos_c_w = Mat_::zeros(1, w.cols); + Mat_ neg_c_w = Mat_::zeros(1, w.cols); + + + float min_err = FLT_MAX; + int min_row = -1; + int min_thr = -1; + int min_pol = -1; + float min_pos = 1; + float min_neg = -1; + float eps = 1.0f / (4 * l.cols); + + /* For every feature */ for( int row = 0; row < data.rows; ++row ) { for( int col = 0; col < data.cols; ++col ) - { - if( sorted_labels.at(row, col) == +1 ) - { - pos_weights.at(row, col) = - sorted_weights.at(row, col); - } - else - { - neg_weights.at(row, col) = - sorted_weights.at(row, col); - } - } - } + d(0, col) = data.at(row, col); - /* Compute cumulative sums for fast stump error computation */ - Mat pos_cum_weights = Mat::zeros(sorted_weights.rows, sorted_weights.cols, - sorted_weights.type()); - Mat neg_cum_weights = Mat::zeros(sorted_weights.rows, sorted_weights.cols, - sorted_weights.type()); - cumsum(pos_weights, pos_cum_weights); - cumsum(neg_weights, neg_cum_weights); + sortIdx(d, indices, cv::SORT_EVERY_ROW | cv::SORT_ASCENDING); - /* Compute total weights of positive and negative samples */ - float pos_total_weight = pos_cum_weights.at(0, weights.cols - 1); - float neg_total_weight = neg_cum_weights.at(0, weights.cols - 1); + for( int col = 0; col < indices.cols; ++col ) + { + int ind = indices(0, col); + sorted_d(0, col) = d(0, ind); + sorted_l(0, col) = l(0, ind); + sorted_w(0, col) = w(0, ind); + } + Mat_ pos_w = Mat_::zeros(1, w.cols); + Mat_ neg_w = Mat_::zeros(1, w.cols); + for( int col = 0; col < d.cols; ++col ) + { + float weight = sorted_w(0, col); + if( sorted_l(0, col) == +1) + pos_w(0, col) = weight; + else + neg_w(0, col) = weight; + } - float eps = 1.0f / (4 * labels.cols); + cumsum(pos_w, pos_c_w); + cumsum(neg_w, neg_c_w); - /* Compute minimal error */ - float min_err = FLT_MAX; - int min_row = -1; - int min_col = -1; - int min_polarity = 0; - float min_pos_value = 1, min_neg_value = -1; + float pos_total_w = pos_c_w(0, w.cols - 1); + float neg_total_w = neg_c_w(0, w.cols - 1); - for( int row = 0; row < sorted_weights.rows; ++row ) - { - for( int col = 0; col < sorted_weights.cols - 1; ++col ) + for( int col = 0; col < w.cols - 1; ++col ) { float err, h_pos, h_neg; + float pos_wrong, pos_right; + float neg_wrong, neg_right; - // Direct polarity + /* Direct polarity */ - float pos_wrong = pos_cum_weights.at(row, col); - float pos_right = pos_total_weight - pos_wrong; + pos_wrong = pos_c_w(0, col); + pos_right = pos_total_w - pos_wrong; - float neg_right = neg_cum_weights.at(row, col); - float neg_wrong = neg_total_weight - neg_right; - - h_pos = (float)(.5 * log((pos_right + eps) / (pos_wrong + eps))); - h_neg = (float)(.5 * log((neg_wrong + eps) / (neg_right + eps))); + neg_right = neg_c_w(0, col); + neg_wrong = neg_total_w - neg_right; err = sqrt(pos_right * neg_wrong) + sqrt(pos_wrong * neg_right); + h_pos = .5f * log((pos_right + eps) / (pos_wrong + eps)); + h_neg = .5f * log((neg_wrong + eps) / (neg_right + eps)); + if( err < min_err ) { min_err = err; min_row = row; - min_col = col; - min_polarity = +1; - min_pos_value = h_pos; - min_neg_value = h_neg; + min_thr = (sorted_d(0, col) + sorted_d(0, col + 1)) / 2; + min_pol = +1; + min_pos = h_pos; + min_neg = h_neg; } - // Opposite polarity + /* Opposite polarity */ + swap(pos_right, pos_wrong); swap(neg_right, neg_wrong); - h_pos = -h_pos; - h_neg = -h_neg; - err = sqrt(pos_right * neg_wrong) + sqrt(pos_wrong * neg_right); - if( err < min_err ) { min_err = err; min_row = row; - min_col = col; - min_polarity = -1; - min_pos_value = h_pos; - min_neg_value = h_neg; + min_thr = (sorted_d(0, col) + sorted_d(0, col + 1)) / 2; + min_pol = -1; + min_pos = -h_pos; + min_neg = -h_neg; } + } } - /* Compute threshold, store found values in fields */ - threshold_ = ( sorted_data.at(min_row, min_col) + - sorted_data.at(min_row, min_col + 1) ) / 2; - polarity_ = min_polarity; - pos_value_ = min_pos_value; - neg_value_ = min_neg_value; + threshold_ = min_thr; + polarity_ = min_pol; + pos_value_ = min_pos; + neg_value_ = min_neg; return min_row; }