Tesseract  3.02
tesseract::TextlineProjection Class Reference

#include <textlineprojection.h>

List of all members.

Public Member Functions

 TextlineProjection (int resolution)
 ~TextlineProjection ()
void ConstructProjection (TO_BLOCK *input_block, const FCOORD &rotation, Pix *nontext_map)
void PlotGradedBlobs (BLOBNBOX_LIST *blobs, ScrollView *win)
void MoveNonTextlineBlobs (BLOBNBOX_LIST *blobs, BLOBNBOX_LIST *small_blobs) const
void DisplayProjection () const
int DistanceOfBoxFromPartition (const TBOX &box, const ColPartition &part, const DENORM *denorm, bool debug) const
int DistanceOfBoxFromBox (const TBOX &from_box, const TBOX &to_box, bool horizontal_textline, const DENORM *denorm, bool debug) const
int VerticalDistance (bool debug, int x, int y1, int y2) const
int HorizontalDistance (bool debug, int x1, int x2, int y) const
bool BoxOutOfHTextline (const TBOX &box, const DENORM *denorm, bool debug) const
int EvaluateColPartition (const ColPartition &part, const DENORM *denorm, bool debug) const
int EvaluateBox (const TBOX &box, const DENORM *denorm, bool debug) const

Detailed Description

Definition at line 33 of file textlineprojection.h.


Constructor & Destructor Documentation

tesseract::TextlineProjection::TextlineProjection ( int  resolution) [explicit]

Definition at line 41 of file textlineprojection.cpp.

  : x_origin_(0), y_origin_(0), pix_(NULL) {
  // The projection map should be about 100 ppi, whatever the input.
  scale_factor_ = IntCastRounded(resolution / 100.0);
  if (scale_factor_ < 1) scale_factor_ = 1;
}
tesseract::TextlineProjection::~TextlineProjection ( )

Definition at line 47 of file textlineprojection.cpp.

                                        {
  pixDestroy(&pix_);
}

Member Function Documentation

bool tesseract::TextlineProjection::BoxOutOfHTextline ( const TBOX box,
const DENORM denorm,
bool  debug 
) const

Definition at line 338 of file textlineprojection.cpp.

                                                            {
  int grad1 = 0;
  int grad2 = 0;
  EvaluateBoxInternal(box, denorm, debug, &grad1, &grad2, NULL, NULL);
  int worst_result = MIN(grad1, grad2);
  int total_result = grad1 + grad2;
  if (total_result >= 6) return false;  // Strongly in textline.
  // Medium strength: if either gradient is negative, it is likely outside
  // the body of the textline.
  if (worst_result < 0)
    return true;
  return false;
}
void tesseract::TextlineProjection::ConstructProjection ( TO_BLOCK input_block,
const FCOORD rotation,
Pix *  nontext_map 
)

Definition at line 58 of file textlineprojection.cpp.

                                                               {
  pixDestroy(&pix_);
  TBOX image_box(0, 0, pixGetWidth(nontext_map), pixGetHeight(nontext_map));
  x_origin_ = 0;
  y_origin_ = image_box.height();
  int width = (image_box.width() + scale_factor_ - 1) / scale_factor_;
  int height = (image_box.height() + scale_factor_ - 1) / scale_factor_;

  pix_ = pixCreate(width, height, 8);
  ProjectBlobs(&input_block->blobs, rotation, image_box, nontext_map);
  ProjectBlobs(&input_block->large_blobs, rotation, image_box, nontext_map);
  Pix* final_pix = pixBlockconv(pix_, 1, 1);
//  Pix* final_pix = pixBlockconv(pix_, 2, 2);
  pixDestroy(&pix_);
  pix_ = final_pix;
}
void tesseract::TextlineProjection::DisplayProjection ( ) const

Definition at line 117 of file textlineprojection.cpp.

                                                 {
  int width = pixGetWidth(pix_);
  int height = pixGetHeight(pix_);
  Pix* pixc = pixCreate(width, height, 32);
  int src_wpl = pixGetWpl(pix_);
  int col_wpl = pixGetWpl(pixc);
  uinT32* src_data = pixGetData(pix_);
  uinT32* col_data = pixGetData(pixc);
  for (int y = 0; y < height; ++y, src_data += src_wpl, col_data += col_wpl) {
    for (int x = 0; x < width; ++x) {
      int pixel = GET_DATA_BYTE(src_data, x);
      l_uint32 result;
      if (pixel <= 17)
        composeRGBPixel(0, 0, pixel * 15, &result);
      else if (pixel <= 145)
        composeRGBPixel(0, (pixel - 17) * 2, 255, &result);
      else
        composeRGBPixel((pixel - 145) * 2, 255, 255, &result);
      col_data[x] = result;
    }
  }
#if 0
  // TODO(rays) uncomment when scrollview can display non-binary images.
  ScrollView* win = new ScrollView("Projection", 0, 0,
                                   width, height, width, height);
  win->Image(pixc, 0, 0);
  win->Update();
#else
  pixWrite("projection.png", pixc, IFF_PNG);
#endif
  pixDestroy(&pixc);
}
int tesseract::TextlineProjection::DistanceOfBoxFromBox ( const TBOX from_box,
const TBOX to_box,
bool  horizontal_textline,
const DENORM denorm,
bool  debug 
) const

Definition at line 194 of file textlineprojection.cpp.

                                                               {
  // The parallel_gap is the horizontal gap between a horizontal textline and
  // the box. Analogous for vertical.
  int parallel_gap = 0;
  // start_pt is the box end of the line to be modified for curved space.
  TPOINT start_pt;
  // end_pt is the partition end of the line to be modified for curved space.
  TPOINT end_pt;
  if (horizontal_textline) {
    parallel_gap = from_box.x_gap(to_box) + from_box.width();
    start_pt.x = (from_box.left() + from_box.right()) / 2;
    end_pt.x = start_pt.x;
    if (from_box.top() - to_box.top() >= to_box.bottom() - from_box.bottom()) {
      start_pt.y = from_box.top();
      end_pt.y = MIN(to_box.top(), start_pt.y);
    } else {
      start_pt.y = from_box.bottom();
      end_pt.y = MAX(to_box.bottom(), start_pt.y);
    }
  } else {
    parallel_gap = from_box.y_gap(to_box) + from_box.height();
    if (from_box.right() - to_box.right() >= to_box.left() - from_box.left()) {
      start_pt.x = from_box.right();
      end_pt.x = MIN(to_box.right(), start_pt.x);
    } else {
      start_pt.x = from_box.left();
      end_pt.x = MAX(to_box.left(), start_pt.x);
    }
    start_pt.y = (from_box.bottom() + from_box.top()) / 2;
    end_pt.y = start_pt.y;
  }
  // The perpendicular gap is the max vertical distance gap out of:
  // top of from_box to to_box top and bottom of from_box to to_box bottom.
  // This value is then modified for curved projection space.
  // Analogous for vertical.
  int perpendicular_gap = 0;
  // If start_pt == end_pt, then the from_box lies entirely within the to_box
  // (in the perpendicular direction), so we don't need to calculate the
  // perpendicular_gap.
  if (start_pt.x != end_pt.x || start_pt.y != end_pt.y) {
    if (denorm != NULL) {
      // Denormalize the start and end.
      denorm->DenormTransform(start_pt, &start_pt);
      denorm->DenormTransform(end_pt, &end_pt);
    }
    if (abs(start_pt.y - end_pt.y) >= abs(start_pt.x - end_pt.x)) {
      perpendicular_gap = VerticalDistance(debug, start_pt.x, start_pt.y,
                                           end_pt.y);
    } else {
      perpendicular_gap = HorizontalDistance(debug, start_pt.x, end_pt.x,
                                             start_pt.y);
    }
  }
  // The parallel_gap weighs less than the perpendicular_gap.
  return perpendicular_gap + parallel_gap / kParaPerpDistRatio;
}
int tesseract::TextlineProjection::DistanceOfBoxFromPartition ( const TBOX box,
const ColPartition part,
const DENORM denorm,
bool  debug 
) const

Definition at line 154 of file textlineprojection.cpp.

                                                                     {
  // Compute a partition box that uses the median top/bottom of the blobs
  // within and median left/right for vertical.
  TBOX part_box = part.bounding_box();
  if (part.IsHorizontalType()) {
    part_box.set_top(part.median_top());
    part_box.set_bottom(part.median_bottom());
  } else {
    part_box.set_left(part.median_left());
    part_box.set_right(part.median_right());
  }
  // Now use DistanceOfBoxFromBox to make the actual calculation.
  return DistanceOfBoxFromBox(box, part_box, part.IsHorizontalType(),
                              denorm, debug);
}
int tesseract::TextlineProjection::EvaluateBox ( const TBOX box,
const DENORM denorm,
bool  debug 
) const

Definition at line 410 of file textlineprojection.cpp.

                                                      {
  return EvaluateBoxInternal(box, denorm, debug, NULL, NULL, NULL, NULL);
}
int tesseract::TextlineProjection::EvaluateColPartition ( const ColPartition part,
const DENORM denorm,
bool  debug 
) const

Definition at line 359 of file textlineprojection.cpp.

                                                               {
  if (part.IsSingleton())
    return EvaluateBox(part.bounding_box(), denorm, debug);
  // Test vertical orientation.
  TBOX box = part.bounding_box();
  // Use the partition median for left/right.
  box.set_left(part.median_left());
  box.set_right(part.median_right());
  int vresult = EvaluateBox(box, denorm, debug);

  // Test horizontal orientation.
  box = part.bounding_box();
  // Use the partition median for top/bottom.
  box.set_top(part.median_top());
  box.set_bottom(part.median_bottom());
  int hresult = EvaluateBox(box, denorm, debug);
  if (debug) {
    tprintf("Partition hresult=%d, vresult=%d from:", hresult, vresult);
    part.bounding_box().print();
    part.Print();
  }
  return hresult >= -vresult ? hresult : vresult;
}
int tesseract::TextlineProjection::HorizontalDistance ( bool  debug,
int  x1,
int  x2,
int  y 
) const

Definition at line 306 of file textlineprojection.cpp.

                                                        {
  x1 = ImageXToProjectionX(x1);
  x2 = ImageXToProjectionX(x2);
  y = ImageYToProjectionY(y);
  if (x1 == x2) return 0;
  int wpl = pixGetWpl(pix_);
  int step = x1 < x2 ? 1 : -1;
  uinT32* data = pixGetData(pix_) + y * wpl;
  int prev_pixel = GET_DATA_BYTE(data, x1);
  int distance = 0;
  int right_way_steps = 0;
  for (int x = x1; x != x2; x += step) {
    int pixel = GET_DATA_BYTE(data, x + step);
    if (debug)
      tprintf("At (%d,%d), pix = %d, prev=%d\n",
              x + step, y, pixel, prev_pixel);
    if (pixel < prev_pixel)
      distance += kWrongWayPenalty;
    else if (pixel > prev_pixel)
      ++right_way_steps;
    else
      ++distance;
    prev_pixel = pixel;
  }
  return distance * scale_factor_ +
      right_way_steps * scale_factor_ / kWrongWayPenalty;
}
void tesseract::TextlineProjection::MoveNonTextlineBlobs ( BLOBNBOX_LIST *  blobs,
BLOBNBOX_LIST *  small_blobs 
) const

Definition at line 100 of file textlineprojection.cpp.

                                                            {
  BLOBNBOX_IT it(blobs);
  BLOBNBOX_IT small_it(small_blobs);
  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
    BLOBNBOX* blob = it.data();
    const TBOX& box = blob->bounding_box();
    bool debug = AlignedBlob::WithinTestRegion(2, box.left(),
                                               box.bottom());
    if (BoxOutOfHTextline(box, NULL, debug) && !blob->UniquelyVertical()) {
      blob->ClearNeighbours();
      small_it.add_to_end(it.extract());
    }
  }
}
void tesseract::TextlineProjection::PlotGradedBlobs ( BLOBNBOX_LIST *  blobs,
ScrollView win 
)

Definition at line 78 of file textlineprojection.cpp.

                                                          {
  #ifndef GRAPHICS_DISABLED
  BLOBNBOX_IT it(blobs);
  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
    BLOBNBOX* blob = it.data();
    const TBOX& box = blob->bounding_box();
    bool bad_box = BoxOutOfHTextline(box, NULL, false);
    if (blob->UniquelyVertical())
      win->Pen(ScrollView::YELLOW);
    else
      win->Pen(bad_box ? ScrollView::RED : ScrollView::BLUE);
    win->Rectangle(box.left(), box.bottom(), box.right(), box.top());
  }
  win->Update();
  #endif  // GRAPHICS_DISABLED
}
int tesseract::TextlineProjection::VerticalDistance ( bool  debug,
int  x,
int  y1,
int  y2 
) const

Definition at line 273 of file textlineprojection.cpp.

                                                               {
  x = ImageXToProjectionX(x);
  y1 = ImageYToProjectionY(y1);
  y2 = ImageYToProjectionY(y2);
  if (y1 == y2) return 0;
  int wpl = pixGetWpl(pix_);
  int step = y1 < y2 ? 1 : -1;
  uinT32* data = pixGetData(pix_) + y1 * wpl;
  wpl *= step;
  int prev_pixel = GET_DATA_BYTE(data, x);
  int distance = 0;
  int right_way_steps = 0;
  for (int y = y1; y != y2; y += step) {
    data += wpl;
    int pixel = GET_DATA_BYTE(data, x);
    if (debug)
      tprintf("At (%d,%d), pix = %d, prev=%d\n",
              x, y + step, pixel, prev_pixel);
    if (pixel < prev_pixel)
      distance += kWrongWayPenalty;
    else if (pixel > prev_pixel)
      ++right_way_steps;
    else
      ++distance;
    prev_pixel = pixel;
  }
  return distance * scale_factor_ +
      right_way_steps * scale_factor_ / kWrongWayPenalty;
}

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