tesseract  5.0.0-alpha-619-ge9db
tesseract::TextlineProjection Class Reference

#include <textlineprojection.h>

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

◆ TextlineProjection()

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

Definition at line 47 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) scale_factor_ = 1;
52 }

◆ ~TextlineProjection()

tesseract::TextlineProjection::~TextlineProjection ( )

Definition at line 53 of file textlineprojection.cpp.

53  {
54  pixDestroy(&pix_);
55 }

Member Function Documentation

◆ BoxOutOfHTextline()

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

Definition at line 341 of file textlineprojection.cpp.

343  {
344  int grad1 = 0;
345  int grad2 = 0;
346  EvaluateBoxInternal(box, denorm, debug, &grad1, &grad2, nullptr, nullptr);
347  int worst_result = std::min(grad1, grad2);
348  int total_result = grad1 + grad2;
349  if (total_result >= 6) return false; // Strongly in textline.
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  return false;
355 }

◆ ConstructProjection()

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

Definition at line 64 of file textlineprojection.cpp.

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

◆ DisplayProjection()

void tesseract::TextlineProjection::DisplayProjection ( ) const

Definition at line 123 of file textlineprojection.cpp.

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

◆ 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 197 of file textlineprojection.cpp.

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

◆ DistanceOfBoxFromPartition()

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

Definition at line 157 of file textlineprojection.cpp.

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

◆ EvaluateBox()

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

Definition at line 413 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 362 of file textlineprojection.cpp.

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

◆ HorizontalDistance()

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

Definition at line 309 of file textlineprojection.cpp.

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

◆ MoveNonTextlineBlobs()

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

Definition at line 106 of file textlineprojection.cpp.

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

◆ PlotGradedBlobs()

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

Definition at line 84 of file textlineprojection.cpp.

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

◆ VerticalDistance()

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

Definition at line 276 of file textlineprojection.cpp.

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

The documentation for this class was generated from the following files:
BLOBNBOX::ClearNeighbours
void ClearNeighbours()
Definition: blobbox.h:498
ScrollView
Definition: scrollview.h:97
TPOINT
Definition: blobs.h:49
tesseract::TextlineProjection::VerticalDistance
int VerticalDistance(bool debug, int x, int y1, int y2) const
Definition: textlineprojection.cpp:276
TBOX::top
int16_t top() const
Definition: rect.h:57
TO_BLOCK::blobs
BLOBNBOX_LIST blobs
Definition: blobbox.h:771
TBOX::set_top
void set_top(int y)
Definition: rect.h:60
ScrollView::Pen
void Pen(Color color)
Definition: scrollview.cpp:717
IntCastRounded
int IntCastRounded(double x)
Definition: helpers.h:173
kParaPerpDistRatio
const int kParaPerpDistRatio
Definition: textlineprojection.cpp:38
tesseract::TextlineProjection::EvaluateBox
int EvaluateBox(const TBOX &box, const DENORM *denorm, bool debug) const
Definition: textlineprojection.cpp:413
BLOBNBOX
Definition: blobbox.h:142
kWrongWayPenalty
const int kWrongWayPenalty
Definition: textlineprojection.cpp:33
ScrollView::BLUE
Definition: scrollview.h:108
TBOX::height
int16_t height() const
Definition: rect.h:107
TBOX::y_gap
int y_gap(const TBOX &box) const
Definition: rect.h:232
TBOX::set_right
void set_right(int x)
Definition: rect.h:81
TO_BLOCK::large_blobs
BLOBNBOX_LIST large_blobs
Definition: blobbox.h:775
TPOINT::x
int16_t x
Definition: blobs.h:91
DENORM::DenormTransform
void DenormTransform(const DENORM *last_denorm, const TPOINT &pt, TPOINT *original) const
Definition: normalis.cpp:389
tesseract::AlignedBlob::WithinTestRegion
static bool WithinTestRegion(int detail_level, int x, int y)
Definition: alignedblob.cpp:150
tesseract::TextlineProjection::DistanceOfBoxFromBox
int DistanceOfBoxFromBox(const TBOX &from_box, const TBOX &to_box, bool horizontal_textline, const DENORM *denorm, bool debug) const
Definition: textlineprojection.cpp:197
TPOINT::y
int16_t y
Definition: blobs.h:92
TBOX::width
int16_t width() const
Definition: rect.h:114
ScrollView::YELLOW
Definition: scrollview.h:105
TBOX::bottom
int16_t bottom() const
Definition: rect.h:64
distance
UnicodeText::const_iterator::difference_type distance(const UnicodeText::const_iterator &first, const UnicodeText::const_iterator &last)
Definition: unicodetext.cc:44
ScrollView::RED
Definition: scrollview.h:104
BLOBNBOX::bounding_box
const TBOX & bounding_box() const
Definition: blobbox.h:229
BLOBNBOX::UniquelyVertical
bool UniquelyVertical() const
Definition: blobbox.h:409
tesseract::TextlineProjection::HorizontalDistance
int HorizontalDistance(bool debug, int x1, int x2, int y) const
Definition: textlineprojection.cpp:309
TBOX::left
int16_t left() const
Definition: rect.h:71
TBOX::right
int16_t right() const
Definition: rect.h:78
tprintf
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:34
ScrollView::Update
static void Update()
Definition: scrollview.cpp:708
TBOX::set_bottom
void set_bottom(int y)
Definition: rect.h:67
ScrollView::Rectangle
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:599
TBOX::set_left
void set_left(int x)
Definition: rect.h:74
TBOX::x_gap
int x_gap(const TBOX &box) const
Definition: rect.h:224
TBOX
Definition: rect.h:33
tesseract::TextlineProjection::BoxOutOfHTextline
bool BoxOutOfHTextline(const TBOX &box, const DENORM *denorm, bool debug) const
Definition: textlineprojection.cpp:341