tesseract 4.1.1
Loading...
Searching...
No Matches
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, Pix *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, 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 ()
 
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
 

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 109 of file strokewidth.cpp.

111 : BlobGrid(gridsize, bleft, tright), nontext_map_(nullptr), projection_(nullptr),
112 denorm_(nullptr), grid_box_(bleft, tright), rerotation_(1.0f, 0.0f) {
113 leaders_win_ = nullptr;
114 widths_win_ = nullptr;
115 initial_widths_win_ = nullptr;
116 chains_win_ = nullptr;
117 diacritics_win_ = nullptr;
118 textlines_win_ = nullptr;
119 smoothed_win_ = nullptr;
120}
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 122 of file strokewidth.cpp.

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

Member Function Documentation

◆ CorrectForRotation()

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

Definition at line 250 of file strokewidth.cpp.

251 {
252 Init(part_grid->gridsize(), part_grid->bleft(), part_grid->tright());
253 grid_box_ = TBOX(bleft(), tright());
254 rerotation_.set_x(rotation.x());
255 rerotation_.set_y(-rotation.y());
256}
void set_y(float yin)
rewrite function
Definition: points.h:218
void set_x(float xin)
rewrite function
Definition: points.h:214
Definition: rect.h:34
void Init(int gridsize, const ICOORD &bleft, const ICOORD &tright)
Definition: bbgrid.h:445

◆ FindLeaderPartitions()

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

Definition at line 259 of file strokewidth.cpp.

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

◆ FindTextlineDirectionAndFixBrokenCJK()

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

Definition at line 156 of file strokewidth.cpp.

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

◆ 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 343 of file strokewidth.cpp.

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

400 {
402 // Run a radial search for blobs that overlap.
403 BlobGridSearch radsearch(this);
404 radsearch.StartRadSearch(x, y, 1);
405 BLOBNBOX* neighbour;
406 FCOORD click(static_cast<float>(x), static_cast<float>(y));
407 while ((neighbour = radsearch.NextRadSearch()) != nullptr) {
408 TBOX nbox = neighbour->bounding_box();
409 if (nbox.contains(click) && neighbour->cblob() != nullptr) {
410 PrintBoxWidths(neighbour);
411 if (neighbour->neighbour(BND_LEFT) != nullptr)
412 PrintBoxWidths(neighbour->neighbour(BND_LEFT));
413 if (neighbour->neighbour(BND_RIGHT) != nullptr)
414 PrintBoxWidths(neighbour->neighbour(BND_RIGHT));
415 if (neighbour->neighbour(BND_ABOVE) != nullptr)
416 PrintBoxWidths(neighbour->neighbour(BND_ABOVE));
417 if (neighbour->neighbour(BND_BELOW) != nullptr)
418 PrintBoxWidths(neighbour->neighbour(BND_BELOW));
419 int gaps[BND_COUNT];
420 neighbour->NeighbourGaps(gaps);
421 tprintf("Left gap=%d, right=%d, above=%d, below=%d, horz=%d, vert=%d\n"
422 "Good= %d %d %d %d\n",
423 gaps[BND_LEFT], gaps[BND_RIGHT],
424 gaps[BND_ABOVE], gaps[BND_BELOW],
425 neighbour->horz_possible(),
426 neighbour->vert_possible(),
430 neighbour->good_stroke_neighbour(BND_BELOW));
431 break;
432 }
433 }
434}
@ BND_COUNT
Definition: blobbox.h:92
@ BND_ABOVE
Definition: blobbox.h:91
@ BND_LEFT
Definition: blobbox.h:88
@ BND_BELOW
Definition: blobbox.h:89
@ BND_RIGHT
Definition: blobbox.h:90
GridSearch< BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT > BlobGridSearch
Definition: blobgrid.h:31
bool good_stroke_neighbour(BlobNeighbourDir n) const
Definition: blobbox.h:373
bool vert_possible() const
Definition: blobbox.h:301
BLOBNBOX * neighbour(BlobNeighbourDir n) const
Definition: blobbox.h:370
const TBOX & bounding_box() const
Definition: blobbox.h:230
C_BLOB * cblob() const
Definition: blobbox.h:268
void NeighbourGaps(int gaps[BND_COUNT]) const
Definition: blobbox.cpp:181
bool horz_possible() const
Definition: blobbox.h:307
bool contains(const FCOORD pt) const
Definition: rect.h:333
virtual void HandleClick(int x, int y)
Definition: bbgrid.h:655

◆ RemoveLineResidue()

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

Definition at line 279 of file strokewidth.cpp.

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

◆ SetNeighboursOnMediumBlobs()

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

Definition at line 142 of file strokewidth.cpp.

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

◆ TestVerticalTextDirection()

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

Definition at line 208 of file strokewidth.cpp.

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

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