tesseract  5.0.0
tesseract::TextlineProjection Class Reference

#include <textlineprojection.h>

Public Member Functions

 TextlineProjection (int resolution)
 
 ~TextlineProjection ()
 
void ConstructProjection (TO_BLOCK *input_block, const FCOORD &rotation, Image 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

◆ TextlineProjection()

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

Definition at line 48 of file textlineprojection.cpp.

48  : x_origin_(0), y_origin_(0), pix_(nullptr) {
49  // The projection map should be about 100 ppi, whatever the input.
50  scale_factor_ = IntCastRounded(resolution / 100.0);
51  if (scale_factor_ < 1) {
52  scale_factor_ = 1;
53  }
54 }
int IntCastRounded(double x)
Definition: helpers.h:175

◆ ~TextlineProjection()

tesseract::TextlineProjection::~TextlineProjection ( )

Definition at line 55 of file textlineprojection.cpp.

55  {
56  pix_.destroy();
57 }
void destroy()
Definition: image.cpp:32

Member Function Documentation

◆ BoxOutOfHTextline()

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

Definition at line 340 of file textlineprojection.cpp.

341  {
342  int grad1 = 0;
343  int grad2 = 0;
344  EvaluateBoxInternal(box, denorm, debug, &grad1, &grad2, nullptr, nullptr);
345  int worst_result = std::min(grad1, grad2);
346  int total_result = grad1 + grad2;
347  if (total_result >= 6) {
348  return false; // Strongly in textline.
349  }
350  // Medium strength: if either gradient is negative, it is likely outside
351  // the body of the textline.
352  if (worst_result < 0) {
353  return true;
354  }
355  return false;
356 }

◆ ConstructProjection()

void tesseract::TextlineProjection::ConstructProjection ( TO_BLOCK input_block,
const FCOORD rotation,
Image  nontext_map 
)

Definition at line 66 of file textlineprojection.cpp.

67  {
68  pix_.destroy();
69  TBOX image_box(0, 0, pixGetWidth(nontext_map), pixGetHeight(nontext_map));
70  x_origin_ = 0;
71  y_origin_ = image_box.height();
72  int width = (image_box.width() + scale_factor_ - 1) / scale_factor_;
73  int height = (image_box.height() + scale_factor_ - 1) / scale_factor_;
74 
75  pix_ = pixCreate(width, height, 8);
76  ProjectBlobs(&input_block->blobs, rotation, image_box, nontext_map);
77  ProjectBlobs(&input_block->large_blobs, rotation, image_box, nontext_map);
78  Image final_pix = pixBlockconv(pix_, 1, 1);
79  // Pix* final_pix = pixBlockconv(pix_, 2, 2);
80  pix_.destroy();
81  pix_ = final_pix;
82 }
@ TBOX

◆ DisplayProjection()

void tesseract::TextlineProjection::DisplayProjection ( ) const

Definition at line 127 of file textlineprojection.cpp.

127  {
128  int width = pixGetWidth(pix_);
129  int height = pixGetHeight(pix_);
130  Image pixc = pixCreate(width, height, 32);
131  int src_wpl = pixGetWpl(pix_);
132  int col_wpl = pixGetWpl(pixc);
133  uint32_t *src_data = pixGetData(pix_);
134  uint32_t *col_data = pixGetData(pixc);
135  for (int y = 0; y < height; ++y, src_data += src_wpl, col_data += col_wpl) {
136  for (int x = 0; x < width; ++x) {
137  int pixel = GET_DATA_BYTE(src_data, x);
138  l_uint32 result;
139  if (pixel <= 17) {
140  composeRGBPixel(0, 0, pixel * 15, &result);
141  } else if (pixel <= 145) {
142  composeRGBPixel(0, (pixel - 17) * 2, 255, &result);
143  } else {
144  composeRGBPixel((pixel - 145) * 2, 255, 255, &result);
145  }
146  col_data[x] = result;
147  }
148  }
149  auto *win = new ScrollView("Projection", 0, 0, width, height, width, height);
150  win->Draw(pixc, 0, 0);
151  win->Update();
152  pixc.destroy();
153 }

◆ DistanceOfBoxFromBox()

int tesseract::TextlineProjection::DistanceOfBoxFromBox ( const TBOX from_box,
const TBOX to_box,
bool  horizontal_textline,
const DENORM denorm,
bool  debug 
) const

Definition at line 198 of file textlineprojection.cpp.

200  {
201  // The parallel_gap is the horizontal gap between a horizontal textline and
202  // the box. Analogous for vertical.
203  int parallel_gap = 0;
204  // start_pt is the box end of the line to be modified for curved space.
205  TPOINT start_pt;
206  // end_pt is the partition end of the line to be modified for curved space.
207  TPOINT end_pt;
208  if (horizontal_textline) {
209  parallel_gap = from_box.x_gap(to_box) + from_box.width();
210  start_pt.x = (from_box.left() + from_box.right()) / 2;
211  end_pt.x = start_pt.x;
212  if (from_box.top() - to_box.top() >= to_box.bottom() - from_box.bottom()) {
213  start_pt.y = from_box.top();
214  end_pt.y = std::min(to_box.top(), start_pt.y);
215  } else {
216  start_pt.y = from_box.bottom();
217  end_pt.y = std::max(to_box.bottom(), start_pt.y);
218  }
219  } else {
220  parallel_gap = from_box.y_gap(to_box) + from_box.height();
221  if (from_box.right() - to_box.right() >= to_box.left() - from_box.left()) {
222  start_pt.x = from_box.right();
223  end_pt.x = std::min(to_box.right(), start_pt.x);
224  } else {
225  start_pt.x = from_box.left();
226  end_pt.x = std::max(to_box.left(), start_pt.x);
227  }
228  start_pt.y = (from_box.bottom() + from_box.top()) / 2;
229  end_pt.y = start_pt.y;
230  }
231  // The perpendicular gap is the max vertical distance gap out of:
232  // top of from_box to to_box top and bottom of from_box to to_box bottom.
233  // This value is then modified for curved projection space.
234  // Analogous for vertical.
235  int perpendicular_gap = 0;
236  // If start_pt == end_pt, then the from_box lies entirely within the to_box
237  // (in the perpendicular direction), so we don't need to calculate the
238  // perpendicular_gap.
239  if (start_pt.x != end_pt.x || start_pt.y != end_pt.y) {
240  if (denorm != nullptr) {
241  // Denormalize the start and end.
242  denorm->DenormTransform(nullptr, start_pt, &start_pt);
243  denorm->DenormTransform(nullptr, end_pt, &end_pt);
244  }
245  if (abs(start_pt.y - end_pt.y) >= abs(start_pt.x - end_pt.x)) {
246  perpendicular_gap = VerticalDistance(debug, start_pt.x, start_pt.y, end_pt.y);
247  } else {
248  perpendicular_gap = HorizontalDistance(debug, start_pt.x, end_pt.x, start_pt.y);
249  }
250  }
251  // The parallel_gap weighs less than the perpendicular_gap.
252  return perpendicular_gap + parallel_gap / kParaPerpDistRatio;
253 }
const int kParaPerpDistRatio
@ TPOINT
int HorizontalDistance(bool debug, int x1, int x2, int y) const
int VerticalDistance(bool debug, int x, int y1, int y2) const

◆ DistanceOfBoxFromPartition()

int tesseract::TextlineProjection::DistanceOfBoxFromPartition ( const TBOX box,
const ColPartition part,
const DENORM denorm,
bool  debug 
) const

Definition at line 161 of file textlineprojection.cpp.

162  {
163  // Compute a partition box that uses the median top/bottom of the blobs
164  // within and median left/right for vertical.
165  TBOX part_box = part.bounding_box();
166  if (part.IsHorizontalType()) {
167  part_box.set_top(part.median_top());
168  part_box.set_bottom(part.median_bottom());
169  } else {
170  part_box.set_left(part.median_left());
171  part_box.set_right(part.median_right());
172  }
173  // Now use DistanceOfBoxFromBox to make the actual calculation.
174  return DistanceOfBoxFromBox(box, part_box, part.IsHorizontalType(), denorm, debug);
175 }
int DistanceOfBoxFromBox(const TBOX &from_box, const TBOX &to_box, bool horizontal_textline, const DENORM *denorm, bool debug) const

◆ EvaluateBox()

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

Definition at line 414 of file textlineprojection.cpp.

414  {
415  return EvaluateBoxInternal(box, denorm, debug, nullptr, nullptr, nullptr, nullptr);
416 }

◆ EvaluateColPartition()

int tesseract::TextlineProjection::EvaluateColPartition ( const ColPartition part,
const DENORM denorm,
bool  debug 
) const

Definition at line 363 of file textlineprojection.cpp.

364  {
365  if (part.IsSingleton()) {
366  return EvaluateBox(part.bounding_box(), denorm, debug);
367  }
368  // Test vertical orientation.
369  TBOX box = part.bounding_box();
370  // Use the partition median for left/right.
371  box.set_left(part.median_left());
372  box.set_right(part.median_right());
373  int vresult = EvaluateBox(box, denorm, debug);
374 
375  // Test horizontal orientation.
376  box = part.bounding_box();
377  // Use the partition median for top/bottom.
378  box.set_top(part.median_top());
379  box.set_bottom(part.median_bottom());
380  int hresult = EvaluateBox(box, denorm, debug);
381  if (debug) {
382  tprintf("Partition hresult=%d, vresult=%d from:", hresult, vresult);
383  part.bounding_box().print();
384  part.Print();
385  }
386  return hresult >= -vresult ? hresult : vresult;
387 }
void tprintf(const char *format,...)
Definition: tprintf.cpp:41
int EvaluateBox(const TBOX &box, const DENORM *denorm, bool debug) const

◆ HorizontalDistance()

int tesseract::TextlineProjection::HorizontalDistance ( bool  debug,
int  x1,
int  x2,
int  y 
) const

Definition at line 307 of file textlineprojection.cpp.

307  {
308  x1 = ImageXToProjectionX(x1);
309  x2 = ImageXToProjectionX(x2);
310  y = ImageYToProjectionY(y);
311  if (x1 == x2) {
312  return 0;
313  }
314  int wpl = pixGetWpl(pix_);
315  int step = x1 < x2 ? 1 : -1;
316  uint32_t *data = pixGetData(pix_) + y * wpl;
317  int prev_pixel = GET_DATA_BYTE(data, x1);
318  int distance = 0;
319  int right_way_steps = 0;
320  for (int x = x1; x != x2; x += step) {
321  int pixel = GET_DATA_BYTE(data, x + step);
322  if (debug) {
323  tprintf("At (%d,%d), pix = %d, prev=%d\n", x + step, y, pixel, prev_pixel);
324  }
325  if (pixel < prev_pixel) {
327  } else if (pixel > prev_pixel) {
328  ++right_way_steps;
329  } else {
330  ++distance;
331  }
332  prev_pixel = pixel;
333  }
334  return distance * scale_factor_ + right_way_steps * scale_factor_ / kWrongWayPenalty;
335 }
const int kWrongWayPenalty
UnicodeText::const_iterator::difference_type distance(const UnicodeText::const_iterator &first, const UnicodeText::const_iterator &last)
Definition: unicodetext.cc:44

◆ MoveNonTextlineBlobs()

void tesseract::TextlineProjection::MoveNonTextlineBlobs ( BLOBNBOX_LIST *  blobs,
BLOBNBOX_LIST *  small_blobs 
) const

Definition at line 109 of file textlineprojection.cpp.

110  {
111  BLOBNBOX_IT it(blobs);
112  BLOBNBOX_IT small_it(small_blobs);
113  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
114  BLOBNBOX *blob = it.data();
115  const TBOX &box = blob->bounding_box();
116  bool debug = AlignedBlob::WithinTestRegion(2, box.left(), box.bottom());
117  if (BoxOutOfHTextline(box, nullptr, debug) && !blob->UniquelyVertical()) {
118  blob->ClearNeighbours();
119  small_it.add_to_end(it.extract());
120  }
121  }
122 }
static bool WithinTestRegion(int detail_level, int x, int y)
bool BoxOutOfHTextline(const TBOX &box, const DENORM *denorm, bool debug) const

◆ PlotGradedBlobs()

void tesseract::TextlineProjection::PlotGradedBlobs ( BLOBNBOX_LIST *  blobs,
ScrollView win 
)

Definition at line 87 of file textlineprojection.cpp.

87  {
88  BLOBNBOX_IT it(blobs);
89  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
90  BLOBNBOX *blob = it.data();
91  const TBOX &box = blob->bounding_box();
92  bool bad_box = BoxOutOfHTextline(box, nullptr, false);
93  if (blob->UniquelyVertical()) {
94  win->Pen(ScrollView::YELLOW);
95  } else {
96  win->Pen(bad_box ? ScrollView::RED : ScrollView::BLUE);
97  }
98  win->Rectangle(box.left(), box.bottom(), box.right(), box.top());
99  }
100  win->Update();
101 }

◆ VerticalDistance()

int tesseract::TextlineProjection::VerticalDistance ( bool  debug,
int  x,
int  y1,
int  y2 
) const

Definition at line 273 of file textlineprojection.cpp.

273  {
274  x = ImageXToProjectionX(x);
275  y1 = ImageYToProjectionY(y1);
276  y2 = ImageYToProjectionY(y2);
277  if (y1 == y2) {
278  return 0;
279  }
280  int wpl = pixGetWpl(pix_);
281  int step = y1 < y2 ? 1 : -1;
282  uint32_t *data = pixGetData(pix_) + y1 * wpl;
283  wpl *= step;
284  int prev_pixel = GET_DATA_BYTE(data, x);
285  int distance = 0;
286  int right_way_steps = 0;
287  for (int y = y1; y != y2; y += step) {
288  data += wpl;
289  int pixel = GET_DATA_BYTE(data, x);
290  if (debug) {
291  tprintf("At (%d,%d), pix = %d, prev=%d\n", x, y + step, pixel, prev_pixel);
292  }
293  if (pixel < prev_pixel) {
295  } else if (pixel > prev_pixel) {
296  ++right_way_steps;
297  } else {
298  ++distance;
299  }
300  prev_pixel = pixel;
301  }
302  return distance * scale_factor_ + right_way_steps * scale_factor_ / kWrongWayPenalty;
303 }

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