tesseract  4.00.00dev
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)
 
Pix * splitted_image ()
 
void set_orig_pix (Pix *pix)
 
Pix * 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 (Pix *pix)
 

Static Public Attributes

static const int kUnspecifiedXheight = -1
 

Detailed Description

Definition at line 74 of file devanagari_processing.h.

Member Enumeration Documentation

◆ SplitStrategy

Enumerator
NO_SPLIT 
MINIMAL_SPLIT 
MAXIMAL_SPLIT 

Definition at line 76 of file devanagari_processing.h.

76  {
77  NO_SPLIT = 0, // No splitting is performed for the phase.
78  MINIMAL_SPLIT, // Blobs are split minimally.
79  MAXIMAL_SPLIT // Blobs are split maximally.
80  };

Constructor & Destructor Documentation

◆ ShiroRekhaSplitter()

tesseract::ShiroRekhaSplitter::ShiroRekhaSplitter ( )

Definition at line 41 of file devanagari_processing.cpp.

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

◆ ~ShiroRekhaSplitter()

tesseract::ShiroRekhaSplitter::~ShiroRekhaSplitter ( )
virtual

Definition at line 52 of file devanagari_processing.cpp.

52  {
53  Clear();
54 }

Member Function Documentation

◆ Clear()

void tesseract::ShiroRekhaSplitter::Clear ( )

Definition at line 56 of file devanagari_processing.cpp.

56  {
57  pixDestroy(&orig_pix_);
58  pixDestroy(&splitted_image_);
59  pageseg_split_strategy_ = NO_SPLIT;
60  ocr_split_strategy_ = NO_SPLIT;
61  pixDestroy(&debug_image_);
62  segmentation_block_list_ = NULL;
63  global_xheight_ = kUnspecifiedXheight;
64  perform_close_ = false;
65 }

◆ GetModeHeight()

int tesseract::ShiroRekhaSplitter::GetModeHeight ( Pix *  pix)
static

Definition at line 410 of file devanagari_processing.cpp.

410  {
411  Boxa* boxa = pixConnComp(pix, NULL, 8);
412  STATS heights(0, pixGetHeight(pix));
413  heights.clear();
414  for (int i = 0; i < boxaGetCount(boxa); ++i) {
415  Box* box = boxaGetBox(boxa, i, L_CLONE);
416  if (box->h >= 3 || box->w >= 3) {
417  heights.add(box->h, 1);
418  }
419  boxDestroy(&box);
420  }
421  boxaDestroy(&boxa);
422  return heights.mode();
423 }
Definition: statistc.h:33

◆ HasDifferentSplitStrategies()

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

Definition at line 100 of file devanagari_processing.h.

100  {
101  return pageseg_split_strategy_ != ocr_split_strategy_;
102  }

◆ ocr_split_strategy()

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

Definition at line 137 of file devanagari_processing.h.

137  {
138  return ocr_split_strategy_;
139  }

◆ orig_pix()

Pix* tesseract::ShiroRekhaSplitter::orig_pix ( )
inline

Definition at line 133 of file devanagari_processing.h.

133  {
134  return orig_pix_;
135  }

◆ pageseg_split_strategy()

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

Definition at line 145 of file devanagari_processing.h.

145  {
146  return pageseg_split_strategy_;
147  }

◆ RefreshSegmentationWithNewBlobs()

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

Definition at line 356 of file devanagari_processing.cpp.

357  {
358  // The segmentation block list must have been specified.
359  ASSERT_HOST(segmentation_block_list_);
360  if (devanagari_split_debuglevel > 0) {
361  tprintf("Before refreshing blobs:\n");
362  PrintSegmentationStats(segmentation_block_list_);
363  tprintf("New Blobs found: %d\n", new_blobs->length());
364  }
365 
366  C_BLOB_LIST not_found_blobs;
367  RefreshWordBlobsFromNewBlobs(segmentation_block_list_,
368  new_blobs,
369  ((devanagari_split_debugimage && debug_image_) ?
370  &not_found_blobs : NULL));
371 
372  if (devanagari_split_debuglevel > 0) {
373  tprintf("After refreshing blobs:\n");
374  PrintSegmentationStats(segmentation_block_list_);
375  }
376  if (devanagari_split_debugimage && debug_image_) {
377  // Plot out the original blobs for which no match was found in the new
378  // all_blobs list.
379  C_BLOB_IT not_found_it(&not_found_blobs);
380  for (not_found_it.mark_cycle_pt(); !not_found_it.cycled_list();
381  not_found_it.forward()) {
382  C_BLOB* not_found = not_found_it.data();
383  TBOX not_found_box = not_found->bounding_box();
384  Box* box_to_plot = GetBoxForTBOX(not_found_box);
385  pixRenderBoxArb(debug_image_, box_to_plot, 1, 255, 0, 255);
386  boxDestroy(&box_to_plot);
387  }
388 
389  // Plot out the blobs unused from all blobs.
390  C_BLOB_IT all_blobs_it(new_blobs);
391  for (all_blobs_it.mark_cycle_pt(); !all_blobs_it.cycled_list();
392  all_blobs_it.forward()) {
393  C_BLOB* a_blob = all_blobs_it.data();
394  Box* box_to_plot = GetBoxForTBOX(a_blob->bounding_box());
395  pixRenderBoxArb(debug_image_, box_to_plot, 3, 0, 127, 0);
396  boxDestroy(&box_to_plot);
397  }
398  }
399 }
void RefreshWordBlobsFromNewBlobs(BLOCK_LIST *block_list, C_BLOB_LIST *new_blobs, C_BLOB_LIST *not_found_blobs)
Definition: ocrblock.cpp:478
bool devanagari_split_debugimage
#define tprintf(...)
Definition: tprintf.h:31
#define ASSERT_HOST(x)
Definition: errcode.h:84
void PrintSegmentationStats(BLOCK_LIST *block_list)
Definition: ocrblock.cpp:410
Definition: rect.h:30
TBOX bounding_box() const
Definition: stepblob.cpp:250
int devanagari_split_debuglevel

◆ segmentation_block_list()

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

Definition at line 153 of file devanagari_processing.h.

153  {
154  return segmentation_block_list_;
155  }

◆ set_global_xheight()

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

Definition at line 113 of file devanagari_processing.h.

113  {
114  global_xheight_ = xheight;
115  }

◆ set_ocr_split_strategy()

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

Definition at line 141 of file devanagari_processing.h.

141  {
142  ocr_split_strategy_ = strategy;
143  }

◆ set_orig_pix()

void tesseract::ShiroRekhaSplitter::set_orig_pix ( Pix *  pix)

Definition at line 68 of file devanagari_processing.cpp.

68  {
69  if (orig_pix_) {
70  pixDestroy(&orig_pix_);
71  }
72  orig_pix_ = pixClone(pix);
73 }

◆ set_pageseg_split_strategy()

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

Definition at line 149 of file devanagari_processing.h.

149  {
150  pageseg_split_strategy_ = strategy;
151  }

◆ set_perform_close()

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

Definition at line 117 of file devanagari_processing.h.

117  {
118  perform_close_ = perform;
119  }

◆ set_segmentation_block_list()

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

Definition at line 107 of file devanagari_processing.h.

107  {
108  segmentation_block_list_ = block_list;
109  }

◆ Split()

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

Definition at line 80 of file devanagari_processing.cpp.

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

◆ splitted_image()

Pix* tesseract::ShiroRekhaSplitter::splitted_image ( )
inline

Definition at line 124 of file devanagari_processing.h.

124  {
125  return splitted_image_;
126  }

Member Data Documentation

◆ kUnspecifiedXheight

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

Definition at line 111 of file devanagari_processing.h.


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