Tesseract  3.02
tesseract::StrokeWidth Class Reference

#include <strokewidth.h>

Inheritance diagram for tesseract::StrokeWidth:
tesseract::BlobGrid tesseract::BBGrid< BLOBNBOX, BLOBNBOX_CLIST, BLOBNBOX_C_IT > tesseract::GridBase

List of all members.

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)

Detailed Description

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.


Constructor & Destructor Documentation

tesseract::StrokeWidth::StrokeWidth ( int  gridsize,
const ICOORD bleft,
const ICOORD tright 
)

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

Member Function Documentation

void tesseract::StrokeWidth::CorrectForRotation ( const FCOORD rerotation,
ColPartitionGrid part_grid 
)

Definition at line 263 of file strokewidth.cpp.

                                                                  {
  Init(part_grid->gridsize(), part_grid->bleft(), part_grid->tright());
  grid_box_ = TBOX(bleft(), tright());
  rerotation_.set_x(rotation.x());
  rerotation_.set_y(-rotation.y());
}
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;
  }
}

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