Tesseract
3.02
|
#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) |
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 () |
void | DumpDebugImage (const char *filename) const |
Static Public Member Functions | |
static int | GetModeHeight (Pix *pix) |
Static Public Attributes | |
static const int | kUnspecifiedXheight = -1 |
Definition at line 66 of file devanagari_processing.h.
Definition at line 68 of file devanagari_processing.h.
{ NO_SPLIT = 0, // No splitting is performed for the phase. MINIMAL_SPLIT, // Blobs are split minimally. MAXIMAL_SPLIT // Blobs are split maximally. };
tesseract::ShiroRekhaSplitter::ShiroRekhaSplitter | ( | ) |
Definition at line 37 of file devanagari_processing.cpp.
tesseract::ShiroRekhaSplitter::~ShiroRekhaSplitter | ( | ) | [virtual] |
Definition at line 48 of file devanagari_processing.cpp.
{ Clear(); }
void tesseract::ShiroRekhaSplitter::Clear | ( | ) |
Definition at line 52 of file devanagari_processing.cpp.
{ pixDestroy(&orig_pix_); pixDestroy(&splitted_image_); pageseg_split_strategy_ = NO_SPLIT; ocr_split_strategy_ = NO_SPLIT; pixDestroy(&debug_image_); segmentation_block_list_ = NULL; global_xheight_ = kUnspecifiedXheight; perform_close_ = false; }
void tesseract::ShiroRekhaSplitter::DumpDebugImage | ( | const char * | filename | ) | const |
Definition at line 64 of file devanagari_processing.cpp.
{ pixWrite(filename, debug_image_, IFF_PNG); }
int tesseract::ShiroRekhaSplitter::GetModeHeight | ( | Pix * | pix | ) | [static] |
Definition at line 409 of file devanagari_processing.cpp.
{ Boxa* boxa = pixConnComp(pix, NULL, 8); STATS heights(0, pixGetHeight(pix)); heights.clear(); for (int i = 0; i < boxaGetCount(boxa); ++i) { Box* box = boxaGetBox(boxa, i, L_CLONE); if (box->h >= 3 || box->w >= 3) { heights.add(box->h, 1); } boxDestroy(&box); } boxaDestroy(&boxa); return heights.mode(); }
bool tesseract::ShiroRekhaSplitter::HasDifferentSplitStrategies | ( | ) | const [inline] |
Definition at line 92 of file devanagari_processing.h.
{
return pageseg_split_strategy_ != ocr_split_strategy_;
}
SplitStrategy tesseract::ShiroRekhaSplitter::ocr_split_strategy | ( | ) | const [inline] |
Definition at line 129 of file devanagari_processing.h.
{
return ocr_split_strategy_;
}
Pix* tesseract::ShiroRekhaSplitter::orig_pix | ( | ) | [inline] |
Definition at line 125 of file devanagari_processing.h.
{
return orig_pix_;
}
SplitStrategy tesseract::ShiroRekhaSplitter::pageseg_split_strategy | ( | ) | const [inline] |
Definition at line 137 of file devanagari_processing.h.
{
return pageseg_split_strategy_;
}
void tesseract::ShiroRekhaSplitter::RefreshSegmentationWithNewBlobs | ( | C_BLOB_LIST * | new_blobs | ) |
Definition at line 355 of file devanagari_processing.cpp.
{ // The segmentation block list must have been specified. ASSERT_HOST(segmentation_block_list_); if (devanagari_split_debuglevel > 0) { tprintf("Before refreshing blobs:\n"); PrintSegmentationStats(segmentation_block_list_); tprintf("New Blobs found: %d\n", new_blobs->length()); } C_BLOB_LIST not_found_blobs; RefreshWordBlobsFromNewBlobs(segmentation_block_list_, new_blobs, ((devanagari_split_debugimage && debug_image_) ? ¬_found_blobs : NULL)); if (devanagari_split_debuglevel > 0) { tprintf("After refreshing blobs:\n"); PrintSegmentationStats(segmentation_block_list_); } if (devanagari_split_debugimage && debug_image_) { // Plot out the original blobs for which no match was found in the new // all_blobs list. C_BLOB_IT not_found_it(¬_found_blobs); for (not_found_it.mark_cycle_pt(); !not_found_it.cycled_list(); not_found_it.forward()) { C_BLOB* not_found = not_found_it.data(); TBOX not_found_box = not_found->bounding_box(); Box* box_to_plot = GetBoxForTBOX(not_found_box); pixRenderBoxArb(debug_image_, box_to_plot, 1, 255, 0, 255); boxDestroy(&box_to_plot); } // Plot out the blobs unused from all blobs. C_BLOB_IT all_blobs_it(new_blobs); for (all_blobs_it.mark_cycle_pt(); !all_blobs_it.cycled_list(); all_blobs_it.forward()) { C_BLOB* a_blob = all_blobs_it.data(); Box* box_to_plot = GetBoxForTBOX(a_blob->bounding_box()); pixRenderBoxArb(debug_image_, box_to_plot, 3, 0, 127, 0); boxDestroy(&box_to_plot); } } }
BLOCK_LIST* tesseract::ShiroRekhaSplitter::segmentation_block_list | ( | ) | [inline] |
Definition at line 145 of file devanagari_processing.h.
{
return segmentation_block_list_;
}
void tesseract::ShiroRekhaSplitter::set_global_xheight | ( | int | xheight | ) | [inline] |
Definition at line 105 of file devanagari_processing.h.
{ global_xheight_ = xheight; }
void tesseract::ShiroRekhaSplitter::set_ocr_split_strategy | ( | SplitStrategy | strategy | ) | [inline] |
Definition at line 133 of file devanagari_processing.h.
{ ocr_split_strategy_ = strategy; }
void tesseract::ShiroRekhaSplitter::set_orig_pix | ( | Pix * | pix | ) |
Definition at line 69 of file devanagari_processing.cpp.
{
if (orig_pix_) {
pixDestroy(&orig_pix_);
}
orig_pix_ = pixClone(pix);
}
void tesseract::ShiroRekhaSplitter::set_pageseg_split_strategy | ( | SplitStrategy | strategy | ) | [inline] |
Definition at line 141 of file devanagari_processing.h.
{ pageseg_split_strategy_ = strategy; }
void tesseract::ShiroRekhaSplitter::set_perform_close | ( | bool | perform | ) | [inline] |
Definition at line 109 of file devanagari_processing.h.
{ perform_close_ = perform; }
void tesseract::ShiroRekhaSplitter::set_segmentation_block_list | ( | BLOCK_LIST * | block_list | ) | [inline] |
Definition at line 99 of file devanagari_processing.h.
{ segmentation_block_list_ = block_list; }
bool tesseract::ShiroRekhaSplitter::Split | ( | bool | split_for_pageseg | ) |
Definition at line 81 of file devanagari_processing.cpp.
{ SplitStrategy split_strategy = split_for_pageseg ? pageseg_split_strategy_ : ocr_split_strategy_; if (split_strategy == NO_SPLIT) { return false; // Nothing to do. } ASSERT_HOST(split_strategy == MINIMAL_SPLIT || split_strategy == MAXIMAL_SPLIT); ASSERT_HOST(orig_pix_); if (devanagari_split_debuglevel > 0) { tprintf("Splitting shiro-rekha ...\n"); tprintf("Split strategy = %s\n", split_strategy == MINIMAL_SPLIT ? "Minimal" : "Maximal"); tprintf("Initial pageseg available = %s\n", segmentation_block_list_ ? "yes" : "no"); } // Create a copy of original image to store the splitting output. pixDestroy(&splitted_image_); splitted_image_ = pixCopy(NULL, orig_pix_); // Initialize debug image if required. if (devanagari_split_debugimage) { pixDestroy(&debug_image_); debug_image_ = pixConvertTo32(orig_pix_); } // Determine all connected components in the input image. A close operation // may be required prior to this, depending on the current settings. Pix* pix_for_ccs = pixClone(orig_pix_); if (perform_close_ && global_xheight_ != kUnspecifiedXheight && !segmentation_block_list_) { if (devanagari_split_debuglevel > 0) { tprintf("Performing a global close operation..\n"); } // A global measure is available for xheight, but no local information // exists. pixDestroy(&pix_for_ccs); pix_for_ccs = pixCopy(NULL, orig_pix_); PerformClose(pix_for_ccs, global_xheight_); } Pixa* ccs; Boxa* tmp_boxa = pixConnComp(pix_for_ccs, &ccs, 8); boxaDestroy(&tmp_boxa); pixDestroy(&pix_for_ccs); // Iterate over all connected components. Get their bounding boxes and clip // out the image regions corresponding to these boxes from the original image. // Conditionally run splitting on each of them. Boxa* regions_to_clear = boxaCreate(0); for (int i = 0; i < pixaGetCount(ccs); ++i) { Box* box = ccs->boxa->box[i]; Pix* word_pix = pixClipRectangle(orig_pix_, box, NULL); ASSERT_HOST(word_pix); int xheight = GetXheightForCC(box); if (xheight == kUnspecifiedXheight && segmentation_block_list_ && devanagari_split_debugimage) { pixRenderBoxArb(debug_image_, box, 1, 255, 0, 0); } // If some xheight measure is available, attempt to pre-eliminate small // blobs from the shiro-rekha process. This is primarily to save the CCs // corresponding to punctuation marks/small dots etc which are part of // larger graphemes. if (xheight == kUnspecifiedXheight || (box->w > xheight / 3 && box->h > xheight / 2)) { SplitWordShiroRekha(split_strategy, word_pix, xheight, box->x, box->y, regions_to_clear); } else if (devanagari_split_debuglevel > 0) { tprintf("CC dropped from splitting: %d,%d (%d, %d)\n", box->x, box->y, box->w, box->h); } pixDestroy(&word_pix); } // Actually clear the boxes now. for (int i = 0; i < boxaGetCount(regions_to_clear); ++i) { Box* box = boxaGetBox(regions_to_clear, i, L_CLONE); pixClearInRect(splitted_image_, box); boxDestroy(&box); } boxaDestroy(®ions_to_clear); pixaDestroy(&ccs); if (devanagari_split_debugimage) { DumpDebugImage(split_for_pageseg ? "pageseg_split_debug.png" : "ocr_split_debug.png"); } return true; }
Pix* tesseract::ShiroRekhaSplitter::splitted_image | ( | ) | [inline] |
Definition at line 116 of file devanagari_processing.h.
{
return splitted_image_;
}
const int tesseract::ShiroRekhaSplitter::kUnspecifiedXheight = -1 [static] |
Definition at line 103 of file devanagari_processing.h.