150 {
151 int16_t x;
152 int16_t min_index;
153 int16_t max_index;
154 int16_t left_edge;
155 int16_t right_edge;
156 int16_t right_max;
157 int16_t min_x;
158 int16_t max_x;
159 int16_t region_index;
160 int16_t best_region_index = 0;
161 int16_t offset;
162 int16_t left_best_x;
163 int16_t right_best_x;
168 FPSEGPT_LIST *segpts;
169 double best_cost;
170 double mean_sum;
172 BLOBNBOX_IT min_it;
173 BLOBNBOX_IT max_it;
174 FPSEGPT_IT segpt_it;
175
176 FPSEGPT_IT outseg_it = seg_list;
177 FPSEGPT_LIST_CLIST lattice;
178
179 FPSEGPT_LIST_C_IT lattice_it = &lattice;
180
181
182
183
184
185 if (pitch < 3)
186 pitch = 3;
187 if ((pitch - 3) / 2 < pitch_error)
188 pitch_error = (pitch - 3) / 2;
189 min_it = *blob_it;
191
192
193
194
195
196 left_edge = min_box.
left () + pitch_error;
197 for (min_index = 1; min_index < blob_count; min_index++) {
199
200
201
202
203 }
204 right_edge = min_box.
right ();
205 max_x = left_edge;
206
207 min_x = max_x - pitch + pitch_error * 2 + 1;
208 right_max = right_edge + pitch - pitch_error - 1;
209 segpts = new FPSEGPT_LIST;
210 segpt_it.set_to_list (segpts);
211 for (x = min_x; x <= max_x; x++) {
213
214 segpt_it.add_after_then_move (segpt);
215 }
216
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;
224 do {
225 left_best_x = -1;
226 right_best_x = -1;
227 segpts = new FPSEGPT_LIST;
228 segpt_it.set_to_list (segpts);
229 min_x += pitch - pitch_error;
230 max_x += pitch + pitch_error;
231 while (min_box.
right () < min_x && min_index < blob_count) {
232 min_index++;
234 }
235 max_it = min_it;
236 max_index = min_index;
237 max_box = min_box;
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;
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 ())
251
252 if (x - max_box.
left () > 0
253 && x - max_box.
left () <= pitch_error)
254
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
264 segpt =
new FPSEGPT (x,
false, offset, region_index,
265 pitch, pitch_error, lattice_it.data ());
266 }
267 else {
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) {
278
279 best_end = segpt;
280 best_region_index = region_index;
281 left_best_x = x;
282 right_best_x = x;
283 }
285 && right_best_x == x - 1)
286 right_best_x = x;
287 }
288 }
289 else {
290 delete segpt;
291 }
292 }
293 if (segpts->empty ()) {
294 if (best_end != nullptr)
295 break;
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
307 best_end = segpt_it.data ();
308 }
309 }
310
311 lattice_it.add_before_then_move (segpts);
312 region_index++;
313 }
314 while (min_x < right_edge);
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
322
323
324
325
326
327
328
329
330
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
336 segpt = segpt_it.extract ();
337 outseg_it.add_before_then_move (segpt);
339 }
340 }
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",
348 outseg_it.data ()->squares (), outseg_it.data ()->sum (),
349 best_region_index);
350 lattice.deep_clear ();
351 return outseg_it.data ()->squares () - mean_sum;
352}
TBOX box_next(BLOBNBOX_IT *it)
DLLSYM void tprintf(const char *format,...)
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)
int32_t pile_count(int32_t value) const