/* * Arguments : emxArray_real_T *x * Return Type : void */ void d_sort(emxArray_real_T *x) { emxArray_real_T *vwork; int i9; int k; int i10; emxArray_int32_T *b_vwork; emxInit_real_T2(&vwork, 1); i9 = x->size[1]; k = x->size[1]; i10 = vwork->size[0]; vwork->size[0] = k; emxEnsureCapacity((emxArray__common *)vwork, i10, (int)sizeof(double)); for (k = 0; k + 1 <= i9; k++) { vwork->data[k] = x->data[k]; } emxInit_int32_T(&b_vwork, 1); sortIdx(vwork, b_vwork); k = 0; emxFree_int32_T(&b_vwork); while (k + 1 <= i9) { x->data[k] = vwork->data[k]; k++; } emxFree_real_T(&vwork); }
/* * Arguments : double x_data[] * int x_size[1] * Return Type : void */ void sort(double x_data[], int x_size[1]) { int dim; int i6; double vwork_data[252]; int vwork_size_idx_0; int vstride; int k; int j; emxArray_real_T *vwork; emxArray_int32_T *b_vwork; dim = nonSingletonDim(x_size); if (dim <= 1) { i6 = x_size[0]; } else { i6 = 1; } vwork_size_idx_0 = (unsigned char)i6; vstride = 1; k = 1; while (k <= dim - 1) { vstride *= x_size[0]; k = 2; } j = 0; emxInit_real_T2(&vwork, 1); emxInit_int32_T(&b_vwork, 1); while (j + 1 <= vstride) { for (k = 0; k + 1 <= i6; k++) { vwork_data[k] = x_data[j + k * vstride]; } dim = vwork->size[0]; vwork->size[0] = vwork_size_idx_0; emxEnsureCapacity((emxArray__common *)vwork, dim, (int)sizeof(double)); for (dim = 0; dim < vwork_size_idx_0; dim++) { vwork->data[dim] = vwork_data[dim]; } sortIdx(vwork, b_vwork); vwork_size_idx_0 = vwork->size[0]; k = vwork->size[0]; for (dim = 0; dim < k; dim++) { vwork_data[dim] = vwork->data[dim]; } for (k = 0; k + 1 <= i6; k++) { x_data[j + k * vstride] = vwork->data[k]; } j++; } emxFree_int32_T(&b_vwork); emxFree_real_T(&vwork); }
static Mat argsort(InputArray _src, bool ascending=true) { Mat src = _src.getMat(); if (src.rows != 1 && src.cols != 1) CV_Error(Error::StsBadArg, "cv::argsort only sorts 1D matrices."); int flags = SORT_EVERY_ROW | (ascending ? SORT_ASCENDING : SORT_DESCENDING); Mat sorted_indices; sortIdx(src.reshape(1,1),sorted_indices,flags); return sorted_indices; }
Vec3f ColorConstancy::DCPveil(const Mat& image, Mat dcpImage) { Mat dst; dcpImage = dcpImage.reshape(0,1); sortIdx(dcpImage, dst, CV_SORT_EVERY_ROW + CV_SORT_DESCENDING); float maxValue = 0; vector<Mat> channels; split(image,channels); Vec3f veil; //cout << dst.rows << " " << dst.cols << endl; //cout << " chnnels" << image.channels() << " " << endl; channels[0] = channels[0].reshape(0,1); channels[1] = channels[1].reshape(0,1); channels[2] = channels[2].reshape(0,1); //cout << dst << endl; //cout << channels[0].rows << " " << channels[0].cols << endl; /// Take the 10% smaller for (int i=0;i<int((image.rows*image.cols)/10);i++){ float intensity = 0.0; intensity = intensity + channels[0].at<float>(0,dst.at<int>(0,i)); intensity = intensity +channels[1].at<float>(0,dst.at<int>(0,i)); intensity = intensity +channels[2].at<float>(0,dst.at<int>(0,i)); //cout << intensity << endl; if (maxValue < intensity/3){ veil[0] = channels[0].at<float>(0,dst.at<int>(0,i)); veil[1] = channels[1].at<float>(0,dst.at<int>(0,i)); veil[2] = channels[2].at<float>(0,dst.at<int>(0,i)); maxValue = intensity/3; } } return veil; }
int Stump::train(const Mat& data, const Mat& labels, const Mat& weights) { CV_Assert(labels.rows == 1 && labels.cols == data.cols); CV_Assert(weights.rows == 1 && weights.cols == data.cols); /* Assert that data and labels have int type */ /* Assert that weights have float type */ /* 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<int>(row, col) = labels.at<int>(0, indices.at<int>(row, col)); sorted_weights.at<float>(row, col) = weights.at<float>(0, indices.at<int>(row, col)); } } /* Sort feature values */ Mat sorted_data(data.rows, data.cols, data.type()); sort(data, sorted_data, cv::SORT_EVERY_ROW | cv::SORT_ASCENDING); /* 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()); for( int row = 0; row < data.rows; ++row ) { for( int col = 0; col < data.cols; ++col ) { if( sorted_labels.at<int>(row, col) == +1 ) { pos_weights.at<float>(row, col) = sorted_weights.at<float>(row, col); } else { neg_weights.at<float>(row, col) = sorted_weights.at<float>(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); /* Compute total weights of positive and negative samples */ float pos_total_weight = pos_cum_weights.at<float>(0, weights.cols - 1); float neg_total_weight = neg_cum_weights.at<float>(0, weights.cols - 1); float eps = 1.0f / (4 * labels.cols); /* 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; for( int row = 0; row < sorted_weights.rows; ++row ) { for( int col = 0; col < sorted_weights.cols - 1; ++col ) { float err, h_pos, h_neg; // Direct polarity float pos_wrong = pos_cum_weights.at<float>(row, col); float pos_right = pos_total_weight - pos_wrong; float neg_right = neg_cum_weights.at<float>(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))); 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; } // 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; } } } /* Compute threshold, store found values in fields */ threshold_ = ( sorted_data.at<int>(min_row, min_col) + sorted_data.at<int>(min_row, min_col + 1) ) / 2; polarity_ = min_polarity; pos_value_ = min_pos_value; neg_value_ = min_neg_value; return min_row; }
cv::Mat PM_type::nms(const cv::Mat &boxes, float overlap) //% Non-maximum suppression. //% pick = nms(boxes, overlap) //% //% Greedily select high-scoring detections and skip detections that are //% significantly covered by a previously selected detection. //% //% Return value //% pick Indices of locally maximal detections //% //% Arguments //% boxes Detection bounding boxes (see pascal_test.m) //% overlap Overlap threshold for suppression //% For a selected box Bi, all boxes Bj that are covered by //% more than overlap are suppressed. Note that 'covered' is //% is |Bi \cap Bj| / |Bj|, not the PASCAL intersection over //% union measure. { if( boxes.empty() ) return boxes; cv::Mat x1 = boxes.col(0); cv::Mat y1 = boxes.col(1); cv::Mat x2 = boxes.col(2); cv::Mat y2 = boxes.col(3); cv::Mat s = boxes.col(boxes.cols - 1); cv::Mat area = x2 - x1 + 1; area = area.mul(y2-y1+1); vector<int> Ind( s.rows, 0 ); cv::Mat Idx(s.rows, 1, CV_32SC1, &Ind[0]); sortIdx( s, Idx, CV_SORT_EVERY_COLUMN+CV_SORT_ASCENDING ); vector<int> pick; while( !Ind.empty() ){ int last = Ind.size() - 1; int i = Ind[last]; pick.push_back(i); vector<int> suppress( 1, last ); for( int pos=0; pos<last; pos++ ){ int j = Ind[pos]; float xx1 = std::max(x1.at<float>(i), x1.at<float>(j)); float yy1 = std::max(y1.at<float>(i), y1.at<float>(j)); float xx2 = std::min(x2.at<float>(i), x2.at<float>(j)); float yy2 = std::min(y2.at<float>(i), y2.at<float>(j)); float w = xx2-xx1+1; float h = yy2-yy1+1; if( w>0 && h>0 ){ // compute overlap float area_intersection = w * h; float o1 = area_intersection / area.at<float>(j); float o2 = area_intersection / area.at<float>(i); float o = std::max(o1,o2); if( o>overlap ) suppress.push_back(pos); } } std::set<int> supp( suppress.begin(), suppress.end() ); vector<int> Ind2; for( int i=0; i!=Ind.size(); i++ ){ if( supp.find(i)==supp.end() ) Ind2.push_back( Ind[i] ); } Ind = Ind2; } cv::Mat ret(pick.size(), boxes.cols, boxes.type()); for( unsigned i=0; i<pick.size(); i++ ) boxes.row( pick[i] ).copyTo( ret.row(i) ); return ret; }
/* NonMaxSup is for non-maximum suppression. Input: boxes: Detection bounding boxes. overlap: Overlap threshold for suppression Output: pick: The locally maximal bounding boxes of detections. For a selected box Bi, all boxes Bj that are covered by more than overlap are suppressed. Note that 'covered' is is |Bi \cap Bj| / |Bj|, not the PASCAL intersection over union measure. */ Mat PostProcessor::NonMaxSup(const Mat& boxes, const float overlap) { if (boxes.dims == 0) { return Mat(); } int numberOfBoxes = boxes.size[0]; if (numberOfBoxes == 0) return Mat(); Mat x1 = boxes.col(0); Mat y1 = boxes.col(1); Mat x2 = boxes.col(2); Mat y2 = boxes.col(3); Mat s = boxes.col(4); Mat area(numberOfBoxes, 1, CV_32FC1, Scalar(0)); for (int i = 0 ; i < numberOfBoxes ; ++i) { area.at<float>(i, 0) = (x2.at<float>(i, 0)-x1.at<float>(i, 0)+1) * (y2.at<float>(i, 0)-y1.at<float>(i, 0)+1); } Mat idx; vector<int> I; sortIdx(s, idx, CV_SORT_EVERY_COLUMN+CV_SORT_ASCENDING); for (int i = 0 ; i < idx.rows ; ++i) { I.push_back(idx.at<int>(i, 0)); } vector<int> pickIdx; vector<int> suppress; while (!I.empty()) { int last = I.size() - 1; int i = I[last]; pickIdx.push_back(i); suppress.clear(); suppress.push_back(last); for (int pos = 0 ; pos < last ; ++pos) { int j = I[pos]; float xx1 = max(x1.at<float>(i, 0), x1.at<float>(j, 0)); float yy1 = max(y1.at<float>(i, 0), y1.at<float>(j, 0)); float xx2 = min(x2.at<float>(i, 0), x2.at<float>(j, 0)); float yy2 = min(y2.at<float>(i, 0), y2.at<float>(j, 0)); float h = xx2 - xx1 + 1; float w = yy2 - yy1 + 1; if (w > 0 && h > 0) { float o = w * h / (area.at<float>(j, 0) + area.at<float>(i, 0) - w * h); if (o > overlap) { suppress.push_back(pos); } } } vector<int> counterPart; for (int idxI = 0 ; idxI < I.size() ; ++idxI) { bool flag = false; for (int sup = 0 ; sup < suppress.size() ; ++sup) { if (idxI == suppress[sup]) { flag = true; break; } } if (flag == false) { counterPart.push_back(I[idxI]); } } I = counterPart; } Mat pick(pickIdx.size(), 5, CV_32FC1, Scalar(0)); for (int i = 0 ; i < pickIdx.size(); ++i) { boxes.row(pickIdx[i]).copyTo(pick.row(i)); } return pick; }
void WBDetectorImpl::train( const string& pos_samples_path, const string& neg_imgs_path) { vector<Mat> pos_imgs = read_imgs(pos_samples_path); vector<Mat> neg_imgs = sample_patches(neg_imgs_path, 24, 24, pos_imgs.size() * 10); assert(pos_imgs.size()); assert(neg_imgs.size()); int n_features; Mat pos_data, neg_data; Ptr<CvFeatureEvaluator> eval = CvFeatureEvaluator::create(); eval->init(CvFeatureParams::create(), 1, Size(24, 24)); n_features = eval->getNumFeatures(); const int stages[] = {64, 128, 256, 512, 1024}; const int stage_count = sizeof(stages) / sizeof(*stages); const int stage_neg = (int)(pos_imgs.size() * 5); const int max_per_image = 100; const float scales_arr[] = {.3f, .4f, .5f, .6f, .7f, .8f, .9f, 1.0f}; const vector<float> scales(scales_arr, scales_arr + sizeof(scales_arr) / sizeof(*scales_arr)); vector<String> neg_filenames; glob(neg_imgs_path, neg_filenames); for (int i = 0; i < stage_count; ++i) { cerr << "compute features" << endl; pos_data = Mat1b(n_features, (int)pos_imgs.size()); neg_data = Mat1b(n_features, (int)neg_imgs.size()); for (size_t k = 0; k < pos_imgs.size(); ++k) { eval->setImage(pos_imgs[k], +1, 0, boost_.get_feature_indices()); for (int j = 0; j < n_features; ++j) { pos_data.at<uchar>(j, (int)k) = (uchar)(*eval)(j); } } for (size_t k = 0; k < neg_imgs.size(); ++k) { eval->setImage(neg_imgs[k], 0, 0, boost_.get_feature_indices()); for (int j = 0; j < n_features; ++j) { neg_data.at<uchar>(j, (int)k) = (uchar)(*eval)(j); } } boost_.reset(stages[i]); boost_.fit(pos_data, neg_data); if (i + 1 == stage_count) { break; } int bootstrap_count = 0; size_t img_i = 0; for (; img_i < neg_filenames.size(); ++img_i) { cerr << "win " << bootstrap_count << "/" << stage_neg << " img " << (img_i + 1) << "/" << neg_filenames.size() << "\r"; Mat img = imread(neg_filenames[img_i], CV_LOAD_IMAGE_GRAYSCALE); vector<Rect> bboxes; Mat1f confidences; boost_.detect(eval, img, scales, bboxes, confidences); if (confidences.rows > 0) { Mat1i indices; sortIdx(confidences, indices, CV_SORT_EVERY_COLUMN + CV_SORT_DESCENDING); int win_count = min(max_per_image, confidences.rows); win_count = min(win_count, stage_neg - bootstrap_count); Mat window; for (int k = 0; k < win_count; ++k) { resize(img(bboxes[indices(k, 0)]), window, Size(24, 24)); neg_imgs.push_back(window.clone()); bootstrap_count += 1; } if (bootstrap_count >= stage_neg) { break; } } } cerr << "bootstrapped " << bootstrap_count << " windows from " << (img_i + 1) << " images" << endl; } }