bool EcvMser::isExtermal(int idx)
{ auto val = img_[idx]; auto p_idx = r_[idx].parent; auto p_val = img_[p_idx]; bool is_extremal = (p_val > val) || (idx == p_idx); retu is_extremal;
}
void EcvMser::reg2ExtermalTree(int idx, int er_count)
{ e_tree_[er_count].index = idx; e_tree_[er_count].parent = er_count; e_tree_[er_count].value = img_[idx]; e_tree_[er_count].area = r_[idx].area;
}
void EcvMser::createExtermalTree()
{ /* Extremal regions are extracted and stored into the array ER. The structure R is also updated so that .SHORTCUT indexes the corresponding extremal region if any (otherwise it is set to VOID). */ if (rer_ < er_count_) { if (e_tree_) free(e_tree_); e_tree_ = (EcvMserExtrReg*)malloc(sizeof(EcvMserExtrReg) * er_count_); rer_ = er_count_; }; mer_count_ = er_count_; er_count_ = 0; for (int i = 0; i < pixel_count_; ++i) { auto idx = pix_order_[i]; auto cur_point = index2Coord(idx); if (isExtermal(idx)) { extrmal_img_.at<float>(cur_point) = 255; reg2ExtermalTree(idx, er_count_); r_[idx].shortcut = er_count_; // link this region to this extremal region ++er_count_;// increase count } else { r_[idx].shortcut = ECV_MSER_VOID_NODE;// link this region to void extrmal_img_.at<float>(cur_point) = 128; } }
}
void EcvMser::linkExtermalRegions2Tree()
{ for (int i = 0; i < er_count_; ++i) { uint idx = e_tree_[i].index; do { idx = r_[idx].parent; } while (r_[idx].shortcut == ECV_MSER_VOID_NODE); e_tree_[i].parent = r_[idx].shortcut; e_tree_[i].shortcut = i; }
}
void EcvMser::computeVaribility()
{ /* ----------------------------------------------------------------- * Compute variability of +DELTA branches * -------------------------------------------------------------- */ /* For each extremal region Xi of value VAL we look for the biggest * parent that has value not greater than VAL+DELTA. This is dubbed * `top parent'. */ for (int i = 0; i < er_count_; ++i) { /* Xj is the current region the region and Xj are the parents */ int top_val = e_tree_[i].value + delta_; int top = e_tree_[i].shortcut; /* examine all parents */ while (1) { int next = e_tree_[top].parent; int next_val = e_tree_[next].value; /* Break if: * - there is no node above the top or * - the next node is above the top value. */ if (next == top || next_val > top_val) break; /* so next could be the top */ top = next; } /* calculate branch variation */ { int area = e_tree_[i].area; int area_top = e_tree_[top].area; e_tree_[i].variation = (float)(area_top - area) / area; e_tree_[i].max_stable = 1; } /* Optimization: since extremal regions are processed by * increasing intensity, all next extremal regions being processed * have value at least equal to the one of Xi. If any of them has * parent the parent of Xi (this comprises the parent itself), we * can safely skip most intermediate node along the branch and * skip directly to the top to start our search. */ { int parent = e_tree_[i].parent; int curr = e_tree_[parent].shortcut; e_tree_[parent].shortcut = std::max(top, curr); } }
}
void EcvMser::SelectMaximallyStableBranches()
{ mer_count_ = er_count_; for (int i = 0; i < er_count_; ++i) { auto parent = e_tree_[i].parent; auto val = e_tree_[i].value; float var = e_tree_[i].variation; uchar p_val = e_tree_[parent].value; float p_var = e_tree_[parent].variation; //Notice that R_parent = R_{l+1} only if p_val = val + 1. If not, //this and the parent region coincide and there is nothing to do. if (p_val > val + 1) continue; // decide which one to keep and put that in loser uint loser = var < p_var ? parent : i; // make loser NON maximally stable if (e_tree_[loser].max_stable) { --mer_count_; e_tree_[loser].max_stable = 0; } } stats_.num_unstable = er_count_ - mer_count_;
}
void EcvMser::furtherFiltering()
{ // It is critical for correct duplicate detection to remove regions // from the bottom (smallest one first). int big_count = 0; int small_count = 0; int bad_count = 0; int dup_count = 0; float max_area = (float)max_area_ * pixel_count_; float min_area = (float)min_area_ * pixel_count_; float max_var = (float)max_variation_; float min_div = (float)min_diversity_; // scan all extremal regions (intensity value order) for (int i = er_count_ - 1; i >= 0; --i) { // process only maximally stable extremal regions if (!e_tree_[i].max_stable) continue; ErState er_state = ErState::none; if (e_tree_[i].variation >= max_var) { ++bad_count; er_state = ErState::max_var; } else if (e_tree_[i].area > max_area) { ++big_count; er_state = ErState::max_area; } else if (e_tree_[i].area < min_area) { ++small_count; er_state = ErState::min_area; } else if (min_div < 1.0) { removeDuplicate(i, min_div, dup_count, er_state); } if (er_state != ErState::none) { e_tree_[i].max_stable = 0; --mer_count_; } } stats_.num_abs_unstable = bad_count; stats_.num_too_big = big_count; stats_.num_too_small = small_count; stats_.num_duplicates = dup_count;
}
void EcvMser::saveResult()
{ // make room if (rmer_ < mer_count_) { if (mer_) free(mer_); mer_ = (uint*)malloc(sizeof(uint) * mer_count_); rmer_ = mer_count_; } // save back mer_count_ = mer_count_; int j = 0; for (int i = 0; i < er_count_; ++i) if (e_tree_[i].max_stable) mer_[j++] = e_tree_[i].index;
}
+ نوشته شده در جمعه 11 خرداد 1397 ساعت: 23:45 توسط محمد رضا جوادیان