tesseract  4.00.00dev
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)
 
virtual ~StrokeWidth ()
 
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, Pix *nontext_pix, const DENORM *denorm, bool cjk_script, TextlineProjection *projection, BLOBNBOX_LIST *diacritic_blobs, ColPartitionGrid *part_grid, ColPartition_LIST *big_parts)
 
virtual void HandleClick (int x, int y)
 
- Public Member Functions inherited from tesseract::BlobGrid
 BlobGrid (int gridsize, const ICOORD &bleft, const ICOORD &tright)
 
virtual ~BlobGrid ()
 
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)
 
virtual ~BBGrid ()
 
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, Pix *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 ()
 
 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 57 of file strokewidth.h.

Constructor & Destructor Documentation

◆ StrokeWidth()

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

Definition at line 113 of file strokewidth.cpp.

115  : BlobGrid(gridsize, bleft, tright), nontext_map_(NULL), projection_(NULL),
116  denorm_(NULL), grid_box_(bleft, tright), rerotation_(1.0f, 0.0f) {
117  leaders_win_ = NULL;
118  widths_win_ = NULL;
119  initial_widths_win_ = NULL;
120  chains_win_ = NULL;
121  diacritics_win_ = NULL;
122  textlines_win_ = NULL;
123  smoothed_win_ = NULL;
124 }
int gridsize() const
Definition: bbgrid.h:64
BlobGrid(int gridsize, const ICOORD &bleft, const ICOORD &tright)
Definition: blobgrid.cpp:24

◆ ~StrokeWidth()

tesseract::StrokeWidth::~StrokeWidth ( )
virtual

Definition at line 126 of file strokewidth.cpp.

126  {
127  if (widths_win_ != NULL) {
128  #ifndef GRAPHICS_DISABLED
129  delete widths_win_->AwaitEvent(SVET_DESTROY);
130  #endif // GRAPHICS_DISABLED
132  exit(0);
133  delete widths_win_;
134  }
135  delete leaders_win_;
136  delete initial_widths_win_;
137  delete chains_win_;
138  delete textlines_win_;
139  delete smoothed_win_;
140  delete diacritics_win_;
141 }
bool textord_tabfind_only_strokewidths
Definition: strokewidth.cpp:45
SVEvent * AwaitEvent(SVEventType type)
Definition: scrollview.cpp:449

Member Function Documentation

◆ CorrectForRotation()

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

Definition at line 254 of file strokewidth.cpp.

255  {
256  Init(part_grid->gridsize(), part_grid->bleft(), part_grid->tright());
257  grid_box_ = TBOX(bleft(), tright());
258  rerotation_.set_x(rotation.x());
259  rerotation_.set_y(-rotation.y());
260 }
void Init(int gridsize, const ICOORD &bleft, const ICOORD &tright)
Definition: bbgrid.h:448
const ICOORD & bleft() const
Definition: bbgrid.h:73
void set_x(float xin)
rewrite function
Definition: points.h:216
void set_y(float yin)
rewrite function
Definition: points.h:220
const ICOORD & tright() const
Definition: bbgrid.h:76
Definition: rect.h:30

◆ FindLeaderPartitions()

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

Definition at line 263 of file strokewidth.cpp.

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

◆ FindTextlineDirectionAndFixBrokenCJK()

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

Definition at line 160 of file strokewidth.cpp.

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

◆ GradeBlobsIntoPartitions()

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

Definition at line 347 of file strokewidth.cpp.

351  {
352  nontext_map_ = nontext_pix;
353  projection_ = projection;
354  denorm_ = denorm;
355  // Clear and re Insert to take advantage of the tab stops in the blobs.
356  Clear();
357  // Setup the strokewidth grid with the remaining non-noise, non-leader blobs.
358  InsertBlobs(block);
359 
360  // Run FixBrokenCJK() again if the page is CJK.
361  if (cjk_script) {
362  FixBrokenCJK(block);
363  }
364  FindTextlineFlowDirection(pageseg_mode, false);
365  projection_->ConstructProjection(block, rerotation, nontext_map_);
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  projection_->MoveNonTextlineBlobs(&block->blobs, &block->noise_blobs);
372  projection_->MoveNonTextlineBlobs(&block->small_blobs, &block->noise_blobs);
373  // Clear and re Insert to take advantage of the removed diacritics.
374  Clear();
375  InsertBlobs(block);
376  FCOORD skew;
377  FindTextlineFlowDirection(pageseg_mode, true);
379  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,
388  diacritic_blobs, part_grid, big_parts, &skew);
389  }
390  nontext_map_ = NULL;
391  projection_ = NULL;
392  denorm_ = NULL;
393 }
Definition: points.h:189
void PlotGradedBlobs(BLOBNBOX_LIST *blobs, ScrollView *win)
ScrollView * MakeWindow(int x, int y, const char *window_name)
Definition: bbgrid.h:593
#define tprintf(...)
Definition: tprintf.h:31
void ConstructProjection(TO_BLOCK *input_block, const FCOORD &rotation, Pix *nontext_map)
BLOBNBOX_LIST small_blobs
Definition: blobbox.h:771
BLOBNBOX_LIST blobs
Definition: blobbox.h:768
void MoveNonTextlineBlobs(BLOBNBOX_LIST *blobs, BLOBNBOX_LIST *small_blobs) const
int textord_tabfind_show_strokewidths
Definition: strokewidth.cpp:44
BLOBNBOX_LIST noise_blobs
Definition: blobbox.h:770
PartitionFindResult
Definition: strokewidth.h:46

◆ HandleClick()

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

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()) != NULL) {
412  TBOX nbox = neighbour->bounding_box();
413  if (nbox.contains(click) && neighbour->cblob() != NULL) {
414  PrintBoxWidths(neighbour);
415  if (neighbour->neighbour(BND_LEFT) != NULL)
416  PrintBoxWidths(neighbour->neighbour(BND_LEFT));
417  if (neighbour->neighbour(BND_RIGHT) != NULL)
418  PrintBoxWidths(neighbour->neighbour(BND_RIGHT));
419  if (neighbour->neighbour(BND_ABOVE) != NULL)
420  PrintBoxWidths(neighbour->neighbour(BND_ABOVE));
421  if (neighbour->neighbour(BND_BELOW) != NULL)
422  PrintBoxWidths(neighbour->neighbour(BND_BELOW));
423  int gaps[BND_COUNT];
424  neighbour->NeighbourGaps(gaps);
425  tprintf("Left gap=%d, right=%d, above=%d, below=%d, horz=%d, vert=%d\n"
426  "Good= %d %d %d %d\n",
427  gaps[BND_LEFT], gaps[BND_RIGHT],
428  gaps[BND_ABOVE], gaps[BND_BELOW],
429  neighbour->horz_possible(),
430  neighbour->vert_possible(),
431  neighbour->good_stroke_neighbour(BND_LEFT),
432  neighbour->good_stroke_neighbour(BND_RIGHT),
433  neighbour->good_stroke_neighbour(BND_ABOVE),
434  neighbour->good_stroke_neighbour(BND_BELOW));
435  break;
436  }
437  }
438 }
void NeighbourGaps(int gaps[BND_COUNT]) const
Definition: blobbox.cpp:176
Definition: points.h:189
GridSearch< BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT > BlobGridSearch
Definition: blobgrid.h:31
bool good_stroke_neighbour(BlobNeighbourDir n) const
Definition: blobbox.h:358
#define tprintf(...)
Definition: tprintf.h:31
virtual void HandleClick(int x, int y)
Definition: bbgrid.h:659
C_BLOB * cblob() const
Definition: blobbox.h:253
bool horz_possible() const
Definition: blobbox.h:292
BLOBNBOX * neighbour(BlobNeighbourDir n) const
Definition: blobbox.h:355
bool contains(const FCOORD pt) const
Definition: rect.h:323
Definition: rect.h:30
bool vert_possible() const
Definition: blobbox.h:286
const TBOX & bounding_box() const
Definition: blobbox.h:215

◆ RemoveLineResidue()

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

Definition at line 283 of file strokewidth.cpp.

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

◆ SetNeighboursOnMediumBlobs()

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

Definition at line 146 of file strokewidth.cpp.

146  {
147  // Run a preliminary strokewidth neighbour detection on the medium blobs.
148  InsertBlobList(&block->blobs);
149  BLOBNBOX_IT blob_it(&block->blobs);
150  for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) {
151  SetNeighbours(false, false, blob_it.data());
152  }
153  Clear();
154 }
void InsertBlobList(BLOBNBOX_LIST *blobs)
Definition: blobgrid.cpp:34
BLOBNBOX_LIST blobs
Definition: blobbox.h:768

◆ 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.

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

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