tesseract  5.0.0
tesseract::StrokeWidth Class Reference

#include <strokewidth.h>

Inheritance diagram for tesseract::StrokeWidth:
tesseract::BlobGrid tesseract::BBGrid< BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT > tesseract::GridBase

Public Member Functions

 StrokeWidth (int gridsize, const ICOORD &bleft, const ICOORD &tright)
 
 ~StrokeWidth () override
 
void SetNeighboursOnMediumBlobs (TO_BLOCK *block)
 
void FindTextlineDirectionAndFixBrokenCJK (PageSegMode pageseg_mode, bool cjk_merge, TO_BLOCK *input_block)
 
bool TestVerticalTextDirection (double find_vertical_text_ratio, TO_BLOCK *block, BLOBNBOX_CLIST *osd_blobs)
 
void CorrectForRotation (const FCOORD &rerotation, ColPartitionGrid *part_grid)
 
void FindLeaderPartitions (TO_BLOCK *block, ColPartitionGrid *part_grid)
 
void RemoveLineResidue (ColPartition_LIST *big_part_list)
 
void GradeBlobsIntoPartitions (PageSegMode pageseg_mode, const FCOORD &rerotation, TO_BLOCK *block, Image nontext_pix, const DENORM *denorm, bool cjk_script, TextlineProjection *projection, BLOBNBOX_LIST *diacritic_blobs, ColPartitionGrid *part_grid, ColPartition_LIST *big_parts)
 
void HandleClick (int x, int y) override
 
- 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 ()
 
- 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
 

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

The StrokeWidth class holds all the normal and large blobs. It is used to find good large blobs and move them to the normal blobs by virtue of having a reasonable strokewidth compatible neighbour.

Definition at line 53 of file strokewidth.h.

Constructor & Destructor Documentation

◆ StrokeWidth()

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

Definition at line 114 of file strokewidth.cpp.

116  , nontext_map_(nullptr)
117  , projection_(nullptr)
118  , denorm_(nullptr)
119  , grid_box_(bleft, tright)
120  , rerotation_(1.0f, 0.0f) {
121 }
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

◆ ~StrokeWidth()

tesseract::StrokeWidth::~StrokeWidth ( )
override

Definition at line 123 of file strokewidth.cpp.

123  {
124 #ifndef GRAPHICS_DISABLED
125  if (widths_win_ != nullptr) {
126  delete widths_win_->AwaitEvent(SVET_DESTROY);
127  if (textord_tabfind_only_strokewidths) {
128  exit(0);
129  }
130  delete widths_win_;
131  }
132  delete leaders_win_;
133  delete initial_widths_win_;
134  delete chains_win_;
135  delete textlines_win_;
136  delete smoothed_win_;
137  delete diacritics_win_;
138 #endif
139 }
@ SVET_DESTROY
Definition: scrollview.h:53
SVEvent * AwaitEvent(SVEventType type)
Definition: scrollview.cpp:445

Member Function Documentation

◆ CorrectForRotation()

void tesseract::StrokeWidth::CorrectForRotation ( const FCOORD rerotation,
ColPartitionGrid part_grid 
)

Definition at line 253 of file strokewidth.cpp.

253  {
254  Init(part_grid->gridsize(), part_grid->bleft(), part_grid->tright());
255  grid_box_ = TBOX(bleft(), tright());
256  rerotation_.set_x(rotation.x());
257  rerotation_.set_y(-rotation.y());
258 }
@ TBOX
void set_y(float yin)
rewrite function
Definition: points.h:217
void set_x(float xin)
rewrite function
Definition: points.h:213
void Init(int gridsize, const ICOORD &bleft, const ICOORD &tright)
Definition: bbgrid.h:488

◆ FindLeaderPartitions()

void tesseract::StrokeWidth::FindLeaderPartitions ( TO_BLOCK block,
ColPartitionGrid part_grid 
)

Definition at line 261 of file strokewidth.cpp.

261  {
262  Clear();
263  // Find and isolate leaders in the noise list.
264  ColPartition_LIST leader_parts;
265  FindLeadersAndMarkNoise(block, &leader_parts);
266  // Setup the strokewidth grid with the block's remaining (non-noise) blobs.
267  InsertBlobList(&block->blobs);
268  // Mark blobs that have leader neighbours.
269  for (ColPartition_IT it(&leader_parts); !it.empty(); it.forward()) {
270  ColPartition *part = it.extract();
271  part->ClaimBoxes();
272  MarkLeaderNeighbours(part, LR_LEFT);
273  MarkLeaderNeighbours(part, LR_RIGHT);
274  part_grid->InsertBBox(true, true, part);
275  }
276 }
void InsertBlobList(BLOBNBOX_LIST *blobs)
Definition: blobgrid.cpp:35

◆ FindTextlineDirectionAndFixBrokenCJK()

void tesseract::StrokeWidth::FindTextlineDirectionAndFixBrokenCJK ( PageSegMode  pageseg_mode,
bool  cjk_merge,
TO_BLOCK input_block 
)

Definition at line 158 of file strokewidth.cpp.

159  {
160  // Setup the grid with the remaining (non-noise) blobs.
161  InsertBlobs(input_block);
162  // Repair broken CJK characters if needed.
163  while (cjk_merge && FixBrokenCJK(input_block)) {
164  ;
165  }
166  // Grade blobs by inspection of neighbours.
167  FindTextlineFlowDirection(pageseg_mode, false);
168  // Clear the grid ready for rotation or leader finding.
169  Clear();
170 }

◆ GradeBlobsIntoPartitions()

void tesseract::StrokeWidth::GradeBlobsIntoPartitions ( PageSegMode  pageseg_mode,
const FCOORD rerotation,
TO_BLOCK block,
Image  nontext_pix,
const DENORM denorm,
bool  cjk_script,
TextlineProjection projection,
BLOBNBOX_LIST *  diacritic_blobs,
ColPartitionGrid part_grid,
ColPartition_LIST *  big_parts 
)

Definition at line 345 of file strokewidth.cpp.

350  {
351  nontext_map_ = nontext_pix;
352  projection_ = projection;
353  denorm_ = denorm;
354  // Clear and re Insert to take advantage of the tab stops in the blobs.
355  Clear();
356  // Setup the strokewidth grid with the remaining non-noise, non-leader blobs.
357  InsertBlobs(block);
358 
359  // Run FixBrokenCJK() again if the page is CJK.
360  if (cjk_script) {
361  FixBrokenCJK(block);
362  }
363  FindTextlineFlowDirection(pageseg_mode, false);
364  projection_->ConstructProjection(block, rerotation, nontext_map_);
365 #ifndef GRAPHICS_DISABLED
366  if (textord_tabfind_show_strokewidths) {
367  ScrollView *line_blobs_win = MakeWindow(0, 0, "Initial textline Blobs");
368  projection_->PlotGradedBlobs(&block->blobs, line_blobs_win);
369  projection_->PlotGradedBlobs(&block->small_blobs, line_blobs_win);
370  }
371 #endif
372  projection_->MoveNonTextlineBlobs(&block->blobs, &block->noise_blobs);
373  projection_->MoveNonTextlineBlobs(&block->small_blobs, &block->noise_blobs);
374  // Clear and re Insert to take advantage of the removed diacritics.
375  Clear();
376  InsertBlobs(block);
377  FCOORD skew;
378  FindTextlineFlowDirection(pageseg_mode, true);
379  PartitionFindResult r = FindInitialPartitions(pageseg_mode, rerotation, true, block,
380  diacritic_blobs, part_grid, big_parts, &skew);
381  if (r == PFR_NOISE) {
382  tprintf("Detected %d diacritics\n", diacritic_blobs->length());
383  // Noise was found, and removed.
384  Clear();
385  InsertBlobs(block);
386  FindTextlineFlowDirection(pageseg_mode, true);
387  r = FindInitialPartitions(pageseg_mode, rerotation, false, block, diacritic_blobs, part_grid,
388  big_parts, &skew);
389  }
390  nontext_map_ = nullptr;
391  projection_ = nullptr;
392  denorm_ = nullptr;
393 }
PartitionFindResult
Definition: strokewidth.h:42
void tprintf(const char *format,...)
Definition: tprintf.cpp:41
ScrollView * MakeWindow(int x, int y, const char *window_name)
Definition: bbgrid.h:633
void ConstructProjection(TO_BLOCK *input_block, const FCOORD &rotation, Image nontext_map)
void MoveNonTextlineBlobs(BLOBNBOX_LIST *blobs, BLOBNBOX_LIST *small_blobs) const
void PlotGradedBlobs(BLOBNBOX_LIST *blobs, ScrollView *win)

◆ HandleClick()

void tesseract::StrokeWidth::HandleClick ( int  x,
int  y 
)
overridevirtual

Handles a click event in a display window.

Reimplemented from tesseract::BBGrid< BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT >.

Definition at line 404 of file strokewidth.cpp.

404  {
406  // Run a radial search for blobs that overlap.
407  BlobGridSearch radsearch(this);
408  radsearch.StartRadSearch(x, y, 1);
409  BLOBNBOX *neighbour;
410  FCOORD click(static_cast<float>(x), static_cast<float>(y));
411  while ((neighbour = radsearch.NextRadSearch()) != nullptr) {
412  TBOX nbox = neighbour->bounding_box();
413  if (nbox.contains(click) && neighbour->cblob() != nullptr) {
414  PrintBoxWidths(neighbour);
415  if (neighbour->neighbour(BND_LEFT) != nullptr) {
416  PrintBoxWidths(neighbour->neighbour(BND_LEFT));
417  }
418  if (neighbour->neighbour(BND_RIGHT) != nullptr) {
419  PrintBoxWidths(neighbour->neighbour(BND_RIGHT));
420  }
421  if (neighbour->neighbour(BND_ABOVE) != nullptr) {
422  PrintBoxWidths(neighbour->neighbour(BND_ABOVE));
423  }
424  if (neighbour->neighbour(BND_BELOW) != nullptr) {
425  PrintBoxWidths(neighbour->neighbour(BND_BELOW));
426  }
427  int gaps[BND_COUNT];
428  neighbour->NeighbourGaps(gaps);
429  tprintf(
430  "Left gap=%d, right=%d, above=%d, below=%d, horz=%d, vert=%d\n"
431  "Good= %d %d %d %d\n",
432  gaps[BND_LEFT], gaps[BND_RIGHT], gaps[BND_ABOVE], gaps[BND_BELOW],
433  neighbour->horz_possible(), neighbour->vert_possible(),
434  neighbour->good_stroke_neighbour(BND_LEFT), neighbour->good_stroke_neighbour(BND_RIGHT),
435  neighbour->good_stroke_neighbour(BND_ABOVE), neighbour->good_stroke_neighbour(BND_BELOW));
436  break;
437  }
438  }
439 }
@ BND_LEFT
Definition: blobbox.h:89
@ BND_RIGHT
Definition: blobbox.h:89
@ BND_BELOW
Definition: blobbox.h:89
@ BND_ABOVE
Definition: blobbox.h:89
@ BND_COUNT
Definition: blobbox.h:89
GridSearch< BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT > BlobGridSearch
Definition: blobgrid.h:30
virtual void HandleClick(int x, int y)
Definition: bbgrid.h:691

◆ RemoveLineResidue()

void tesseract::StrokeWidth::RemoveLineResidue ( ColPartition_LIST *  big_part_list)

Definition at line 280 of file strokewidth.cpp.

280  {
281  BlobGridSearch gsearch(this);
282  BLOBNBOX *bbox;
283  // For every vertical line-like bbox in the grid, search its neighbours
284  // to find the tallest, and if the original box is taller by sufficient
285  // margin, then call it line residue and delete it.
286  gsearch.StartFullSearch();
287  while ((bbox = gsearch.NextFullSearch()) != nullptr) {
288  TBOX box = bbox->bounding_box();
289  if (box.height() < box.width() * kLineResidueAspectRatio) {
290  continue;
291  }
292  // Set up a rectangle search around the blob to find the size of its
293  // neighbours.
294  int padding = box.height() * kLineResiduePadRatio;
295  TBOX search_box = box;
296  search_box.pad(padding, padding);
297  bool debug = AlignedBlob::WithinTestRegion(2, box.left(), box.bottom());
298  // Find the largest object in the search box not equal to bbox.
299  BlobGridSearch rsearch(this);
300  int max_height = 0;
301  BLOBNBOX *n;
302  rsearch.StartRectSearch(search_box);
303  while ((n = rsearch.NextRectSearch()) != nullptr) {
304  if (n == bbox) {
305  continue;
306  }
307  TBOX nbox = n->bounding_box();
308  if (nbox.height() > max_height) {
309  max_height = nbox.height();
310  }
311  }
312  if (debug) {
313  tprintf("Max neighbour size=%d for candidate line box at:", max_height);
314  box.print();
315  }
316  if (max_height * kLineResidueSizeRatio < box.height()) {
317 #ifndef GRAPHICS_DISABLED
318  if (leaders_win_ != nullptr) {
319  // We are debugging, so display deleted in pink blobs in the same
320  // window that we use to display leader detection.
321  leaders_win_->Pen(ScrollView::PINK);
322  leaders_win_->Rectangle(box.left(), box.bottom(), box.right(), box.top());
323  }
324 #endif // !GRAPHICS_DISABLED
325  ColPartition::MakeBigPartition(bbox, big_part_list);
326  }
327  }
328 }
const int kLineResiduePadRatio
const double kLineResidueAspectRatio
Definition: strokewidth.cpp:99
const double kLineResidueSizeRatio
static bool WithinTestRegion(int detail_level, int x, int y)
static ColPartition * MakeBigPartition(BLOBNBOX *box, ColPartition_LIST *big_part_list)
void Pen(Color color)
Definition: scrollview.cpp:723
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:589

◆ SetNeighboursOnMediumBlobs()

void tesseract::StrokeWidth::SetNeighboursOnMediumBlobs ( TO_BLOCK block)

Definition at line 144 of file strokewidth.cpp.

144  {
145  // Run a preliminary strokewidth neighbour detection on the medium blobs.
146  InsertBlobList(&block->blobs);
147  BLOBNBOX_IT blob_it(&block->blobs);
148  for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
149  SetNeighbours(false, false, blob_it.data());
150  }
151  Clear();
152 }

◆ TestVerticalTextDirection()

bool tesseract::StrokeWidth::TestVerticalTextDirection ( double  find_vertical_text_ratio,
TO_BLOCK block,
BLOBNBOX_CLIST *  osd_blobs 
)

Definition at line 212 of file strokewidth.cpp.

213  {
214  int vertical_boxes = 0;
215  int horizontal_boxes = 0;
216  // Count vertical normal and large blobs.
217  BLOBNBOX_CLIST vertical_blobs;
218  BLOBNBOX_CLIST horizontal_blobs;
219  BLOBNBOX_CLIST nondescript_blobs;
220  CollectHorizVertBlobs(&block->blobs, &vertical_boxes, &horizontal_boxes, &vertical_blobs,
221  &horizontal_blobs, &nondescript_blobs);
222  CollectHorizVertBlobs(&block->large_blobs, &vertical_boxes, &horizontal_boxes, &vertical_blobs,
223  &horizontal_blobs, &nondescript_blobs);
224  if (textord_debug_tabfind) {
225  tprintf("TextDir hbox=%d vs vbox=%d, %dH, %dV, %dN osd blobs\n", horizontal_boxes,
226  vertical_boxes, horizontal_blobs.length(), vertical_blobs.length(),
227  nondescript_blobs.length());
228  }
229  if (osd_blobs != nullptr && vertical_boxes == 0 && horizontal_boxes == 0) {
230  // Only nondescript blobs available, so return those.
231  BLOBNBOX_C_IT osd_it(osd_blobs);
232  osd_it.add_list_after(&nondescript_blobs);
233  return false;
234  }
235  int min_vert_boxes =
236  static_cast<int>((vertical_boxes + horizontal_boxes) * find_vertical_text_ratio);
237  if (vertical_boxes >= min_vert_boxes) {
238  if (osd_blobs != nullptr) {
239  BLOBNBOX_C_IT osd_it(osd_blobs);
240  osd_it.add_list_after(&vertical_blobs);
241  }
242  return true;
243  } else {
244  if (osd_blobs != nullptr) {
245  BLOBNBOX_C_IT osd_it(osd_blobs);
246  osd_it.add_list_after(&horizontal_blobs);
247  }
248  return false;
249  }
250 }
int textord_debug_tabfind
Definition: alignedblob.cpp:29

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