|
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;
}
}