tesseract  5.0.0
tesseract::ShiroRekhaSplitter Class Reference

#include <devanagari_processing.h>

Public Types

enum  SplitStrategy { NO_SPLIT = 0 , MINIMAL_SPLIT , MAXIMAL_SPLIT }
 

Public Member Functions

 ShiroRekhaSplitter ()
 
virtual ~ShiroRekhaSplitter ()
 
bool Split (bool split_for_pageseg, DebugPixa *pixa_debug)
 
void Clear ()
 
void RefreshSegmentationWithNewBlobs (C_BLOB_LIST *new_blobs)
 
bool HasDifferentSplitStrategies () const
 
void set_segmentation_block_list (BLOCK_LIST *block_list)
 
void set_global_xheight (int xheight)
 
void set_perform_close (bool perform)
 
Image splitted_image ()
 
void set_orig_pix (Image pix)
 
Image orig_pix ()
 
SplitStrategy ocr_split_strategy () const
 
void set_ocr_split_strategy (SplitStrategy strategy)
 
SplitStrategy pageseg_split_strategy () const
 
void set_pageseg_split_strategy (SplitStrategy strategy)
 
BLOCK_LIST * segmentation_block_list ()
 

Static Public Member Functions

static int GetModeHeight (Image pix)
 

Static Public Attributes

static const int kUnspecifiedXheight = -1
 

Detailed Description

Definition at line 70 of file devanagari_processing.h.

Member Enumeration Documentation

◆ SplitStrategy

Enumerator
NO_SPLIT 
MINIMAL_SPLIT 
MAXIMAL_SPLIT 

Definition at line 72 of file devanagari_processing.h.

72  {
73  NO_SPLIT = 0, // No splitting is performed for the phase.
74  MINIMAL_SPLIT, // Blobs are split minimally.
75  MAXIMAL_SPLIT // Blobs are split maximally.
76  };

Constructor & Destructor Documentation

◆ ShiroRekhaSplitter()

tesseract::ShiroRekhaSplitter::ShiroRekhaSplitter ( )

Definition at line 42 of file devanagari_processing.cpp.

42  {
43  orig_pix_ = nullptr;
44  segmentation_block_list_ = nullptr;
45  splitted_image_ = nullptr;
46  global_xheight_ = kUnspecifiedXheight;
47  perform_close_ = false;
48  debug_image_ = nullptr;
49  pageseg_split_strategy_ = NO_SPLIT;
50  ocr_split_strategy_ = NO_SPLIT;
51 }

◆ ~ShiroRekhaSplitter()

tesseract::ShiroRekhaSplitter::~ShiroRekhaSplitter ( )
virtual

Definition at line 53 of file devanagari_processing.cpp.

53  {
54  Clear();
55 }

Member Function Documentation

◆ Clear()

void tesseract::ShiroRekhaSplitter::Clear ( )

Definition at line 57 of file devanagari_processing.cpp.

57  {
58  orig_pix_.destroy();
59  splitted_image_.destroy();
60  pageseg_split_strategy_ = NO_SPLIT;
61  ocr_split_strategy_ = NO_SPLIT;
62  debug_image_.destroy();
63  segmentation_block_list_ = nullptr;
64  global_xheight_ = kUnspecifiedXheight;
65  perform_close_ = false;
66 }
void destroy()
Definition: image.cpp:32

◆ GetModeHeight()

int tesseract::ShiroRekhaSplitter::GetModeHeight ( Image  pix)
static

Definition at line 388 of file devanagari_processing.cpp.

388  {
389  Boxa *boxa = pixConnComp(pix, nullptr, 8);
390  STATS heights(0, pixGetHeight(pix));
391  heights.clear();
392  for (int i = 0; i < boxaGetCount(boxa); ++i) {
393  Box *box = boxaGetBox(boxa, i, L_CLONE);
394  if (box->h >= 3 || box->w >= 3) {
395  heights.add(box->h, 1);
396  }
397  boxDestroy(&box);
398  }
399  boxaDestroy(&boxa);
400  return heights.mode();
401 }

◆ HasDifferentSplitStrategies()

bool tesseract::ShiroRekhaSplitter::HasDifferentSplitStrategies ( ) const
inline

Definition at line 96 of file devanagari_processing.h.

96  {
97  return pageseg_split_strategy_ != ocr_split_strategy_;
98  }

◆ ocr_split_strategy()

SplitStrategy tesseract::ShiroRekhaSplitter::ocr_split_strategy ( ) const
inline

Definition at line 133 of file devanagari_processing.h.

133  {
134  return ocr_split_strategy_;
135  }

◆ orig_pix()

Image tesseract::ShiroRekhaSplitter::orig_pix ( )
inline

Definition at line 129 of file devanagari_processing.h.

129  {
130  return orig_pix_;
131  }

◆ pageseg_split_strategy()

SplitStrategy tesseract::ShiroRekhaSplitter::pageseg_split_strategy ( ) const
inline

Definition at line 141 of file devanagari_processing.h.

141  {
142  return pageseg_split_strategy_;
143  }

◆ RefreshSegmentationWithNewBlobs()

void tesseract::ShiroRekhaSplitter::RefreshSegmentationWithNewBlobs ( C_BLOB_LIST *  new_blobs)

Definition at line 338 of file devanagari_processing.cpp.

338  {
339  // The segmentation block list must have been specified.
340  ASSERT_HOST(segmentation_block_list_);
341  if (devanagari_split_debuglevel > 0) {
342  tprintf("Before refreshing blobs:\n");
343  PrintSegmentationStats(segmentation_block_list_);
344  tprintf("New Blobs found: %d\n", new_blobs->length());
345  }
346 
347  C_BLOB_LIST not_found_blobs;
349  segmentation_block_list_, new_blobs,
350  ((devanagari_split_debugimage && debug_image_) ? &not_found_blobs : nullptr));
351 
352  if (devanagari_split_debuglevel > 0) {
353  tprintf("After refreshing blobs:\n");
354  PrintSegmentationStats(segmentation_block_list_);
355  }
356  if (devanagari_split_debugimage && debug_image_) {
357  // Plot out the original blobs for which no match was found in the new
358  // all_blobs list.
359  C_BLOB_IT not_found_it(&not_found_blobs);
360  for (not_found_it.mark_cycle_pt(); !not_found_it.cycled_list(); not_found_it.forward()) {
361  C_BLOB *not_found = not_found_it.data();
362  TBOX not_found_box = not_found->bounding_box();
363  Box *box_to_plot = GetBoxForTBOX(not_found_box);
364  pixRenderBoxArb(debug_image_, box_to_plot, 1, 255, 0, 255);
365  boxDestroy(&box_to_plot);
366  }
367 
368  // Plot out the blobs unused from all blobs.
369  C_BLOB_IT all_blobs_it(new_blobs);
370  for (all_blobs_it.mark_cycle_pt(); !all_blobs_it.cycled_list(); all_blobs_it.forward()) {
371  C_BLOB *a_blob = all_blobs_it.data();
372  Box *box_to_plot = GetBoxForTBOX(a_blob->bounding_box());
373  pixRenderBoxArb(debug_image_, box_to_plot, 3, 0, 127, 0);
374  boxDestroy(&box_to_plot);
375  }
376  }
377 }
#define ASSERT_HOST(x)
Definition: errcode.h:59
@ TBOX
bool devanagari_split_debugimage
void tprintf(const char *format,...)
Definition: tprintf.cpp:41
void RefreshWordBlobsFromNewBlobs(BLOCK_LIST *block_list, C_BLOB_LIST *new_blobs, C_BLOB_LIST *not_found_blobs)
Definition: ocrblock.cpp:474
void PrintSegmentationStats(BLOCK_LIST *block_list)
Definition: ocrblock.cpp:407

◆ segmentation_block_list()

BLOCK_LIST* tesseract::ShiroRekhaSplitter::segmentation_block_list ( )
inline

Definition at line 149 of file devanagari_processing.h.

149  {
150  return segmentation_block_list_;
151  }

◆ set_global_xheight()

void tesseract::ShiroRekhaSplitter::set_global_xheight ( int  xheight)
inline

Definition at line 109 of file devanagari_processing.h.

109  {
110  global_xheight_ = xheight;
111  }

◆ set_ocr_split_strategy()

void tesseract::ShiroRekhaSplitter::set_ocr_split_strategy ( SplitStrategy  strategy)
inline

Definition at line 137 of file devanagari_processing.h.

137  {
138  ocr_split_strategy_ = strategy;
139  }

◆ set_orig_pix()

void tesseract::ShiroRekhaSplitter::set_orig_pix ( Image  pix)

Definition at line 69 of file devanagari_processing.cpp.

69  {
70  if (orig_pix_) {
71  orig_pix_.destroy();
72  }
73  orig_pix_ = pix.clone();
74 }
Image clone() const
Definition: image.cpp:24

◆ set_pageseg_split_strategy()

void tesseract::ShiroRekhaSplitter::set_pageseg_split_strategy ( SplitStrategy  strategy)
inline

Definition at line 145 of file devanagari_processing.h.

145  {
146  pageseg_split_strategy_ = strategy;
147  }

◆ set_perform_close()

void tesseract::ShiroRekhaSplitter::set_perform_close ( bool  perform)
inline

Definition at line 113 of file devanagari_processing.h.

113  {
114  perform_close_ = perform;
115  }

◆ set_segmentation_block_list()

void tesseract::ShiroRekhaSplitter::set_segmentation_block_list ( BLOCK_LIST *  block_list)
inline

Definition at line 103 of file devanagari_processing.h.

103  {
104  segmentation_block_list_ = block_list;
105  }

◆ Split()

bool tesseract::ShiroRekhaSplitter::Split ( bool  split_for_pageseg,
DebugPixa pixa_debug 
)

Definition at line 81 of file devanagari_processing.cpp.

81  {
82  SplitStrategy split_strategy = split_for_pageseg ? pageseg_split_strategy_ : ocr_split_strategy_;
83  if (split_strategy == NO_SPLIT) {
84  return false; // Nothing to do.
85  }
86  ASSERT_HOST(split_strategy == MINIMAL_SPLIT || split_strategy == MAXIMAL_SPLIT);
87  ASSERT_HOST(orig_pix_);
89  tprintf("Splitting shiro-rekha ...\n");
90  tprintf("Split strategy = %s\n", split_strategy == MINIMAL_SPLIT ? "Minimal" : "Maximal");
91  tprintf("Initial pageseg available = %s\n", segmentation_block_list_ ? "yes" : "no");
92  }
93  // Create a copy of original image to store the splitting output.
94  splitted_image_.destroy();
95  splitted_image_ = orig_pix_.copy();
96 
97  // Initialize debug image if required.
99  debug_image_.destroy();
100  debug_image_ = pixConvertTo32(orig_pix_);
101  }
102 
103  // Determine all connected components in the input image. A close operation
104  // may be required prior to this, depending on the current settings.
105  Image pix_for_ccs = orig_pix_.clone();
106  if (perform_close_ && global_xheight_ != kUnspecifiedXheight && !segmentation_block_list_) {
107  if (devanagari_split_debuglevel > 0) {
108  tprintf("Performing a global close operation..\n");
109  }
110  // A global measure is available for xheight, but no local information
111  // exists.
112  pix_for_ccs.destroy();
113  pix_for_ccs = orig_pix_.copy();
114  PerformClose(pix_for_ccs, global_xheight_);
115  }
116  Pixa *ccs;
117  Boxa *tmp_boxa = pixConnComp(pix_for_ccs, &ccs, 8);
118  boxaDestroy(&tmp_boxa);
119  pix_for_ccs.destroy();
120 
121  // Iterate over all connected components. Get their bounding boxes and clip
122  // out the image regions corresponding to these boxes from the original image.
123  // Conditionally run splitting on each of them.
124  Boxa *regions_to_clear = boxaCreate(0);
125  int num_ccs = 0;
126  if (ccs != nullptr) {
127  num_ccs = pixaGetCount(ccs);
128  }
129  for (int i = 0; i < num_ccs; ++i) {
130  Box *box = ccs->boxa->box[i];
131  Image word_pix = pixClipRectangle(orig_pix_, box, nullptr);
132  ASSERT_HOST(word_pix);
133  int xheight = GetXheightForCC(box);
134  if (xheight == kUnspecifiedXheight && segmentation_block_list_ && devanagari_split_debugimage) {
135  pixRenderBoxArb(debug_image_, box, 1, 255, 0, 0);
136  }
137  // If some xheight measure is available, attempt to pre-eliminate small
138  // blobs from the shiro-rekha process. This is primarily to save the CCs
139  // corresponding to punctuation marks/small dots etc which are part of
140  // larger graphemes.
141  if (xheight == kUnspecifiedXheight || (box->w > xheight / 3 && box->h > xheight / 2)) {
142  SplitWordShiroRekha(split_strategy, word_pix, xheight, box->x, box->y, regions_to_clear);
143  } else if (devanagari_split_debuglevel > 0) {
144  tprintf("CC dropped from splitting: %d,%d (%d, %d)\n", box->x, box->y, box->w, box->h);
145  }
146  word_pix.destroy();
147  }
148  // Actually clear the boxes now.
149  for (int i = 0; i < boxaGetCount(regions_to_clear); ++i) {
150  Box *box = boxaGetBox(regions_to_clear, i, L_CLONE);
151  pixClearInRect(splitted_image_, box);
152  boxDestroy(&box);
153  }
154  boxaDestroy(&regions_to_clear);
155  pixaDestroy(&ccs);
156  if (devanagari_split_debugimage && pixa_debug != nullptr) {
157  pixa_debug->AddPix(debug_image_, split_for_pageseg ? "pageseg_split" : "ocr_split");
158  }
159  return true;
160 }
Image copy() const
Definition: image.cpp:28

◆ splitted_image()

Image tesseract::ShiroRekhaSplitter::splitted_image ( )
inline

Definition at line 120 of file devanagari_processing.h.

120  {
121  return splitted_image_;
122  }

Member Data Documentation

◆ kUnspecifiedXheight

const int tesseract::ShiroRekhaSplitter::kUnspecifiedXheight = -1
static

Definition at line 107 of file devanagari_processing.h.


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