Tesseract
3.02
|
#include <strokewidth.h>
Public Member Functions | |
StrokeWidth (int gridsize, const ICOORD &bleft, const ICOORD &tright) | |
virtual | ~StrokeWidth () |
void | SetNeighboursOnMediumBlobs (TO_BLOCK *block) |
void | FindTextlineDirectionAndFixBrokenCJK (bool cjk_merge, TO_BLOCK *input_block) |
bool | TestVerticalTextDirection (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 (const FCOORD &rerotation, TO_BLOCK *block, Pix *nontext_pix, const DENORM *denorm, TextlineProjection *projection, ColPartitionGrid *part_grid, ColPartition_LIST *big_parts) |
virtual void | HandleClick (int x, int y) |
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 49 of file strokewidth.h.
Definition at line 121 of file strokewidth.cpp.
: BlobGrid(gridsize, bleft, tright), nontext_map_(NULL), projection_(NULL), denorm_(NULL), grid_box_(bleft, tright), rerotation_(1.0f, 0.0f) { leaders_win_ = NULL; widths_win_ = NULL; initial_widths_win_ = NULL; chains_win_ = NULL; diacritics_win_ = NULL; textlines_win_ = NULL; smoothed_win_ = NULL; }
tesseract::StrokeWidth::~StrokeWidth | ( | ) | [virtual] |
Definition at line 134 of file strokewidth.cpp.
{ if (widths_win_ != NULL) { #ifndef GRAPHICS_DISABLED delete widths_win_->AwaitEvent(SVET_DESTROY); #endif // GRAPHICS_DISABLED if (textord_tabfind_only_strokewidths) exit(0); delete widths_win_; } delete leaders_win_; delete initial_widths_win_; delete chains_win_; delete textlines_win_; delete smoothed_win_; delete diacritics_win_; }
void tesseract::StrokeWidth::CorrectForRotation | ( | const FCOORD & | rerotation, |
ColPartitionGrid * | part_grid | ||
) |
void tesseract::StrokeWidth::FindLeaderPartitions | ( | TO_BLOCK * | block, |
ColPartitionGrid * | part_grid | ||
) |
Definition at line 272 of file strokewidth.cpp.
{ Clear(); // Find and isolate leaders in the noise list. ColPartition_LIST leader_parts; FindLeadersAndMarkNoise(block, &leader_parts); // Setup the strokewidth grid with the block's remaining (non-noise) blobs. InsertBlobList(&block->blobs); // Mark blobs that have leader neighbours. for (ColPartition_IT it(&leader_parts); !it.empty(); it.forward()) { ColPartition* part = it.extract(); part->ClaimBoxes(); MarkLeaderNeighbours(part, LR_LEFT); MarkLeaderNeighbours(part, LR_RIGHT); part_grid->InsertBBox(true, true, part); } }
void tesseract::StrokeWidth::FindTextlineDirectionAndFixBrokenCJK | ( | bool | cjk_merge, |
TO_BLOCK * | input_block | ||
) |
Definition at line 168 of file strokewidth.cpp.
{ // Setup the grid with the remaining (non-noise) blobs. InsertBlobs(input_block); // Repair broken CJK characters if needed. while (cjk_merge && FixBrokenCJK(input_block)); // Grade blobs by inspection of neighbours. FindTextlineFlowDirection(false); // Clear the grid ready for rotation or leader finding. Clear(); }
void tesseract::StrokeWidth::GradeBlobsIntoPartitions | ( | const FCOORD & | rerotation, |
TO_BLOCK * | block, | ||
Pix * | nontext_pix, | ||
const DENORM * | denorm, | ||
TextlineProjection * | projection, | ||
ColPartitionGrid * | part_grid, | ||
ColPartition_LIST * | big_parts | ||
) |
Definition at line 356 of file strokewidth.cpp.
{ nontext_map_ = nontext_pix; projection_ = projection; denorm_ = denorm; // Clear and re Insert to take advantage of the tab stops in the blobs. Clear(); // Setup the strokewidth grid with the remaining non-noise, non-leader blobs. InsertBlobs(block); // Run FixBrokenCJK() again if the page is rotated and the blobs // lists are reset and re-flitered, because we may have some new // blobs in the medium blob list. if (rerotation_.x() != 1.0f || rerotation_.y() != 0.0f) { FixBrokenCJK(block); } FindTextlineFlowDirection(true); projection_->ConstructProjection(block, rerotation, nontext_map_); if (textord_tabfind_show_strokewidths) { ScrollView* line_blobs_win = MakeWindow(0, 0, "Initial textline Blobs"); projection_->PlotGradedBlobs(&block->blobs, line_blobs_win); projection_->PlotGradedBlobs(&block->small_blobs, line_blobs_win); } projection_->MoveNonTextlineBlobs(&block->blobs, &block->noise_blobs); projection_->MoveNonTextlineBlobs(&block->small_blobs, &block->noise_blobs); // Clear and re Insert to take advantage of the removed diacritics. Clear(); InsertBlobs(block); FindInitialPartitions(rerotation, block, part_grid, big_parts); nontext_map_ = NULL; projection_ = NULL; denorm_ = NULL; }
void tesseract::StrokeWidth::HandleClick | ( | int | x, |
int | y | ||
) | [virtual] |
Handles a click event in a display window.
Reimplemented from tesseract::BBGrid< BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT >.
Definition at line 404 of file strokewidth.cpp.
{ BBGrid<BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT>::HandleClick(x, y); // Run a radial search for blobs that overlap. BlobGridSearch radsearch(this); radsearch.StartRadSearch(x, y, 1); BLOBNBOX* neighbour; FCOORD click(static_cast<float>(x), static_cast<float>(y)); while ((neighbour = radsearch.NextRadSearch()) != NULL) { TBOX nbox = neighbour->bounding_box(); if (nbox.contains(click) && neighbour->cblob() != NULL) { PrintBoxWidths(neighbour); if (neighbour->neighbour(BND_LEFT) != NULL) PrintBoxWidths(neighbour->neighbour(BND_LEFT)); if (neighbour->neighbour(BND_RIGHT) != NULL) PrintBoxWidths(neighbour->neighbour(BND_RIGHT)); if (neighbour->neighbour(BND_ABOVE) != NULL) PrintBoxWidths(neighbour->neighbour(BND_ABOVE)); if (neighbour->neighbour(BND_BELOW) != NULL) PrintBoxWidths(neighbour->neighbour(BND_BELOW)); int gaps[BND_COUNT]; neighbour->NeighbourGaps(gaps); tprintf("Left gap=%d, right=%d, above=%d, below=%d, horz=%d, vert=%d\n" "Good= %d %d %d %d\n", gaps[BND_LEFT], gaps[BND_RIGHT], gaps[BND_ABOVE], gaps[BND_BELOW], neighbour->horz_possible(), neighbour->vert_possible(), neighbour->good_stroke_neighbour(BND_LEFT), neighbour->good_stroke_neighbour(BND_RIGHT), neighbour->good_stroke_neighbour(BND_ABOVE), neighbour->good_stroke_neighbour(BND_BELOW)); break; } } }
void tesseract::StrokeWidth::RemoveLineResidue | ( | ColPartition_LIST * | big_part_list | ) |
Definition at line 292 of file strokewidth.cpp.
{ BlobGridSearch gsearch(this); BLOBNBOX* bbox; // For every vertical line-like bbox in the grid, search its neighbours // to find the tallest, and if the original box is taller by sufficient // margin, then call it line residue and delete it. gsearch.StartFullSearch(); while ((bbox = gsearch.NextFullSearch()) != NULL) { TBOX box = bbox->bounding_box(); if (box.height() < box.width() * kLineResidueAspectRatio) continue; // Set up a rectangle search around the blob to find the size of its // neighbours. int padding = box.height() * kLineResiduePadRatio; TBOX search_box = box; search_box.pad(padding, padding); bool debug = AlignedBlob::WithinTestRegion(2, box.left(), box.bottom()); // Find the largest object in the search box not equal to bbox. BlobGridSearch rsearch(this); int max_size = 0; BLOBNBOX* n; rsearch.StartRectSearch(search_box); while ((n = rsearch.NextRectSearch()) != NULL) { if (n == bbox) continue; TBOX nbox = n->bounding_box(); if (nbox.height() > max_size) { max_size = nbox.height(); } } if (debug) { tprintf("Max neighbour size=%d for candidate line box at:", max_size); box.print(); } if (max_size * kLineResidueSizeRatio < box.height()) { #ifndef GRAPHICS_DISABLED if (leaders_win_ != NULL) { // We are debugging, so display deleted in pink blobs in the same // window that we use to display leader detection. leaders_win_->Pen(ScrollView::PINK); leaders_win_->Rectangle(box.left(), box.bottom(), box.right(), box.top()); } #endif // GRAPHICS_DISABLED ColPartition::MakeBigPartition(bbox, big_part_list); } } }
void tesseract::StrokeWidth::SetNeighboursOnMediumBlobs | ( | TO_BLOCK * | block | ) |
Definition at line 154 of file strokewidth.cpp.
{ // Run a preliminary strokewidth neighbour detection on the medium blobs. InsertBlobList(&block->blobs); BLOBNBOX_IT blob_it(&block->blobs); for (blob_it.mark_cycle_pt(); !blob_it.cycled_list(); blob_it.forward()) { SetNeighbours(false, false, blob_it.data()); } Clear(); }
bool tesseract::StrokeWidth::TestVerticalTextDirection | ( | TO_BLOCK * | block, |
BLOBNBOX_CLIST * | osd_blobs | ||
) |
Definition at line 219 of file strokewidth.cpp.
{ if (textord_tabfind_force_vertical_text) return true; if (!textord_tabfind_vertical_text) return false; int vertical_boxes = 0; int horizontal_boxes = 0; // Count vertical normal and large blobs. BLOBNBOX_CLIST vertical_blobs; BLOBNBOX_CLIST horizontal_blobs; BLOBNBOX_CLIST nondescript_blobs; CollectHorizVertBlobs(&block->blobs, &vertical_boxes, &horizontal_boxes, &vertical_blobs, &horizontal_blobs, &nondescript_blobs); CollectHorizVertBlobs(&block->large_blobs, &vertical_boxes, &horizontal_boxes, &vertical_blobs, &horizontal_blobs, &nondescript_blobs); if (textord_debug_tabfind) tprintf("TextDir hbox=%d vs vbox=%d, %dH, %dV, %dN osd blobs\n", horizontal_boxes, vertical_boxes, horizontal_blobs.length(), vertical_blobs.length(), nondescript_blobs.length()); if (osd_blobs != NULL && vertical_boxes == 0 && horizontal_boxes == 0) { // Only nondescript blobs available, so return those. BLOBNBOX_C_IT osd_it(osd_blobs); osd_it.add_list_after(&nondescript_blobs); return false; } int min_vert_boxes = static_cast<int>((vertical_boxes + horizontal_boxes) * textord_tabfind_vertical_text_ratio); if (vertical_boxes >= min_vert_boxes) { if (osd_blobs != NULL) { BLOBNBOX_C_IT osd_it(osd_blobs); osd_it.add_list_after(&vertical_blobs); } return true; } else { if (osd_blobs != NULL) { BLOBNBOX_C_IT osd_it(osd_blobs); osd_it.add_list_after(&horizontal_blobs); } return false; } }