tesseract v5.3.3.20231005
tesseract::C_BLOB Class Reference

#include <stepblob.h>

Inheritance diagram for tesseract::C_BLOB:
tesseract::ELIST_LINK

Public Member Functions

 C_BLOB ()=default
 
 C_BLOB (C_OUTLINE_LIST *outline_list)
 
 C_BLOB (C_OUTLINE *outline)
 
void CheckInverseFlagAndDirection ()
 
C_OUTLINE_LIST * out_list ()
 
TBOX bounding_box () const
 
int32_t area ()
 
int32_t perimeter ()
 
int32_t outer_area ()
 
int32_t count_transitions (int32_t threshold)
 
void move (const ICOORD vec)
 
void rotate (const FCOORD &rotation)
 
void ComputeEdgeOffsets (int threshold, Image pix)
 
int16_t EstimateBaselinePosition ()
 
Image render ()
 
Image render_outline ()
 
void plot (ScrollView *window, ScrollView::Color blob_colour, ScrollView::Color child_colour)
 
void plot_normed (const DENORM &denorm, ScrollView::Color blob_colour, ScrollView::Color child_colour, ScrollView *window)
 
C_BLOBoperator= (const C_BLOB &source)
 
- Public Member Functions inherited from tesseract::ELIST_LINK
 ELIST_LINK ()
 
 ELIST_LINK (const ELIST_LINK &)
 
void operator= (const ELIST_LINK &)
 

Static Public Member Functions

static void ConstructBlobsFromOutlines (bool good_blob, C_OUTLINE_LIST *outline_list, C_BLOB_IT *good_blobs_it, C_BLOB_IT *bad_blobs_it)
 
static C_BLOBFakeBlob (const TBOX &box)
 
static C_BLOBdeep_copy (const C_BLOB *src)
 
static int SortByXMiddle (const void *v1, const void *v2)
 

Detailed Description

Definition at line 40 of file stepblob.h.

Constructor & Destructor Documentation

◆ C_BLOB() [1/3]

tesseract::C_BLOB::C_BLOB ( )
default

◆ C_BLOB() [2/3]

tesseract::C_BLOB::C_BLOB ( C_OUTLINE_LIST *  outline_list)
explicit

Definition at line 162 of file stepblob.cpp.

162 {
163 for (C_OUTLINE_IT ol_it(outline_list); !ol_it.empty(); ol_it.forward()) {
164 C_OUTLINE *outline = ol_it.extract();
165 // Position this outline in appropriate position in the hierarchy.
166 position_outline(outline, &outlines);
167 }
169}
void CheckInverseFlagAndDirection()
Definition: stepblob.cpp:222

◆ C_BLOB() [3/3]

tesseract::C_BLOB::C_BLOB ( C_OUTLINE outline)
explicit

Definition at line 173 of file stepblob.cpp.

173 {
174 C_OUTLINE_IT it(&outlines);
175 it.add_to_end(outline);
176}

Member Function Documentation

◆ area()

int32_t tesseract::C_BLOB::area ( )

Definition at line 268 of file stepblob.cpp.

268 { // area
269 C_OUTLINE_IT it = &outlines; // outlines of blob
270 int32_t total = 0; // total area
271
272 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
273 C_OUTLINE *outline = it.data();
274 total += outline->area();
275 }
276 return total;
277}

◆ bounding_box()

TBOX tesseract::C_BLOB::bounding_box ( ) const

Definition at line 250 of file stepblob.cpp.

250 { // bounding box
251 // This is a read-only iteration of the outlines.
252 C_OUTLINE_IT it = const_cast<C_OUTLINE_LIST *>(&outlines);
253 TBOX box; // bounding box
254
255 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
256 C_OUTLINE *outline = it.data();
257 box += outline->bounding_box();
258 }
259 return box;
260}
@ TBOX

◆ CheckInverseFlagAndDirection()

void tesseract::C_BLOB::CheckInverseFlagAndDirection ( )

Definition at line 222 of file stepblob.cpp.

222 {
223 C_OUTLINE_IT ol_it(&outlines);
224 for (ol_it.mark_cycle_pt(); !ol_it.cycled_list(); ol_it.forward()) {
225 C_OUTLINE *outline = ol_it.data();
226 if (outline->turn_direction() < 0) {
227 outline->reverse();
228 reverse_outline_list(outline->child());
229 outline->set_flag(COUT_INVERSE, true);
230 } else {
231 outline->set_flag(COUT_INVERSE, false);
232 }
233 }
234}
@ COUT_INVERSE
Definition: coutln.h:46

◆ ComputeEdgeOffsets()

void tesseract::C_BLOB::ComputeEdgeOffsets ( int  threshold,
Image  pix 
)

Definition at line 398 of file stepblob.cpp.

398 {
399 ComputeEdgeOffsetsOutlineList(threshold, pix, &outlines);
400}

◆ ConstructBlobsFromOutlines()

void tesseract::C_BLOB::ConstructBlobsFromOutlines ( bool  good_blob,
C_OUTLINE_LIST *  outline_list,
C_BLOB_IT *  good_blobs_it,
C_BLOB_IT *  bad_blobs_it 
)
static

Definition at line 188 of file stepblob.cpp.

189 {
190 // List of top-level outlines with correctly nested children.
191 C_OUTLINE_LIST nested_outlines;
192 for (C_OUTLINE_IT ol_it(outline_list); !ol_it.empty(); ol_it.forward()) {
193 C_OUTLINE *outline = ol_it.extract();
194 // Position this outline in appropriate position in the hierarchy.
195 position_outline(outline, &nested_outlines);
196 }
197 // Check for legal nesting and reassign as required.
198 for (C_OUTLINE_IT ol_it(&nested_outlines); !ol_it.empty(); ol_it.forward()) {
199 C_OUTLINE *outline = ol_it.extract();
200 bool blob_is_good = good_blob;
201 if (!outline->IsLegallyNested()) {
202 // The blob is illegally nested.
203 // Mark it bad, and add all its children to the top-level list.
204 blob_is_good = false;
205 ol_it.add_list_after(outline->child());
206 }
207 auto *blob = new C_BLOB(outline);
208 // Set inverse flag and reverse if needed.
209 blob->CheckInverseFlagAndDirection();
210 // Put on appropriate list.
211 if (!blob_is_good && bad_blobs_it != nullptr) {
212 bad_blobs_it->add_after_then_move(blob);
213 } else {
214 good_blobs_it->add_after_then_move(blob);
215 }
216 }
217}

◆ count_transitions()

int32_t tesseract::C_BLOB::count_transitions ( int32_t  threshold)

Definition at line 320 of file stepblob.cpp.

322 {
323 C_OUTLINE_IT it = &outlines; // outlines of blob
324 int32_t total = 0; // total area
325
326 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
327 C_OUTLINE *outline = it.data();
328 total += outline->count_transitions(threshold);
329 }
330 return total;
331}

◆ deep_copy()

static C_BLOB * tesseract::C_BLOB::deep_copy ( const C_BLOB src)
inlinestatic

Definition at line 118 of file stepblob.h.

118 {
119 auto *blob = new C_BLOB;
120 *blob = *src;
121 return blob;
122 }

◆ EstimateBaselinePosition()

int16_t tesseract::C_BLOB::EstimateBaselinePosition ( )

Definition at line 416 of file stepblob.cpp.

416 {
417 TBOX box = bounding_box();
418 int left = box.left();
419 int width = box.width();
420 int bottom = box.bottom();
421 if (outlines.empty() || perimeter() > width * kMaxPerimeterWidthRatio) {
422 return bottom; // This is only for non-CJK blobs.
423 }
424 // Get the minimum y coordinate at each x-coordinate.
425 std::vector<int> y_mins(width + 1, box.top());
426 C_OUTLINE_IT it(&outlines);
427 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
428 C_OUTLINE *outline = it.data();
429 ICOORD pos = outline->start_pos();
430 for (int s = 0; s < outline->pathlength(); ++s) {
431 if (pos.y() < y_mins[pos.x() - left]) {
432 y_mins[pos.x() - left] = pos.y();
433 }
434 pos += outline->step(s);
435 }
436 }
437 // Find the total extent of the bottom or bottom + 1.
438 int bottom_extent = 0;
439 for (int x = 0; x <= width; ++x) {
440 if (y_mins[x] == bottom || y_mins[x] == bottom + 1) {
441 ++bottom_extent;
442 }
443 }
444 // Find the lowest run longer than the bottom extent that is not the bottom.
445 int best_min = box.top();
446 int prev_run = 0;
447 int prev_y = box.top();
448 int prev_prev_y = box.top();
449 for (int x = 0; x < width; x += prev_run) {
450 // Find the length of the current run.
451 int y_at_x = y_mins[x];
452 int run = 1;
453 while (x + run <= width && y_mins[x + run] == y_at_x) {
454 ++run;
455 }
456 if (y_at_x > bottom + 1) {
457 // Possible contender.
458 int total_run = run;
459 // Find extent of current value or +1 to the right of x.
460 while (x + total_run <= width &&
461 (y_mins[x + total_run] == y_at_x || y_mins[x + total_run] == y_at_x + 1)) {
462 ++total_run;
463 }
464 // At least one end has to be higher so it is not a local max.
465 if (prev_prev_y > y_at_x + 1 || x + total_run > width || y_mins[x + total_run] > y_at_x + 1) {
466 // If the prev_run is at y + 1, then we can add that too. There cannot
467 // be a suitable run at y before that or we would have found it already.
468 if (prev_run > 0 && prev_y == y_at_x + 1) {
469 total_run += prev_run;
470 }
471 if (total_run > bottom_extent && y_at_x < best_min) {
472 best_min = y_at_x;
473 }
474 }
475 }
476 prev_run = run;
477 prev_prev_y = prev_y;
478 prev_y = y_at_x;
479 }
480 return best_min == box.top() ? bottom : best_min;
481}
const double kMaxPerimeterWidthRatio
Definition: stepblob.cpp:36
TBOX bounding_box() const
Definition: stepblob.cpp:250
int32_t perimeter()
Definition: stepblob.cpp:285

◆ FakeBlob()

C_BLOB * tesseract::C_BLOB::FakeBlob ( const TBOX box)
static

Definition at line 238 of file stepblob.cpp.

238 {
239 C_OUTLINE_LIST outlines;
240 C_OUTLINE::FakeOutline(box, &outlines);
241 return new C_BLOB(&outlines);
242}
static void FakeOutline(const TBOX &box, C_OUTLINE_LIST *outlines)
Definition: coutln.cpp:241

◆ move()

void tesseract::C_BLOB::move ( const ICOORD  vec)

Definition at line 339 of file stepblob.cpp.

341 {
342 C_OUTLINE_IT it(&outlines); // iterator
343
344 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
345 it.data()->move(vec); // move each outline
346 }
347}

◆ operator=()

C_BLOB & tesseract::C_BLOB::operator= ( const C_BLOB source)
inline

Definition at line 110 of file stepblob.h.

110 {
111 if (!outlines.empty()) {
112 outlines.clear();
113 }
114 outlines.deep_copy(&source.outlines, &C_OUTLINE::deep_copy);
115 return *this;
116 }
static C_OUTLINE * deep_copy(const C_OUTLINE *src)
Definition: coutln.h:261

◆ out_list()

C_OUTLINE_LIST * tesseract::C_BLOB::out_list ( )
inline

Definition at line 70 of file stepblob.h.

70 { // get outline list
71 return &outlines;
72 }

◆ outer_area()

int32_t tesseract::C_BLOB::outer_area ( )

Definition at line 302 of file stepblob.cpp.

302 { // area
303 C_OUTLINE_IT it = &outlines; // outlines of blob
304 int32_t total = 0; // total area
305
306 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
307 C_OUTLINE *outline = it.data();
308 total += outline->outer_area();
309 }
310 return total;
311}

◆ perimeter()

int32_t tesseract::C_BLOB::perimeter ( )

Definition at line 285 of file stepblob.cpp.

285 {
286 C_OUTLINE_IT it = &outlines; // outlines of blob
287 int32_t total = 0; // total perimeter
288
289 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
290 C_OUTLINE *outline = it.data();
291 total += outline->perimeter();
292 }
293 return total;
294}

◆ plot()

void tesseract::C_BLOB::plot ( ScrollView window,
ScrollView::Color  blob_colour,
ScrollView::Color  child_colour 
)

Definition at line 526 of file stepblob.cpp.

528 { // for holes
529 plot_outline_list(&outlines, window, blob_colour, child_colour);
530}

◆ plot_normed()

void tesseract::C_BLOB::plot_normed ( const DENORM denorm,
ScrollView::Color  blob_colour,
ScrollView::Color  child_colour,
ScrollView window 
)

Definition at line 534 of file stepblob.cpp.

535 {
536 plot_normed_outline_list(denorm, &outlines, blob_colour, child_colour, window);
537}

◆ render()

Image tesseract::C_BLOB::render ( )

Definition at line 503 of file stepblob.cpp.

503 {
504 TBOX box = bounding_box();
505 Image pix = pixCreate(box.width(), box.height(), 1);
506 render_outline_list(&outlines, box.left(), box.top(), pix);
507 return pix;
508}

◆ render_outline()

Image tesseract::C_BLOB::render_outline ( )

Definition at line 512 of file stepblob.cpp.

512 {
513 TBOX box = bounding_box();
514 Image pix = pixCreate(box.width(), box.height(), 1);
515 render_outline_list_outline(&outlines, box.left(), box.top(), pix);
516 return pix;
517}

◆ rotate()

void tesseract::C_BLOB::rotate ( const FCOORD rotation)

Definition at line 375 of file stepblob.cpp.

375 {
376 RotateOutlineList(rotation, &outlines);
377}

◆ SortByXMiddle()

static int tesseract::C_BLOB::SortByXMiddle ( const void *  v1,
const void *  v2 
)
inlinestatic

Definition at line 124 of file stepblob.h.

124 {
125 const C_BLOB *blob1 = *static_cast<const C_BLOB *const *>(v1);
126 const C_BLOB *blob2 = *static_cast<const C_BLOB *const *>(v2);
127 return blob1->bounding_box().x_middle() - blob2->bounding_box().x_middle();
128 }

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