tesseract  4.00.00dev
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 45 of file textlineprojection.cpp.

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

◆ ~TextlineProjection()

tesseract::TextlineProjection::~TextlineProjection ( )

Definition at line 51 of file textlineprojection.cpp.

51  {
52  pixDestroy(&pix_);
53 }

Member Function Documentation

◆ BoxOutOfHTextline()

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

Definition at line 339 of file textlineprojection.cpp.

341  {
342  int grad1 = 0;
343  int grad2 = 0;
344  EvaluateBoxInternal(box, denorm, debug, &grad1, &grad2, NULL, NULL);
345  int worst_result = MIN(grad1, grad2);
346  int total_result = grad1 + grad2;
347  if (total_result >= 6) return false; // Strongly in textline.
348  // Medium strength: if either gradient is negative, it is likely outside
349  // the body of the textline.
350  if (worst_result < 0)
351  return true;
352  return false;
353 }
#define MIN(x, y)
Definition: ndminx.h:28

◆ ConstructProjection()

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

Definition at line 62 of file textlineprojection.cpp.

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

◆ DisplayProjection()

void tesseract::TextlineProjection::DisplayProjection ( ) const

Definition at line 121 of file textlineprojection.cpp.

121  {
122 #ifndef GRAPHICS_DISABLED
123  int width = pixGetWidth(pix_);
124  int height = pixGetHeight(pix_);
125  Pix* pixc = pixCreate(width, height, 32);
126  int src_wpl = pixGetWpl(pix_);
127  int col_wpl = pixGetWpl(pixc);
128  uinT32* src_data = pixGetData(pix_);
129  uinT32* col_data = pixGetData(pixc);
130  for (int y = 0; y < height; ++y, src_data += src_wpl, col_data += col_wpl) {
131  for (int x = 0; x < width; ++x) {
132  int pixel = GET_DATA_BYTE(src_data, x);
133  l_uint32 result;
134  if (pixel <= 17)
135  composeRGBPixel(0, 0, pixel * 15, &result);
136  else if (pixel <= 145)
137  composeRGBPixel(0, (pixel - 17) * 2, 255, &result);
138  else
139  composeRGBPixel((pixel - 145) * 2, 255, 255, &result);
140  col_data[x] = result;
141  }
142  }
143  ScrollView* win = new ScrollView("Projection", 0, 0,
144  width, height, width, height);
145  win->Image(pixc, 0, 0);
146  win->Update();
147  pixDestroy(&pixc);
148 #endif // GRAPHICS_DISABLED
149 }
uint32_t uinT32
Definition: host.h:39
static void Update()
Definition: scrollview.cpp:715
void Image(struct Pix *image, int x_pos, int y_pos)
Definition: scrollview.cpp:773

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

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

◆ DistanceOfBoxFromPartition()

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

Definition at line 155 of file textlineprojection.cpp.

158  {
159  // Compute a partition box that uses the median top/bottom of the blobs
160  // within and median left/right for vertical.
161  TBOX part_box = part.bounding_box();
162  if (part.IsHorizontalType()) {
163  part_box.set_top(part.median_top());
164  part_box.set_bottom(part.median_bottom());
165  } else {
166  part_box.set_left(part.median_left());
167  part_box.set_right(part.median_right());
168  }
169  // Now use DistanceOfBoxFromBox to make the actual calculation.
170  return DistanceOfBoxFromBox(box, part_box, part.IsHorizontalType(),
171  denorm, debug);
172 }
int DistanceOfBoxFromBox(const TBOX &from_box, const TBOX &to_box, bool horizontal_textline, const DENORM *denorm, bool debug) const
void set_top(int y)
Definition: rect.h:57
Definition: rect.h:30
void set_right(int x)
Definition: rect.h:78
void set_left(int x)
Definition: rect.h:71
void set_bottom(int y)
Definition: rect.h:64

◆ EvaluateBox()

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

Definition at line 411 of file textlineprojection.cpp.

412  {
413  return EvaluateBoxInternal(box, denorm, debug, NULL, NULL, NULL, NULL);
414 }

◆ EvaluateColPartition()

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

Definition at line 360 of file textlineprojection.cpp.

362  {
363  if (part.IsSingleton())
364  return EvaluateBox(part.bounding_box(), denorm, debug);
365  // Test vertical orientation.
366  TBOX box = part.bounding_box();
367  // Use the partition median for left/right.
368  box.set_left(part.median_left());
369  box.set_right(part.median_right());
370  int vresult = EvaluateBox(box, denorm, debug);
371 
372  // Test horizontal orientation.
373  box = part.bounding_box();
374  // Use the partition median for top/bottom.
375  box.set_top(part.median_top());
376  box.set_bottom(part.median_bottom());
377  int hresult = EvaluateBox(box, denorm, debug);
378  if (debug) {
379  tprintf("Partition hresult=%d, vresult=%d from:", hresult, vresult);
380  part.bounding_box().print();
381  part.Print();
382  }
383  return hresult >= -vresult ? hresult : vresult;
384 }
int EvaluateBox(const TBOX &box, const DENORM *denorm, bool debug) const
#define tprintf(...)
Definition: tprintf.h:31
void set_top(int y)
Definition: rect.h:57
Definition: rect.h:30
void set_right(int x)
Definition: rect.h:78
void set_left(int x)
Definition: rect.h:71
void set_bottom(int y)
Definition: rect.h:64

◆ HorizontalDistance()

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

Definition at line 307 of file textlineprojection.cpp.

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

◆ MoveNonTextlineBlobs()

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

Definition at line 104 of file textlineprojection.cpp.

105  {
106  BLOBNBOX_IT it(blobs);
107  BLOBNBOX_IT small_it(small_blobs);
108  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
109  BLOBNBOX* blob = it.data();
110  const TBOX& box = blob->bounding_box();
111  bool debug = AlignedBlob::WithinTestRegion(2, box.left(),
112  box.bottom());
113  if (BoxOutOfHTextline(box, NULL, debug) && !blob->UniquelyVertical()) {
114  blob->ClearNeighbours();
115  small_it.add_to_end(it.extract());
116  }
117  }
118 }
bool UniquelyVertical() const
Definition: blobbox.h:395
inT16 left() const
Definition: rect.h:68
void ClearNeighbours()
Definition: blobbox.h:494
static bool WithinTestRegion(int detail_level, int x, int y)
Definition: rect.h:30
inT16 bottom() const
Definition: rect.h:61
bool BoxOutOfHTextline(const TBOX &box, const DENORM *denorm, bool debug) const
const TBOX & bounding_box() const
Definition: blobbox.h:215

◆ PlotGradedBlobs()

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

Definition at line 82 of file textlineprojection.cpp.

83  {
84 #ifndef GRAPHICS_DISABLED
85  BLOBNBOX_IT it(blobs);
86  for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
87  BLOBNBOX* blob = it.data();
88  const TBOX& box = blob->bounding_box();
89  bool bad_box = BoxOutOfHTextline(box, NULL, false);
90  if (blob->UniquelyVertical())
91  win->Pen(ScrollView::YELLOW);
92  else
93  win->Pen(bad_box ? ScrollView::RED : ScrollView::BLUE);
94  win->Rectangle(box.left(), box.bottom(), box.right(), box.top());
95  }
96  win->Update();
97 #endif // GRAPHICS_DISABLED
98 }
bool UniquelyVertical() const
Definition: blobbox.h:395
inT16 left() const
Definition: rect.h:68
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:606
static void Update()
Definition: scrollview.cpp:715
inT16 top() const
Definition: rect.h:54
Definition: rect.h:30
inT16 right() const
Definition: rect.h:75
inT16 bottom() const
Definition: rect.h:61
bool BoxOutOfHTextline(const TBOX &box, const DENORM *denorm, bool debug) const
const TBOX & bounding_box() const
Definition: blobbox.h:215
void Pen(Color color)
Definition: scrollview.cpp:726

◆ VerticalDistance()

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

Definition at line 274 of file textlineprojection.cpp.

275  {
276  x = ImageXToProjectionX(x);
277  y1 = ImageYToProjectionY(y1);
278  y2 = ImageYToProjectionY(y2);
279  if (y1 == y2) return 0;
280  int wpl = pixGetWpl(pix_);
281  int step = y1 < y2 ? 1 : -1;
282  uinT32* 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",
292  x, y + step, pixel, prev_pixel);
293  if (pixel < prev_pixel)
294  distance += kWrongWayPenalty;
295  else if (pixel > prev_pixel)
296  ++right_way_steps;
297  else
298  ++distance;
299  prev_pixel = pixel;
300  }
301  return distance * scale_factor_ +
302  right_way_steps * scale_factor_ / kWrongWayPenalty;
303 }
#define tprintf(...)
Definition: tprintf.h:31
const int kWrongWayPenalty
uint32_t uinT32
Definition: host.h:39

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