tesseract v5.3.3.20231005
tesseract::AlignedBlob Class Reference

#include <alignedblob.h>

Inheritance diagram for tesseract::AlignedBlob:
tesseract::BlobGrid tesseract::BBGrid< BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT > tesseract::GridBase tesseract::TabFind tesseract::ColumnFinder

Public Member Functions

 AlignedBlob (int gridsize, const ICOORD &bleft, const ICOORD &tright)
 
 ~AlignedBlob () override
 
ScrollViewDisplayTabs (const char *window_name, ScrollView *tab_win)
 
TabVectorFindVerticalAlignment (AlignedBlobParams align_params, BLOBNBOX *bbox, int *vertical_x, int *vertical_y)
 
- Public Member Functions inherited from tesseract::BlobGrid
 BlobGrid (int gridsize, const ICOORD &bleft, const ICOORD &tright)
 
 ~BlobGrid () override
 
void InsertBlobList (BLOBNBOX_LIST *blobs)
 
- Public Member Functions inherited from tesseract::BBGrid< BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT >
 BBGrid ()
 
 BBGrid (int gridsize, const ICOORD &bleft, const ICOORD &tright)
 
 ~BBGrid () override
 
void Init (int gridsize, const ICOORD &bleft, const ICOORD &tright)
 
void Clear ()
 
void ClearGridData (void(*free_method)(BLOBNBOX *))
 
void InsertBBox (bool h_spread, bool v_spread, BLOBNBOX *bbox)
 
void InsertPixPtBBox (int left, int bottom, Image pix, BLOBNBOX *bbox)
 
void RemoveBBox (BLOBNBOX *bbox)
 
bool RectangleEmpty (const TBOX &rect)
 
IntGridCountCellElements ()
 
ScrollViewMakeWindow (int x, int y, const char *window_name)
 
void DisplayBoxes (ScrollView *window)
 
void AssertNoDuplicates ()
 
virtual void HandleClick (int x, int y)
 
- Public Member Functions inherited from tesseract::GridBase
 GridBase ()=default
 
 GridBase (int gridsize, const ICOORD &bleft, const ICOORD &tright)
 
virtual ~GridBase ()
 
void Init (int gridsize, const ICOORD &bleft, const ICOORD &tright)
 
int gridsize () const
 
int gridwidth () const
 
int gridheight () const
 
const ICOORDbleft () const
 
const ICOORDtright () const
 
void GridCoords (int x, int y, int *grid_x, int *grid_y) const
 
void ClipGridCoords (int *x, int *y) const
 

Static Public Member Functions

static bool WithinTestRegion (int detail_level, int x, int y)
 

Additional Inherited Members

- Protected Attributes inherited from tesseract::BBGrid< BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT >
BLOBNBOX_CLIST * grid_
 
- Protected Attributes inherited from tesseract::GridBase
int gridsize_
 
int gridwidth_
 
int gridheight_
 
int gridbuckets_
 
ICOORD bleft_
 
ICOORD tright_
 

Detailed Description

Definition at line 76 of file alignedblob.h.

Constructor & Destructor Documentation

◆ AlignedBlob()

tesseract::AlignedBlob::AlignedBlob ( int  gridsize,
const ICOORD bleft,
const ICOORD tright 
)

Definition at line 149 of file alignedblob.cpp.

int gridsize() const
Definition: bbgrid.h:63
const ICOORD & bleft() const
Definition: bbgrid.h:72
const ICOORD & tright() const
Definition: bbgrid.h:75
BlobGrid(int gridsize, const ICOORD &bleft, const ICOORD &tright)
Definition: blobgrid.cpp:24

◆ ~AlignedBlob()

tesseract::AlignedBlob::~AlignedBlob ( )
overridedefault

Member Function Documentation

◆ DisplayTabs()

ScrollView * tesseract::AlignedBlob::DisplayTabs ( const char *  window_name,
ScrollView tab_win 
)

Definition at line 165 of file alignedblob.cpp.

165 {
166 if (tab_win == nullptr) {
167 tab_win = MakeWindow(0, 50, window_name);
168 }
169 // For every tab in the grid, display it.
170 GridSearch<BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT> gsearch(this);
171 gsearch.StartFullSearch();
172 BLOBNBOX *bbox;
173 while ((bbox = gsearch.NextFullSearch()) != nullptr) {
174 const TBOX &box = bbox->bounding_box();
175 int left_x = box.left();
176 int right_x = box.right();
177 int top_y = box.top();
178 int bottom_y = box.bottom();
179 TabType tabtype = bbox->left_tab_type();
180 if (tabtype != TT_NONE) {
181 if (tabtype == TT_MAYBE_ALIGNED) {
182 tab_win->Pen(ScrollView::BLUE);
183 } else if (tabtype == TT_MAYBE_RAGGED) {
184 tab_win->Pen(ScrollView::YELLOW);
185 } else if (tabtype == TT_CONFIRMED) {
186 tab_win->Pen(ScrollView::GREEN);
187 } else {
188 tab_win->Pen(ScrollView::GREY);
189 }
190 tab_win->Line(left_x, top_y, left_x, bottom_y);
191 }
192 tabtype = bbox->right_tab_type();
193 if (tabtype != TT_NONE) {
194 if (tabtype == TT_MAYBE_ALIGNED) {
195 tab_win->Pen(ScrollView::MAGENTA);
196 } else if (tabtype == TT_MAYBE_RAGGED) {
197 tab_win->Pen(ScrollView::ORANGE);
198 } else if (tabtype == TT_CONFIRMED) {
199 tab_win->Pen(ScrollView::RED);
200 } else {
201 tab_win->Pen(ScrollView::GREY);
202 }
203 tab_win->Line(right_x, top_y, right_x, bottom_y);
204 }
205 }
206 tab_win->Update();
207 return tab_win;
208}
@ TBOX
@ TT_MAYBE_RAGGED
Definition: blobbox.h:64
@ TT_MAYBE_ALIGNED
Definition: blobbox.h:65
@ TT_CONFIRMED
Definition: blobbox.h:66
@ TT_NONE
Definition: blobbox.h:62
ScrollView * MakeWindow(int x, int y, const char *window_name)
Definition: bbgrid.h:633

◆ FindVerticalAlignment()

TabVector * tesseract::AlignedBlob::FindVerticalAlignment ( AlignedBlobParams  align_params,
BLOBNBOX bbox,
int *  vertical_x,
int *  vertical_y 
)

Definition at line 234 of file alignedblob.cpp.

235 {
236 int ext_start_y, ext_end_y;
237 BLOBNBOX_CLIST good_points;
238 // Search up and then down from the starting bbox.
239 TBOX box = bbox->bounding_box();
240 bool debug = WithinTestRegion(2, box.left(), box.bottom());
241 int pt_count = AlignTabs(align_params, false, bbox, &good_points, &ext_end_y);
242 pt_count += AlignTabs(align_params, true, bbox, &good_points, &ext_start_y);
243 BLOBNBOX_C_IT it(&good_points);
244 it.move_to_last();
245 box = it.data()->bounding_box();
246 int end_y = box.top();
247 int end_x = align_params.right_tab ? box.right() : box.left();
248 it.move_to_first();
249 box = it.data()->bounding_box();
250 int start_x = align_params.right_tab ? box.right() : box.left();
251 int start_y = box.bottom();
252 // Acceptable tab vectors must have a minimum number of points,
253 // have a minimum acceptable length, and have a minimum gradient.
254 // The gradient corresponds to the skew angle.
255 // Ragged tabs don't need to satisfy the gradient condition, as they
256 // will always end up parallel to the vertical direction.
257 bool at_least_2_crossings = AtLeast2LineCrossings(&good_points);
258 if ((pt_count >= align_params.min_points && end_y - start_y >= align_params.min_length &&
259 (align_params.ragged || end_y - start_y >= abs(end_x - start_x) * kMinTabGradient)) ||
260 at_least_2_crossings) {
261 int confirmed_points = 0;
262 // Count existing confirmed points to see if vector is acceptable.
263 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
264 bbox = it.data();
265 if (align_params.right_tab) {
266 if (bbox->right_tab_type() == align_params.confirmed_type) {
267 ++confirmed_points;
268 }
269 } else {
270 if (bbox->left_tab_type() == align_params.confirmed_type) {
271 ++confirmed_points;
272 }
273 }
274 }
275 // Ragged vectors are not allowed to use too many already used points.
276 if (!align_params.ragged || confirmed_points + confirmed_points < pt_count) {
277 const TBOX &box = bbox->bounding_box();
278 if (debug) {
279 tprintf("Confirming tab vector of %d pts starting at %d,%d\n", pt_count, box.left(),
280 box.bottom());
281 }
282 // Flag all the aligned neighbours as confirmed .
283 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
284 bbox = it.data();
285 if (align_params.right_tab) {
286 bbox->set_right_tab_type(align_params.confirmed_type);
287 } else {
288 bbox->set_left_tab_type(align_params.confirmed_type);
289 }
290 if (debug) {
291 bbox->bounding_box().print();
292 }
293 }
294 // Now make the vector and return it.
295 TabVector *result =
296 TabVector::FitVector(align_params.alignment, align_params.vertical, ext_start_y,
297 ext_end_y, &good_points, vertical_x, vertical_y);
298 result->set_intersects_other_lines(at_least_2_crossings);
299 if (debug) {
300 tprintf("Box was %d, %d\n", box.left(), box.bottom());
301 result->Print("After fitting");
302 }
303 return result;
304 } else if (debug) {
305 tprintf("Ragged tab used too many used points: %d out of %d\n", confirmed_points, pt_count);
306 }
307 } else if (debug) {
308 tprintf(
309 "Tab vector failed basic tests: pt count %d vs min %d, "
310 "length %d vs min %d, min grad %g\n",
311 pt_count, align_params.min_points, end_y - start_y, align_params.min_length,
312 abs(end_x - start_x) * kMinTabGradient);
313 }
314 return nullptr;
315}
void tprintf(const char *format,...)
Definition: tprintf.cpp:41
const double kMinTabGradient
Definition: alignedblob.cpp:68
static bool WithinTestRegion(int detail_level, int x, int y)
static TabVector * FitVector(TabAlignment alignment, ICOORD vertical, int extended_start_y, int extended_end_y, BLOBNBOX_CLIST *good_points, int *vertical_x, int *vertical_y)
Definition: tabvector.cpp:176

◆ WithinTestRegion()

bool tesseract::AlignedBlob::WithinTestRegion ( int  detail_level,
int  x,
int  y 
)
static

Definition at line 154 of file alignedblob.cpp.

154 {
155 if (textord_debug_tabfind < detail_level) {
156 return false;
157 }
158 return x >= textord_testregion_left && x <= textord_testregion_right &&
159 y <= textord_testregion_top && y >= textord_testregion_bottom;
160}
int textord_debug_tabfind
Definition: alignedblob.cpp:29

The documentation for this class was generated from the following files: