41 mean_sum = cutpt->
sum();
84 FPSEGPT_LIST *prev_list
86 : fake_count(0), xpos(
x), mean_sum(0.0), sq_sum(0.0) {
94 FPSEGPT_IT pred_it = prev_list;
100 best_fake = INT16_MAX;
102 for (pred_it.mark_cycle_pt(); !pred_it.cycled_list(); pred_it.forward()) {
103 segpt = pred_it.data();
107 dist =
x - segpt->xpos;
108 if (dist >= pitch - pitch_error && dist <= pitch + pitch_error && !segpt->
terminal) {
109 total = segpt->mean_sum + dist;
110 sq_dist = dist * dist + segpt->sq_sum + offset * offset;
112 mean = total / region_index;
113 factor = mean - pitch;
115 factor += sq_dist / (region_index)-mean * mean;
139 BLOBNBOX_IT *blob_it,
144 FPSEGPT_LIST *seg_list
154 int16_t region_index;
155 int16_t best_region_index = 0;
158 int16_t right_best_x;
163 FPSEGPT_LIST *segpts;
171 FPSEGPT_IT outseg_it = seg_list;
172 FPSEGPT_LIST_CLIST lattice;
174 FPSEGPT_LIST_C_IT lattice_it = &lattice;
183 if ((pitch - 3) / 2 < pitch_error) {
184 pitch_error = (pitch - 3) / 2;
193 left_edge = min_box.
left() + pitch_error;
194 for (min_index = 1; min_index < blob_count; min_index++) {
201 right_edge = min_box.
right();
204 min_x = max_x - pitch + pitch_error * 2 + 1;
205 right_max = right_edge + pitch - pitch_error - 1;
206 segpts =
new FPSEGPT_LIST;
207 segpt_it.set_to_list(segpts);
208 for (
x = min_x;
x <= max_x;
x++) {
211 segpt_it.add_after_then_move(segpt);
214 lattice_it.add_before_then_move(segpts);
224 segpts =
new FPSEGPT_LIST;
225 segpt_it.set_to_list(segpts);
226 min_x += pitch - pitch_error;
227 max_x += pitch + pitch_error;
228 while (min_box.
right() < min_x && min_index < blob_count) {
233 max_index = min_index;
236 for (
x = min_x;
x <= max_x &&
x <= right_max;
x++) {
237 while (
x < right_edge && max_index < blob_count && x > max_box.
right()) {
242 if (
x <= max_box.
left() + pitch_error ||
x >= max_box.
right() - pitch_error ||
243 x >= right_edge || (max_index < blob_count - 1 && x >= next_box.
left()) ||
247 if (
x - max_box.
left() > 0 &&
x - max_box.
left() <= pitch_error) {
249 offset =
x - max_box.
left();
250 }
else if (max_box.
right() -
x > 0 && max_box.
right() -
x <= pitch_error &&
251 (max_index >= blob_count - 1 ||
x < next_box.
left())) {
252 offset = max_box.
right() -
x;
257 segpt =
new FPSEGPT(
x,
false, offset, region_index, pitch, pitch_error, lattice_it.data());
260 segpt =
new FPSEGPT(
x,
true, offset, region_index, pitch, pitch_error, lattice_it.data());
263 segpt_it.add_after_then_move(segpt);
264 if (
x >= right_edge - pitch_error) {
270 best_region_index = region_index;
273 }
else if (segpt->
cost_function() == best_cost && right_best_x ==
x - 1) {
281 if (segpts->empty()) {
282 if (best_end !=
nullptr) {
288 if (right_best_x > left_best_x + 1) {
289 left_best_x = (left_best_x + right_best_x + 1) / 2;
290 for (segpt_it.mark_cycle_pt();
291 !segpt_it.cycled_list() && segpt_it.data()->position() != left_best_x;
292 segpt_it.forward()) {
295 if (segpt_it.data()->position() == left_best_x) {
297 best_end = segpt_it.data();
302 lattice_it.add_before_then_move(segpts);
304 }
while (min_x < right_edge);
307 for (lattice_it.mark_cycle_pt(); !lattice_it.cycled_list(); lattice_it.forward()) {
308 segpts = lattice_it.data();
309 segpt_it.set_to_list(segpts);
323 for (segpt_it.mark_cycle_pt(); !segpt_it.cycled_list() && segpt_it.data() != best_end;
324 segpt_it.forward()) {
327 if (segpt_it.data() == best_end) {
329 segpt = segpt_it.extract();
330 outseg_it.add_before_then_move(segpt);
336 outseg_it.move_to_last();
337 mean_sum = outseg_it.data()->sum();
338 mean_sum = mean_sum * mean_sum / best_region_index;
339 if (outseg_it.data()->squares() - mean_sum < 0) {
340 tprintf(
"Impossible sqsum=%g, mean=%g, total=%d\n", outseg_it.data()->squares(),
341 outseg_it.data()->sum(), best_region_index);
343 lattice.deep_clear();
344 return outseg_it.data()->squares() - mean_sum;
354 FPSEGPT_LIST *prev_list,
357 int16_t region_index,
360 FPSEGPT_LIST *seg_list
369 FPSEGPT_IT segpt_it = seg_list;
371 FPSEGPT_IT prevpt_it = prev_list;
374 for (prevpt_it.mark_cycle_pt(); !prevpt_it.cycled_list(); prevpt_it.forward()) {
375 prevpt = prevpt_it.data();
385 min_x += pitch - pitch_error;
386 max_x += pitch + pitch_error;
387 for (
x = min_x;
x <= max_x;
x++) {
388 while (
x > blob_box.
right()) {
391 offset =
x - blob_box.
left();
392 if (blob_box.
right() -
x < offset) {
393 offset = blob_box.
right() -
x;
395 segpt =
new FPSEGPT(
x,
false, offset, region_index, pitch, pitch_error, prev_list);
398 fprintf(stderr,
"made fake at %d\n",
x);
400 segpt_it.add_after_then_move(segpt);
#define INT_VAR(name, val, comment)
#define double_VAR(name, val, comment)
void tprintf(const char *format,...)
double pitsync_offset_freecut_fraction
int pitsync_linear_version
double pitsync_joined_edge
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)
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)
int32_t pile_count(int32_t value) const
int16_t cheap_cuts() const