Tesseract
3.02
|
#include <alignedblob.h>
Public Member Functions | |
AlignedBlob (int gridsize, const ICOORD &bleft, const ICOORD &tright) | |
virtual | ~AlignedBlob () |
ScrollView * | DisplayTabs (const char *window_name, ScrollView *tab_win) |
TabVector * | FindVerticalAlignment (AlignedBlobParams align_params, BLOBNBOX *bbox, int *vertical_x, int *vertical_y) |
Static Public Member Functions | |
static bool | WithinTestRegion (int detail_level, int x, int y) |
static void | IncrementDebugPix () |
static const STRING & | textord_debug_pix () |
Definition at line 83 of file alignedblob.h.
Definition at line 164 of file alignedblob.cpp.
tesseract::AlignedBlob::~AlignedBlob | ( | ) | [virtual] |
Definition at line 169 of file alignedblob.cpp.
{ }
ScrollView * tesseract::AlignedBlob::DisplayTabs | ( | const char * | window_name, |
ScrollView * | tab_win | ||
) |
Definition at line 182 of file alignedblob.cpp.
{ #ifndef GRAPHICS_DISABLED if (tab_win == NULL) tab_win = MakeWindow(0, 50, window_name); // For every tab in the grid, display it. GridSearch<BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT> gsearch(this); gsearch.StartFullSearch(); BLOBNBOX* bbox; while ((bbox = gsearch.NextFullSearch()) != NULL) { TBOX box = bbox->bounding_box(); int left_x = box.left(); int right_x = box.right(); int top_y = box.top(); int bottom_y = box.bottom(); TabType tabtype = bbox->left_tab_type(); if (tabtype != TT_NONE) { if (tabtype == TT_MAYBE_ALIGNED) tab_win->Pen(ScrollView::BLUE); else if (tabtype == TT_MAYBE_RAGGED) tab_win->Pen(ScrollView::YELLOW); else if (tabtype == TT_CONFIRMED) tab_win->Pen(ScrollView::GREEN); else tab_win->Pen(ScrollView::GREY); tab_win->Line(left_x, top_y, left_x, bottom_y); } tabtype = bbox->right_tab_type(); if (tabtype != TT_NONE) { if (tabtype == TT_MAYBE_ALIGNED) tab_win->Pen(ScrollView::MAGENTA); else if (tabtype == TT_MAYBE_RAGGED) tab_win->Pen(ScrollView::ORANGE); else if (tabtype == TT_CONFIRMED) tab_win->Pen(ScrollView::RED); else tab_win->Pen(ScrollView::GREY); tab_win->Line(right_x, top_y, right_x, bottom_y); } } tab_win->Update(); #endif return tab_win; }
TabVector * tesseract::AlignedBlob::FindVerticalAlignment | ( | AlignedBlobParams | align_params, |
BLOBNBOX * | bbox, | ||
int * | vertical_x, | ||
int * | vertical_y | ||
) |
Definition at line 244 of file alignedblob.cpp.
{ int ext_start_y, ext_end_y; BLOBNBOX_CLIST good_points; // Search up and then down from the starting bbox. TBOX box = bbox->bounding_box(); bool debug = WithinTestRegion(2, box.left(), box.bottom()); int pt_count = AlignTabs(align_params, false, bbox, &good_points, &ext_end_y); pt_count += AlignTabs(align_params, true, bbox, &good_points, &ext_start_y); BLOBNBOX_C_IT it(&good_points); it.move_to_last(); box = it.data()->bounding_box(); int end_y = box.top(); int end_x = align_params.right_tab ? box.right() : box.left(); it.move_to_first(); box = it.data()->bounding_box(); int start_x = align_params.right_tab ? box.right() : box.left(); int start_y = box.bottom(); // Acceptable tab vectors must have a mininum number of points, // have a minimum acceptable length, and have a minimum gradient. // The gradient corresponds to the skew angle. // Ragged tabs don't need to satisfy the gradient condition, as they // will always end up parallel to the vertical direction. bool at_least_2_crossings = AtLeast2LineCrossings(&good_points); if ((pt_count >= align_params.min_points && end_y - start_y >= align_params.min_length && (align_params.ragged || end_y - start_y >= abs(end_x - start_x) * kMinTabGradient)) || at_least_2_crossings) { int confirmed_points = 0; // Count existing confirmed points to see if vector is acceptable. for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) { bbox = it.data(); if (align_params.right_tab) { if (bbox->right_tab_type() == align_params.confirmed_type) ++confirmed_points; } else { if (bbox->left_tab_type() == align_params.confirmed_type) ++confirmed_points; } } // Ragged vectors are not allowed to use too many already used points. if (!align_params.ragged || confirmed_points + confirmed_points < pt_count) { const TBOX& box = bbox->bounding_box(); if (debug) { tprintf("Confirming tab vector of %d pts starting at %d,%d\n", pt_count, box.left(), box.bottom()); } // Flag all the aligned neighbours as confirmed . for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) { bbox = it.data(); if (align_params.right_tab) { bbox->set_right_tab_type(align_params.confirmed_type); } else { bbox->set_left_tab_type(align_params.confirmed_type); } if (debug) { bbox->bounding_box().print(); } } // Now make the vector and return it. TabVector* result = TabVector::FitVector(align_params.alignment, align_params.vertical, ext_start_y, ext_end_y, &good_points, vertical_x, vertical_y); result->set_intersects_other_lines(at_least_2_crossings); if (debug) { tprintf("Box was %d, %d\n", box.left(), box.bottom()); result->Print("After fitting"); } return result; } else if (debug) { tprintf("Ragged tab used too many used points: %d out of %d\n", confirmed_points, pt_count); } } else if (debug) { tprintf("Tab vector failed basic tests: pt count %d vs min %d, " "length %d vs min %d, min grad %g\n", pt_count, align_params.min_points, end_y - start_y, align_params.min_length, abs(end_x - start_x) * kMinTabGradient); } return NULL; }
void tesseract::AlignedBlob::IncrementDebugPix | ( | ) | [static] |
Definition at line 78 of file alignedblob.cpp.
{ ++debug_pix_index_; textord_debug_pix_ = kTextordDebugPix; char numbuf[32]; snprintf(numbuf, sizeof(numbuf), "%d", debug_pix_index_); textord_debug_pix_ += numbuf; textord_debug_pix_ += ".pix"; }
static const STRING& tesseract::AlignedBlob::textord_debug_pix | ( | ) | [inline, static] |
Definition at line 112 of file alignedblob.h.
{
return textord_debug_pix_;
}
bool tesseract::AlignedBlob::WithinTestRegion | ( | int | detail_level, |
int | x, | ||
int | y | ||
) | [static] |
Definition at line 174 of file alignedblob.cpp.
{ if (textord_debug_tabfind < detail_level) return false; return x >= textord_testregion_left && x <= textord_testregion_right && y <= textord_testregion_top && y >= textord_testregion_bottom; }