// Finds vertical lines in the given list of BLOBNBOXes. bleft and tright // are the bounds of the image on which the input line_bblobs were found. // The input line_bblobs list is const really. // The output vertical_x and vertical_y are the total of all the vectors. // The output list of TabVector makes no reference to the input BLOBNBOXes. void LineFinder::FindLineVectors(const ICOORD& bleft, const ICOORD& tright, BLOBNBOX_LIST* line_bblobs, int* vertical_x, int* vertical_y, TabVector_LIST* vectors) { BLOBNBOX_IT bbox_it(line_bblobs); int b_count = 0; // Put all the blobs into the grid to find the lines, and move the blobs // to the output lists. AlignedBlob blob_grid(kLineFindGridSize, bleft, tright); for (bbox_it.mark_cycle_pt(); !bbox_it.cycled_list(); bbox_it.forward()) { BLOBNBOX* bblob = bbox_it.data(); bblob->set_left_tab_type(TT_UNCONFIRMED); bblob->set_left_rule(bleft.x()); bblob->set_right_rule(tright.x()); bblob->set_left_crossing_rule(bleft.x()); bblob->set_right_crossing_rule(tright.x()); blob_grid.InsertBBox(false, true, bblob); ++b_count; } if (textord_debug_tabfind) tprintf("Inserted %d line blobs into grid\n", b_count); if (b_count == 0) return; // Search the entire grid, looking for vertical line vectors. GridSearch<BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT> lsearch(&blob_grid); BLOBNBOX* bbox; TabVector_IT vector_it(vectors); *vertical_x = 0; *vertical_y = 1; lsearch.StartFullSearch(); while ((bbox = lsearch.NextFullSearch()) != NULL) { if (bbox->left_tab_type() == TT_UNCONFIRMED) { const TBOX& box = bbox->bounding_box(); if (AlignedBlob::WithinTestRegion(2, box.left(), box.bottom())) tprintf("Finding line vector starting at bbox (%d,%d)\n", box.left(), box.bottom()); AlignedBlobParams align_params(*vertical_x, *vertical_y, box.width()); TabVector* vector = blob_grid.FindVerticalAlignment(align_params, bbox, vertical_x, vertical_y); if (vector != NULL) { vector->Freeze(); vector_it.add_to_end(vector); } } } ScrollView* line_win = NULL; if (textord_tabfind_show_vlines) { line_win = blob_grid.MakeWindow(0, 50, "Vlines"); blob_grid.DisplayBoxes(line_win); line_win = blob_grid.DisplayTabs("Vlines", line_win); } }
static void align_same_func_call_params() { chunk_t *pc; chunk_t *align_root = NULL; chunk_t *align_cur = NULL; int align_len = 0; chunk_t *chunks[16]; AlignStack as[16]; AlignStack fcn_as; int max_idx = -1; int cur_as; int idx; const char *add_str = NULL; fcn_as.Start(3); for (pc = chunk_get_head(); pc != NULL; pc = chunk_get_next(pc)) { if (pc->type != CT_FUNC_CALL) { if (chunk_is_newline(pc)) { for (idx = 0; idx <= max_idx; idx++) { as[idx].NewLines(pc->nl_count); } fcn_as.NewLines(pc->nl_count); } continue; } /* Only align function calls that are right after a newline */ if (!chunk_is_newline(chunk_get_prev(pc))) { continue; } fcn_as.Add(pc); add_str = NULL; if (align_root != NULL) { if ((pc->len == align_root->len) && (memcmp(pc->str, align_root->str, pc->len) == 0)) { align_cur->align.next = pc; align_cur = pc; align_len++; add_str = " Add"; } else { LOG_FMT(LASFCP, " ++ Ended with %d fcns\n", align_len); /* Flush it all! */ fcn_as.Flush(); for (idx = 0; idx <= max_idx; idx++) { as[idx].Flush(); } align_root = NULL; } } if (align_root == NULL) { align_root = pc; align_cur = pc; align_len = 1; add_str = "Start"; } if (add_str != NULL) { LOG_FMT(LASFCP, "%s '%.*s' on line %d -", add_str, pc->len, pc->str, pc->orig_line); cur_as = align_params(pc, chunks, ARRAY_SIZE(chunks)); LOG_FMT(LASFCP, " %d items:", cur_as); for (idx = 0; idx < cur_as; idx++) { LOG_FMT(LASFCP, " [%.*s]", chunks[idx]->len, chunks[idx]->str); if (idx > max_idx) { as[idx].Start(3); if (!cpd.settings[UO_align_number_left].b) { if ((chunks[idx]->type == CT_NUMBER_FP) || (chunks[idx]->type == CT_NUMBER) || (chunks[idx]->type == CT_POS) || (chunks[idx]->type == CT_NEG)) { as[idx].m_right_align = true; } } max_idx = idx; } as[idx].Add(chunks[idx]); } LOG_FMT(LASFCP, "\n"); } } fcn_as.End(); for (idx = 0; idx <= max_idx; idx++) { as[idx].End(); } }
void LineFinder::findAndRemoveVLines(){ set<PBLOBNBOX, jun::BoxCmp_LT<BLOBNBOX>> bset; getLineBlobs(false, &pix_vline, &pix_intersections, bset); if (bset.empty()) return; int vertical_x = 0, vertical_y = 1; deque<PBLOBNBOX> alignedblobs; for (auto it = bset.begin(); it != bset.end(); ++it){ if ((*it)->left_tab_type == TabType::TT_MAYBE_ALIGNED){ PBLOBNBOX bbox = *it; Rect box = bbox->bounding_box(); logger()->info("Finding live vector starting at ({},{}) \n", box.x, box.y); AlignedBlobParams align_params(vertical_x, vertical_y, box.width); alignedblobs.clear(); alignedblobs.push_back(bbox); findAlignedBlobs(alignedblobs, align_params, bset, bbox); align_params.vertical *= -1; //反向 findAlignedBlobs(alignedblobs, align_params, bset, bbox); auto box = alignedblobs.front()->bounding_box(); int start_x = box.x; int start_y = box.y; box = alignedblobs.back()->bounding_box(); int end_x = box.x; int end_y = box.ylast(); bool at_least_2_crossings = atLeast2LineCrossing(alignedblobs); if ((alignedblobs.size() >= align_params.min_points && end_y - start_y >= align_params.min_length && (align_params.ragged || end_y - start_y >= std::abs(end_x - start_x)*kMinTabGradient)) || at_least_2_crossings){ int confirmed_pts = 0; for (auto iter = alignedblobs.begin(); iter != alignedblobs.end(); ++iter){ auto bbox = *iter; if (align_params.right_tab){ if (bbox->right_tab_type == align_params.confirmed_type) ++confirmed_pts; } else{ if (bbox->left_tab_type == align_params.confirmed_type) ++confirmed_pts; } } if (!align_params.ragged || confirmed_pts * 2 < alignedblobs.size()){ for (auto iter = alignedblobs.begin(); iter != alignedblobs.end(); ++iter){ PBLOBNBOX bbox = *iter; if (align_params.right_tab){ bbox->right_tab_type = align_params.confirmed_type; } else{ bbox->left_tab_type = align_params.confirmed_type; } } } } } } }