26 INT_VAR(pitsync_linear_version, 6,
"Use new fast algorithm");
29 "Fraction of cut for free cuts");
43 mean_sum = cutpt->
sum ();
87 FPSEGPT_LIST * prev_list
101 FPSEGPT_IT pred_it = prev_list;
107 best_fake = INT16_MAX;
109 for (pred_it.mark_cycle_pt (); !pred_it.cycled_list (); pred_it.forward ()) {
110 segpt = pred_it.data ();
113 dist = x - segpt->xpos;
114 if (dist >= pitch - pitch_error && dist <= pitch + pitch_error
116 total = segpt->mean_sum + dist;
117 sq_dist = dist * dist + segpt->sq_sum + offset * offset;
119 mean = total / region_index;
120 factor = mean - pitch;
122 factor += sq_dist / (region_index) - mean * mean;
145 BLOBNBOX_IT *blob_it,
150 FPSEGPT_LIST *seg_list
160 int16_t region_index;
161 int16_t best_region_index = 0;
164 int16_t right_best_x;
169 FPSEGPT_LIST *segpts;
177 FPSEGPT_IT outseg_it = seg_list;
178 FPSEGPT_LIST_CLIST lattice;
180 FPSEGPT_LIST_C_IT lattice_it = &lattice;
188 if ((pitch - 3) / 2 < pitch_error)
189 pitch_error = (pitch - 3) / 2;
197 left_edge = min_box.
left () + pitch_error;
198 for (min_index = 1; min_index < blob_count; min_index++) {
205 right_edge = min_box.
right ();
208 min_x = max_x - pitch + pitch_error * 2 + 1;
209 right_max = right_edge + pitch - pitch_error - 1;
210 segpts =
new FPSEGPT_LIST;
211 segpt_it.set_to_list (segpts);
212 for (x = min_x; x <= max_x; x++) {
215 segpt_it.add_after_then_move (segpt);
218 lattice_it.add_before_then_move (segpts);
228 segpts =
new FPSEGPT_LIST;
229 segpt_it.set_to_list (segpts);
230 min_x += pitch - pitch_error;
231 max_x += pitch + pitch_error;
232 while (min_box.
right () < min_x && min_index < blob_count) {
237 max_index = min_index;
240 for (x = min_x; x <= max_x && x <= right_max; x++) {
241 while (x < right_edge && max_index < blob_count
242 && x > max_box.
right ()) {
247 if (x <= max_box.
left () + pitch_error
248 || x >= max_box.
right () - pitch_error || x >= right_edge
249 || (max_index < blob_count - 1 && x >= next_box.
left ())
253 if (x - max_box.
left () > 0
254 && x - max_box.
left () <= pitch_error)
256 offset = x - max_box.
left ();
257 else if (max_box.
right () - x > 0
258 && max_box.
right () - x <= pitch_error
259 && (max_index >= blob_count - 1
260 || x < next_box.
left ()))
261 offset = max_box.
right () - x;
266 pitch, pitch_error, lattice_it.data ());
270 segpt =
new FPSEGPT (x,
TRUE, offset, region_index,
271 pitch, pitch_error, lattice_it.data ());
273 if (segpt->
previous () !=
nullptr) {
274 segpt_it.add_after_then_move (segpt);
275 if (x >= right_edge - pitch_error) {
281 best_region_index = region_index;
286 && right_best_x == x - 1)
294 if (segpts->empty ()) {
295 if (best_end !=
nullptr)
298 region_index, pitch, pitch_error, segpts);
301 if (right_best_x > left_best_x + 1) {
302 left_best_x = (left_best_x + right_best_x + 1) / 2;
303 for (segpt_it.mark_cycle_pt (); !segpt_it.cycled_list ()
304 && segpt_it.data ()->position () != left_best_x;
305 segpt_it.forward ());
306 if (segpt_it.data ()->position () == left_best_x)
308 best_end = segpt_it.data ();
312 lattice_it.add_before_then_move (segpts);
315 while (min_x < right_edge);
318 for (lattice_it.mark_cycle_pt (); !lattice_it.cycled_list ();
319 lattice_it.forward ()) {
320 segpts = lattice_it.data ();
321 segpt_it.set_to_list (segpts);
333 for (segpt_it.mark_cycle_pt (); !segpt_it.cycled_list ()
334 && segpt_it.data () != best_end; segpt_it.forward ());
335 if (segpt_it.data () == best_end) {
337 segpt = segpt_it.extract ();
338 outseg_it.add_before_then_move (segpt);
344 outseg_it.move_to_last ();
345 mean_sum = outseg_it.data ()->sum ();
346 mean_sum = mean_sum * mean_sum / best_region_index;
347 if (outseg_it.data ()->squares () - mean_sum < 0)
348 tprintf (
"Impossible sqsum=%g, mean=%g, total=%d\n",
349 outseg_it.data ()->squares (), outseg_it.data ()->sum (),
351 lattice.deep_clear ();
352 return outseg_it.data ()->squares () - mean_sum;
363 FPSEGPT_LIST *prev_list,
366 int16_t region_index,
369 FPSEGPT_LIST *seg_list
378 FPSEGPT_IT segpt_it = seg_list;
380 FPSEGPT_IT prevpt_it = prev_list;
383 for (prevpt_it.mark_cycle_pt (); !prevpt_it.cycled_list ();
384 prevpt_it.forward ()) {
385 prevpt = prevpt_it.data ();
396 min_x += pitch - pitch_error;
397 max_x += pitch + pitch_error;
398 for (x = min_x; x <= max_x; x++) {
399 while (x > blob_box.
right ()) {
402 offset = x - blob_box.
left ();
403 if (blob_box.
right () - x < offset)
404 offset = blob_box.
right () - x;
406 region_index, pitch, pitch_error, prev_list);
407 if (segpt->
previous () !=
nullptr) {
409 fprintf (stderr,
"made fake at %d\n", x);
411 segpt_it.add_after_then_move (segpt);
int32_t pile_count(int32_t value) const
int16_t cheap_cuts() const
double pitsync_offset_freecut_fraction
#define double_VAR(name, val, comment)
double pitsync_joined_edge
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)
TBOX box_next(BLOBNBOX_IT *it)
ELISTIZE(FPSEGPT) CLISTIZE(FPSEGPT_LIST) int pitsync_linear_version
DLLSYM void tprintf(const char *format,...)
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)
CLISTIZE(BLOCK_RES) ELISTIZE(ROW_RES) ELISTIZE(WERD_RES) static const double kStopperAmbiguityThresholdGain
#define INT_VAR(name, val, comment)