tesseract 4.1.1
Loading...
Searching...
No Matches
pitsync1.h File Reference
#include "elst.h"
#include "clst.h"
#include "blobbox.h"
#include "params.h"
#include "statistc.h"
#include "pithsync.h"

Go to the source code of this file.

Classes

class  FPSEGPT
 

Functions

 ELISTIZEH (FPSEGPT) CLISTIZEH(FPSEGPT_LIST) extern int pitsync_linear_version=0
 
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)
 
int16_t vertical_torow_projection (TO_ROW *row, STATS *projection)
 
void vertical_cblob_projection (C_BLOB *blob, STATS *stats)
 
void vertical_coutline_projection (C_OUTLINE *outline, STATS *stats)
 

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 143 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",
348 outseg_it.data ()->squares (), outseg_it.data ()->sum (),
349 best_region_index);
350 lattice.deep_clear (); //shift the lot
351 return outseg_it.data ()->squares () - mean_sum;
352}
TBOX box_next(BLOBNBOX_IT *it)
Definition: blobbox.cpp:636
#define ASSERT_HOST(x)
Definition: errcode.h:88
DLLSYM void tprintf(const char *format,...)
Definition: tprintf.cpp:35
double pitsync_joined_edge
Definition: pitsync1.cpp:26
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:361
Definition: rect.h:34
int16_t left() const
Definition: rect.h:72
int16_t right() const
Definition: rect.h:79
int32_t pile_count(int32_t value) const
Definition: statistc.h:76
FPSEGPT * previous()
Definition: pitsync1.h:60
bool terminal
Definition: pitsync1.h:68
double cost_function()
Definition: pitsync1.h:51

◆ ELISTIZEH()

ELISTIZEH ( FPSEGPT  )
pure virtual

"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 361 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;
412 segpt->fake_count++;
413 }
414 else
415 delete segpt;
416 }
417}
int32_t position()
Definition: pitsync1.h:48
int16_t fake_count
Definition: pitsync1.h:69
bool faked
Definition: pitsync1.h:67

◆ vertical_cblob_projection()

void vertical_cblob_projection ( C_BLOB blob,
STATS stats 
)

Definition at line 868 of file blobbox.cpp.

871 {
872 //outlines of blob
873 C_OUTLINE_IT out_it = blob->out_list ();
874
875 for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
876 vertical_coutline_projection (out_it.data (), stats);
877 }
878}
void vertical_coutline_projection(C_OUTLINE *outline, STATS *stats)
Definition: blobbox.cpp:888
C_OUTLINE_LIST * out_list()
Definition: stepblob.h:70

◆ vertical_coutline_projection()

void vertical_coutline_projection ( C_OUTLINE outline,
STATS stats 
)

Definition at line 888 of file blobbox.cpp.

891 {
892 ICOORD pos; //current point
893 ICOORD step; //edge step
894 int32_t length; //of outline
895 int16_t stepindex; //current step
896 C_OUTLINE_IT out_it = outline->child ();
897
898 pos = outline->start_pos ();
899 length = outline->pathlength ();
900 for (stepindex = 0; stepindex < length; stepindex++) {
901 step = outline->step (stepindex);
902 if (step.x () > 0) {
903 stats->add (pos.x (), -pos.y ());
904 } else if (step.x () < 0) {
905 stats->add (pos.x () - 1, pos.y ());
906 }
907 pos += step;
908 }
909
910 for (out_it.mark_cycle_pt (); !out_it.cycled_list (); out_it.forward ()) {
911 vertical_coutline_projection (out_it.data (), stats);
912 }
913}
C_OUTLINE_LIST * child()
Definition: coutln.h:108
ICOORD step(int index) const
Definition: coutln.h:144
const ICOORD & start_pos() const
Definition: coutln.h:148
int32_t pathlength() const
Definition: coutln.h:135
integer coordinate
Definition: points.h:32
int16_t y() const
access_function
Definition: points.h:56
int16_t x() const
access function
Definition: points.h:52
void add(int32_t value, int32_t count)
Definition: statistc.cpp:93

◆ vertical_torow_projection()

int16_t vertical_torow_projection ( TO_ROW row,
STATS projection 
)

Variable Documentation

◆ pitsync_fake_depth

int pitsync_fake_depth = 1
extern

"Max advance fake generation"

Definition at line 29 of file pitsync1.cpp.

◆ pitsync_joined_edge

double pitsync_joined_edge = 0.75
extern

"Dist inside big blob for chopping"

Definition at line 26 of file pitsync1.cpp.

◆ pitsync_offset_freecut_fraction

double pitsync_offset_freecut_fraction = 0.25
extern

"Fraction of cut for free cuts"

Definition at line 28 of file pitsync1.cpp.