tesseract  5.0.0-alpha-619-ge9db
pitsync1.cpp File Reference
#include <cfloat>
#include <cmath>
#include "pitsync1.h"

Go to the source code of this file.

Functions

 ELISTIZE (FPSEGPT) CLISTIZE(FPSEGPT_LIST) int pitsync_linear_version
 
double check_pitch_sync (BLOBNBOX_IT *blob_it, int16_t blob_count, int16_t pitch, int16_t pitch_error, STATS *projection, FPSEGPT_LIST *seg_list)
 
void make_illegal_segment (FPSEGPT_LIST *prev_list, TBOX blob_box, BLOBNBOX_IT blob_it, int16_t region_index, int16_t pitch, int16_t pitch_error, FPSEGPT_LIST *seg_list)
 

Variables

double pitsync_joined_edge = 0.75
 
double pitsync_offset_freecut_fraction = 0.25
 
int pitsync_fake_depth = 1
 

Function Documentation

◆ check_pitch_sync()

double check_pitch_sync ( BLOBNBOX_IT *  blob_it,
int16_t  blob_count,
int16_t  pitch,
int16_t  pitch_error,
STATS projection,
FPSEGPT_LIST *  seg_list 
)

Definition at line 138 of file pitsync1.cpp.

150  {
151  int16_t x; //current coord
152  int16_t min_index; //blob number
153  int16_t max_index; //blob number
154  int16_t left_edge; //of word
155  int16_t right_edge; //of word
156  int16_t right_max; //max allowed x
157  int16_t min_x; //in this region
158  int16_t max_x;
159  int16_t region_index;
160  int16_t best_region_index = 0; //for best result
161  int16_t offset; //dist to legal area
162  int16_t left_best_x; //edge of good region
163  int16_t right_best_x; //right edge
164  TBOX min_box; //bounding box
165  TBOX max_box; //bounding box
166  TBOX next_box; //box of next blob
167  FPSEGPT *segpt; //segment point
168  FPSEGPT_LIST *segpts; //points in a segment
169  double best_cost; //best path
170  double mean_sum; //computes result
171  FPSEGPT *best_end; //end of best path
172  BLOBNBOX_IT min_it; //copy iterator
173  BLOBNBOX_IT max_it; //copy iterator
174  FPSEGPT_IT segpt_it; //iterator
175  //output segments
176  FPSEGPT_IT outseg_it = seg_list;
177  FPSEGPT_LIST_CLIST lattice; //list of lists
178  //region iterator
179  FPSEGPT_LIST_C_IT lattice_it = &lattice;
180 
181  // tprintf("Computing sync on word of %d blobs with pitch %d\n",
182  // blob_count, pitch);
183  // if (blob_count==8 && pitch==27)
184  // projection->print(stdout,true);
185  if (pitch < 3)
186  pitch = 3; //nothing ludicrous
187  if ((pitch - 3) / 2 < pitch_error)
188  pitch_error = (pitch - 3) / 2;
189  min_it = *blob_it;
190  min_box = box_next (&min_it); //get box
191  // if (blob_count==8 && pitch==27)
192  // tprintf("1st box at (%d,%d)->(%d,%d)\n",
193  // min_box.left(),min_box.bottom(),
194  // min_box.right(),min_box.top());
195  //left of word
196  left_edge = min_box.left () + pitch_error;
197  for (min_index = 1; min_index < blob_count; min_index++) {
198  min_box = box_next (&min_it);
199  // if (blob_count==8 && pitch==27)
200  // tprintf("Box at (%d,%d)->(%d,%d)\n",
201  // min_box.left(),min_box.bottom(),
202  // min_box.right(),min_box.top());
203  }
204  right_edge = min_box.right (); //end of word
205  max_x = left_edge;
206  //min permissible
207  min_x = max_x - pitch + pitch_error * 2 + 1;
208  right_max = right_edge + pitch - pitch_error - 1;
209  segpts = new FPSEGPT_LIST; //list of points
210  segpt_it.set_to_list (segpts);
211  for (x = min_x; x <= max_x; x++) {
212  segpt = new FPSEGPT (x); //make a new one
213  //put in list
214  segpt_it.add_after_then_move (segpt);
215  }
216  //first segment
217  lattice_it.add_before_then_move (segpts);
218  min_index = 0;
219  region_index = 1;
220  best_cost = FLT_MAX;
221  best_end = nullptr;
222  min_it = *blob_it;
223  min_box = box_next (&min_it); //first box
224  do {
225  left_best_x = -1;
226  right_best_x = -1;
227  segpts = new FPSEGPT_LIST; //list of points
228  segpt_it.set_to_list (segpts);
229  min_x += pitch - pitch_error;//next limits
230  max_x += pitch + pitch_error;
231  while (min_box.right () < min_x && min_index < blob_count) {
232  min_index++;
233  min_box = box_next (&min_it);
234  }
235  max_it = min_it;
236  max_index = min_index;
237  max_box = min_box;
238  next_box = box_next (&max_it);
239  for (x = min_x; x <= max_x && x <= right_max; x++) {
240  while (x < right_edge && max_index < blob_count
241  && x > max_box.right ()) {
242  max_index++;
243  max_box = next_box;
244  next_box = box_next (&max_it);
245  }
246  if (x <= max_box.left () + pitch_error
247  || x >= max_box.right () - pitch_error || x >= right_edge
248  || (max_index < blob_count - 1 && x >= next_box.left ())
249  || (x - max_box.left () > pitch * pitsync_joined_edge
250  && max_box.right () - x > pitch * pitsync_joined_edge)) {
251  // || projection->local_min(x))
252  if (x - max_box.left () > 0
253  && x - max_box.left () <= pitch_error)
254  //dist to real break
255  offset = x - max_box.left ();
256  else if (max_box.right () - x > 0
257  && max_box.right () - x <= pitch_error
258  && (max_index >= blob_count - 1
259  || x < next_box.left ()))
260  offset = max_box.right () - x;
261  else
262  offset = 0;
263  // offset=pitsync_offset_freecut_fraction*projection->pile_count(x);
264  segpt = new FPSEGPT (x, false, offset, region_index,
265  pitch, pitch_error, lattice_it.data ());
266  }
267  else {
268  offset = projection->pile_count (x);
269  segpt = new FPSEGPT (x, true, offset, region_index,
270  pitch, pitch_error, lattice_it.data ());
271  }
272  if (segpt->previous () != nullptr) {
273  segpt_it.add_after_then_move (segpt);
274  if (x >= right_edge - pitch_error) {
275  segpt->terminal = true;//no more wanted
276  if (segpt->cost_function () < best_cost) {
277  best_cost = segpt->cost_function ();
278  //find least
279  best_end = segpt;
280  best_region_index = region_index;
281  left_best_x = x;
282  right_best_x = x;
283  }
284  else if (segpt->cost_function () == best_cost
285  && right_best_x == x - 1)
286  right_best_x = x;
287  }
288  }
289  else {
290  delete segpt; //no good
291  }
292  }
293  if (segpts->empty ()) {
294  if (best_end != nullptr)
295  break; //already found one
296  make_illegal_segment (lattice_it.data (), min_box, min_it,
297  region_index, pitch, pitch_error, segpts);
298  }
299  else {
300  if (right_best_x > left_best_x + 1) {
301  left_best_x = (left_best_x + right_best_x + 1) / 2;
302  for (segpt_it.mark_cycle_pt (); !segpt_it.cycled_list ()
303  && segpt_it.data ()->position () != left_best_x;
304  segpt_it.forward ());
305  if (segpt_it.data ()->position () == left_best_x)
306  //middle of region
307  best_end = segpt_it.data ();
308  }
309  }
310  //new segment
311  lattice_it.add_before_then_move (segpts);
312  region_index++;
313  }
314  while (min_x < right_edge);
315  ASSERT_HOST (best_end != nullptr);//must always find some
316 
317  for (lattice_it.mark_cycle_pt (); !lattice_it.cycled_list ();
318  lattice_it.forward ()) {
319  segpts = lattice_it.data ();
320  segpt_it.set_to_list (segpts);
321  // if (blob_count==8 && pitch==27)
322  // {
323  // for (segpt_it.mark_cycle_pt();!segpt_it.cycled_list();segpt_it.forward())
324  // {
325  // segpt=segpt_it.data();
326  // tprintf("At %d, (%x) cost=%g, m=%g, sq=%g, pred=%x\n",
327  // segpt->position(),segpt,segpt->cost_function(),
328  // segpt->sum(),segpt->squares(),segpt->previous());
329  // }
330  // tprintf("\n");
331  // }
332  for (segpt_it.mark_cycle_pt (); !segpt_it.cycled_list ()
333  && segpt_it.data () != best_end; segpt_it.forward ());
334  if (segpt_it.data () == best_end) {
335  //save good one
336  segpt = segpt_it.extract ();
337  outseg_it.add_before_then_move (segpt);
338  best_end = segpt->previous ();
339  }
340  }
341  ASSERT_HOST (best_end == nullptr);
342  ASSERT_HOST (!outseg_it.empty ());
343  outseg_it.move_to_last ();
344  mean_sum = outseg_it.data ()->sum ();
345  mean_sum = mean_sum * mean_sum / best_region_index;
346  if (outseg_it.data ()->squares () - mean_sum < 0)
347  tprintf ("Impossible sqsum=%g, mean=%g, total=%d\n",

◆ ELISTIZE()

ELISTIZE ( FPSEGPT  )

"Use new fast algorithm"

◆ make_illegal_segment()

void make_illegal_segment ( FPSEGPT_LIST *  prev_list,
TBOX  blob_box,
BLOBNBOX_IT  blob_it,
int16_t  region_index,
int16_t  pitch,
int16_t  pitch_error,
FPSEGPT_LIST *  seg_list 
)

Definition at line 355 of file pitsync1.cpp.

369  {
370  int16_t x; //current coord
371  int16_t min_x = 0; //in this region
372  int16_t max_x = 0;
373  int16_t offset; //dist to edge
374  FPSEGPT *segpt; //segment point
375  FPSEGPT *prevpt; //previous point
376  float best_cost; //best path
377  FPSEGPT_IT segpt_it = seg_list;//iterator
378  //previous points
379  FPSEGPT_IT prevpt_it = prev_list;
380 
381  best_cost = FLT_MAX;
382  for (prevpt_it.mark_cycle_pt (); !prevpt_it.cycled_list ();
383  prevpt_it.forward ()) {
384  prevpt = prevpt_it.data ();
385  if (prevpt->cost_function () < best_cost) {
386  //find least
387  best_cost = prevpt->cost_function ();
388  min_x = prevpt->position ();
389  max_x = min_x; //limits on coords
390  }
391  else if (prevpt->cost_function () == best_cost) {
392  max_x = prevpt->position ();
393  }
394  }
395  min_x += pitch - pitch_error;
396  max_x += pitch + pitch_error;
397  for (x = min_x; x <= max_x; x++) {
398  while (x > blob_box.right ()) {
399  blob_box = box_next (&blob_it);
400  }
401  offset = x - blob_box.left ();
402  if (blob_box.right () - x < offset)
403  offset = blob_box.right () - x;
404  segpt = new FPSEGPT (x, false, offset,
405  region_index, pitch, pitch_error, prev_list);
406  if (segpt->previous () != nullptr) {
407  ASSERT_HOST (offset >= 0);
408  fprintf (stderr, "made fake at %d\n", x);
409  //make one up
410  segpt_it.add_after_then_move (segpt);
411  segpt->faked = true;

Variable Documentation

◆ pitsync_fake_depth

int pitsync_fake_depth = 1

"Max advance fake generation"

Definition at line 28 of file pitsync1.cpp.

◆ pitsync_joined_edge

double pitsync_joined_edge = 0.75

"Dist inside big blob for chopping"

Definition at line 25 of file pitsync1.cpp.

◆ pitsync_offset_freecut_fraction

double pitsync_offset_freecut_fraction = 0.25

"Fraction of cut for free cuts"

Definition at line 27 of file pitsync1.cpp.

pitsync_joined_edge
double pitsync_joined_edge
Definition: pitsync1.cpp:25
FPSEGPT::faked
bool faked
Definition: pitsync1.h:66
FPSEGPT::terminal
bool terminal
Definition: pitsync1.h:67
ASSERT_HOST
#define ASSERT_HOST(x)
Definition: errcode.h:87
STATS::pile_count
int32_t pile_count(int32_t value) const
Definition: statistc.h:75
FPSEGPT::position
int32_t position()
Definition: pitsync1.h:47
FPSEGPT::cost_function
double cost_function()
Definition: pitsync1.h:50
FPSEGPT::previous
FPSEGPT * previous()
Definition: pitsync1.h:59
make_illegal_segment
void make_illegal_segment(FPSEGPT_LIST *prev_list, TBOX blob_box, BLOBNBOX_IT blob_it, int16_t region_index, int16_t pitch, int16_t pitch_error, FPSEGPT_LIST *seg_list)
Definition: pitsync1.cpp:355
box_next
TBOX box_next(BLOBNBOX_IT *it)
Definition: blobbox.cpp:629
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
FPSEGPT
Definition: pitsync1.h:31
TBOX
Definition: rect.h:33