#include "blobbox.h"
#include "varable.h"
#include "statistc.h"
#include "notdll.h"
Go to the source code of this file.
double check_pitch_sync2 | ( | BLOBNBOX_IT * | blob_it, | |
INT16 | blob_count, | |||
INT16 | pitch, | |||
INT16 | pitch_error, | |||
STATS * | projection, | |||
INT16 | projection_left, | |||
INT16 | projection_right, | |||
float | projection_scale, | |||
INT16 & | occupation_count, | |||
FPSEGPT_LIST * | seg_list, | |||
INT16 | start, | |||
INT16 | end | |||
) |
Find segmentation.
blob_it | Pointer to blobs to do | |
blob_count | Number of blobs | |
pitch | Pitch estimate | |
pitch_error | Tolerance | |
projection | Vertical | |
projection_left | Left edge | |
projection_right | Right edge | |
projection_scale | Scale factor | |
occupation_count | Number of occupied cells | |
seg_list | LIST of segments (modified) | |
start | Start of good range | |
end | End of good range |
Definition at line 307 of file pithsync.cpp.
References alloc_mem(), ASSERT_HOST, box_next(), check_pitch_sync3(), cprintf(), FALSE, free_mem(), BOX::left(), MAX_FLOAT32, MAX_INT16, MAX_INT32, NULL, STATS::pile_count(), FPCUTPT::position(), FPCUTPT::previous(), projection, BOX::right(), FPCUTPT::sum(), BOX::top(), tprintf(), and TRUE.
Referenced by compute_pitch_sd(), compute_pitch_sd2(), plot_fp_cells(), and print_pitch_sd().
00320 { 00321 BOOL8 faking; //illegal cut pt 00322 BOOL8 mid_cut; //cheap cut pt. 00323 INT16 x; //current coord 00324 INT16 blob_index; //blob number 00325 INT16 left_edge; //of word 00326 INT16 right_edge; //of word 00327 INT16 array_origin; //x coord of array 00328 INT16 offset; //dist to legal area 00329 INT16 zero_count; //projection zero 00330 INT16 best_left_x = 0; //for equals 00331 INT16 best_right_x = 0; //right edge 00332 BOX this_box; //bounding box 00333 BOX next_box; //box of next blob 00334 FPSEGPT *segpt; //segment point 00335 FPCUTPT *cutpts; //array of points 00336 double best_cost; //best path 00337 double mean_sum; //computes result 00338 FPCUTPT *best_end; //end of best path 00339 INT16 best_fake; //best fake level 00340 INT16 best_count; //no of cuts 00341 BLOBNBOX_IT this_it; //copy iterator 00342 FPSEGPT_IT seg_it = seg_list; //output iterator 00343 00344 #ifdef TEXT_VERBOSE 00345 // gets a 't', see ccmain/tesseractmain.dox 00346 cprintf("t"); 00347 #endif 00348 // tprintf("Computing sync on word of %d blobs with pitch %d\n", 00349 // blob_count, pitch); 00350 // if (blob_count==8 && pitch==27) 00351 // projection->print(stdout,TRUE); 00352 zero_count = 0; 00353 if (pitch < 3) 00354 pitch = 3; //nothing ludicrous 00355 if ((pitch - 3) / 2 < pitch_error) 00356 pitch_error = (pitch - 3) / 2; 00357 this_it = *blob_it; 00358 this_box = box_next (&this_it);//get box 00359 // left_edge=this_box.left(); //left of word 00360 // right_edge=this_box.right(); 00361 // for (blob_index=1;blob_index<blob_count;blob_index++) 00362 // { 00363 // this_box=box_next(&this_it); 00364 // if (this_box.right()>right_edge) 00365 // right_edge=this_box.right(); 00366 // } 00367 for (left_edge = projection_left; projection->pile_count (left_edge) == 0 00368 && left_edge < projection_right; left_edge++); 00369 for (right_edge = projection_right; projection->pile_count (right_edge) == 0 00370 && right_edge > left_edge; right_edge--); 00371 ASSERT_HOST (right_edge >= left_edge); 00372 if (pitsync_linear_version >= 4) 00373 return check_pitch_sync3 (projection_left, projection_right, zero_count, 00374 pitch, pitch_error, projection, 00375 projection_scale, occupation_count, seg_list, 00376 start, end); 00377 array_origin = left_edge - pitch; 00378 cutpts = (FPCUTPT *) alloc_mem ((right_edge - left_edge + pitch * 2 + 1) 00379 * sizeof (FPCUTPT)); 00380 for (x = array_origin; x < left_edge; x++) 00381 //free cuts 00382 cutpts[x - array_origin].setup (cutpts, array_origin, projection, 00383 zero_count, pitch, x, 0); 00384 for (offset = 0; offset <= pitch_error; offset++, x++) 00385 //not quite free 00386 cutpts[x - array_origin].setup (cutpts, array_origin, projection, 00387 zero_count, pitch, x, offset); 00388 00389 this_it = *blob_it; 00390 best_cost = MAX_FLOAT32; 00391 best_end = NULL; 00392 this_box = box_next (&this_it);//first box 00393 next_box = box_next (&this_it);//second box 00394 blob_index = 1; 00395 while (x < right_edge - pitch_error) { 00396 if (x > this_box.right () + pitch_error && blob_index < blob_count) { 00397 this_box = next_box; 00398 next_box = box_next (&this_it); 00399 blob_index++; 00400 } 00401 faking = FALSE; 00402 mid_cut = FALSE; 00403 if (x <= this_box.left ()) 00404 offset = 0; 00405 else if (x <= this_box.left () + pitch_error) 00406 offset = x - this_box.left (); 00407 else if (x >= this_box.right ()) 00408 offset = 0; 00409 else if (x >= next_box.left () && blob_index < blob_count) { 00410 offset = x - next_box.left (); 00411 if (this_box.right () - x < offset) 00412 offset = this_box.right () - x; 00413 } 00414 else if (x >= this_box.right () - pitch_error) 00415 offset = this_box.right () - x; 00416 else if (x - this_box.left () > pitch * pitsync_joined_edge 00417 && this_box.right () - x > pitch * pitsync_joined_edge) { 00418 mid_cut = TRUE; 00419 offset = 0; 00420 } 00421 else { 00422 faking = TRUE; 00423 offset = projection->pile_count (x); 00424 } 00425 cutpts[x - array_origin].assign (cutpts, array_origin, x, 00426 faking, mid_cut, offset, projection, 00427 projection_scale, zero_count, pitch, 00428 pitch_error); 00429 x++; 00430 } 00431 00432 best_fake = MAX_INT16; 00433 best_cost = MAX_INT32; 00434 best_count = MAX_INT16; 00435 while (x < right_edge + pitch) { 00436 offset = x < right_edge ? right_edge - x : 0; 00437 cutpts[x - array_origin].assign (cutpts, array_origin, x, 00438 FALSE, FALSE, offset, projection, 00439 projection_scale, zero_count, pitch, 00440 pitch_error); 00441 cutpts[x - array_origin].terminal = TRUE; 00442 if (cutpts[x - array_origin].index () + 00443 cutpts[x - array_origin].fake_count <= best_count + best_fake) { 00444 if (cutpts[x - array_origin].fake_count < best_fake 00445 || cutpts[x - array_origin].fake_count == best_fake 00446 && cutpts[x - array_origin].cost_function () < best_cost) { 00447 best_fake = cutpts[x - array_origin].fake_count; 00448 best_cost = cutpts[x - array_origin].cost_function (); 00449 best_left_x = x; 00450 best_right_x = x; 00451 best_count = cutpts[x - array_origin].index (); 00452 } 00453 else if (cutpts[x - array_origin].fake_count == best_fake 00454 && x == best_right_x + 1 00455 && cutpts[x - array_origin].cost_function () == best_cost) { 00456 //exactly equal 00457 best_right_x = x; 00458 } 00459 } 00460 x++; 00461 } 00462 ASSERT_HOST (best_fake < MAX_INT16); 00463 00464 best_end = &cutpts[(best_left_x + best_right_x) / 2 - array_origin]; 00465 if (this_box.right () == textord_test_x 00466 && this_box.top () == textord_test_y) { 00467 for (x = left_edge - pitch; x < right_edge + pitch; x++) { 00468 tprintf ("x=%d, C=%g, s=%g, sq=%g, prev=%d\n", 00469 x, cutpts[x - array_origin].cost_function (), 00470 cutpts[x - array_origin].sum (), 00471 cutpts[x - array_origin].squares (), 00472 cutpts[x - array_origin].previous ()->position ()); 00473 } 00474 } 00475 occupation_count = -1; 00476 do { 00477 for (x = best_end->position () - pitch + pitch_error; 00478 x < best_end->position () - pitch_error 00479 && projection->pile_count (x) == 0; x++); 00480 if (x < best_end->position () - pitch_error) 00481 occupation_count++; 00482 //copy it 00483 segpt = new FPSEGPT (best_end); 00484 seg_it.add_before_then_move (segpt); 00485 best_end = best_end->previous (); 00486 } 00487 while (best_end != NULL); 00488 seg_it.move_to_last (); 00489 mean_sum = seg_it.data ()->sum (); 00490 mean_sum = mean_sum * mean_sum / best_count; 00491 if (seg_it.data ()->squares () - mean_sum < 0) 00492 tprintf ("Impossible sqsum=%g, mean=%g, total=%d\n", 00493 seg_it.data ()->squares (), seg_it.data ()->sum (), best_count); 00494 free_mem(cutpts); 00495 // tprintf("blob_count=%d, pitch=%d, sync=%g, occ=%d\n", 00496 // blob_count,pitch,seg_it.data()->squares()-mean_sum, 00497 // occupation_count); 00498 return seg_it.data ()->squares () - mean_sum; 00499 }
double check_pitch_sync3 | ( | INT16 | projection_left, | |
INT16 | projection_right, | |||
INT16 | zero_count, | |||
INT16 | pitch, | |||
INT16 | pitch_error, | |||
STATS * | projection, | |||
float | projection_scale, | |||
INT16 & | occupation_count, | |||
FPSEGPT_LIST * | seg_list, | |||
INT16 | start, | |||
INT16 | end | |||
) |
Find segmentation.
Definition at line 510 of file pithsync.cpp.
References alloc_mem(), ASSERT_HOST, FALSE, free_mem(), STATS::local_min(), MAX_FLOAT32, MAX_INT16, MAX_INT32, NULL, STATS::pile_count(), FPCUTPT::position(), FPCUTPT::previous(), projection, FPCUTPT::sum(), tprintf(), and TRUE.
Referenced by check_pitch_sync2().
00522 { 00523 BOOL8 faking; //illegal cut pt 00524 BOOL8 mid_cut; //cheap cut pt. 00525 INT16 left_edge; //of word 00526 INT16 right_edge; //of word 00527 INT16 x; //current coord 00528 INT16 array_origin; //x coord of array 00529 INT16 offset; //dist to legal area 00530 INT16 projection_offset; //from scaled projection 00531 INT16 prev_zero; //previous zero dist 00532 INT16 next_zero; //next zero dist 00533 INT16 zero_offset; //scan window 00534 INT16 best_left_x = 0; //for equals 00535 INT16 best_right_x = 0; //right edge 00536 FPSEGPT *segpt; //segment point 00537 FPCUTPT *cutpts; //array of points 00538 BOOL8 *mins; //local min results 00539 int minindex; //next input position 00540 int test_index; //index to mins 00541 double best_cost; //best path 00542 double mean_sum; //computes result 00543 FPCUTPT *best_end; //end of best path 00544 INT16 best_fake; //best fake level 00545 INT16 best_count; //no of cuts 00546 FPSEGPT_IT seg_it = seg_list; //output iterator 00547 00548 end = (end - start) % pitch; 00549 if (pitch < 3) 00550 pitch = 3; //nothing ludicrous 00551 if ((pitch - 3) / 2 < pitch_error) 00552 pitch_error = (pitch - 3) / 2; 00553 //min dist of zero 00554 zero_offset = (INT16) (pitch * pitsync_joined_edge); 00555 for (left_edge = projection_left; projection->pile_count (left_edge) == 0 00556 && left_edge < projection_right; left_edge++); 00557 for (right_edge = projection_right; projection->pile_count (right_edge) == 0 00558 && right_edge > left_edge; right_edge--); 00559 array_origin = left_edge - pitch; 00560 cutpts = (FPCUTPT *) alloc_mem ((right_edge - left_edge + pitch * 2 + 1) 00561 * sizeof (FPCUTPT)); 00562 mins = (BOOL8 *) alloc_mem ((pitch_error * 2 + 1) * sizeof (BOOL8)); 00563 for (x = array_origin; x < left_edge; x++) 00564 //free cuts 00565 cutpts[x - array_origin].setup (cutpts, array_origin, projection, 00566 zero_count, pitch, x, 0); 00567 prev_zero = left_edge - 1; 00568 for (offset = 0; offset <= pitch_error; offset++, x++) 00569 //not quite free 00570 cutpts[x - array_origin].setup (cutpts, array_origin, projection, 00571 zero_count, pitch, x, offset); 00572 00573 best_cost = MAX_FLOAT32; 00574 best_end = NULL; 00575 for (offset = -pitch_error, minindex = 0; offset < pitch_error; 00576 offset++, minindex++) 00577 mins[minindex] = projection->local_min (x + offset); 00578 next_zero = x + zero_offset + 1; 00579 for (offset = next_zero - 1; offset >= x; offset--) { 00580 if (projection->pile_count (offset) <= zero_count) { 00581 next_zero = offset; 00582 break; 00583 } 00584 } 00585 while (x < right_edge - pitch_error) { 00586 mins[minindex] = projection->local_min (x + pitch_error); 00587 minindex++; 00588 if (minindex > pitch_error * 2) 00589 minindex = 0; 00590 faking = FALSE; 00591 mid_cut = FALSE; 00592 offset = 0; 00593 if (projection->pile_count (x) <= zero_count) { 00594 prev_zero = x; 00595 } 00596 else { 00597 for (offset = 1; offset <= pitch_error; offset++) 00598 if (projection->pile_count (x + offset) <= zero_count 00599 || projection->pile_count (x - offset) <= zero_count) 00600 break; 00601 } 00602 if (offset > pitch_error) { 00603 if (x - prev_zero > zero_offset && next_zero - x > zero_offset) { 00604 for (offset = 0; offset <= pitch_error; offset++) { 00605 test_index = minindex + pitch_error + offset; 00606 if (test_index > pitch_error * 2) 00607 test_index -= pitch_error * 2 + 1; 00608 if (mins[test_index]) 00609 break; 00610 test_index = minindex + pitch_error - offset; 00611 if (test_index > pitch_error * 2) 00612 test_index -= pitch_error * 2 + 1; 00613 if (mins[test_index]) 00614 break; 00615 } 00616 } 00617 if (offset > pitch_error) { 00618 offset = projection->pile_count (x); 00619 faking = TRUE; 00620 } 00621 else { 00622 projection_offset = 00623 (INT16) (projection->pile_count (x) / projection_scale); 00624 if (projection_offset > offset) 00625 offset = projection_offset; 00626 mid_cut = TRUE; 00627 } 00628 } 00629 if (start == 0 && end == 0 00630 || !textord_fast_pitch_test 00631 || (x - projection_left - start) % pitch <= end) 00632 cutpts[x - array_origin].assign (cutpts, array_origin, x, 00633 faking, mid_cut, offset, projection, 00634 projection_scale, zero_count, pitch, 00635 pitch_error); 00636 else 00637 cutpts[x - array_origin].assign_cheap (cutpts, array_origin, x, 00638 faking, mid_cut, offset, 00639 projection, projection_scale, 00640 zero_count, pitch, 00641 pitch_error); 00642 x++; 00643 if (next_zero < x || next_zero == x + zero_offset) 00644 next_zero = x + zero_offset + 1; 00645 if (projection->pile_count (x + zero_offset) <= zero_count) 00646 next_zero = x + zero_offset; 00647 } 00648 00649 best_fake = MAX_INT16; 00650 best_cost = MAX_INT32; 00651 best_count = MAX_INT16; 00652 while (x < right_edge + pitch) { 00653 offset = x < right_edge ? right_edge - x : 0; 00654 cutpts[x - array_origin].assign (cutpts, array_origin, x, 00655 FALSE, FALSE, offset, projection, 00656 projection_scale, zero_count, pitch, 00657 pitch_error); 00658 cutpts[x - array_origin].terminal = TRUE; 00659 if (cutpts[x - array_origin].index () + 00660 cutpts[x - array_origin].fake_count <= best_count + best_fake) { 00661 if (cutpts[x - array_origin].fake_count < best_fake 00662 || cutpts[x - array_origin].fake_count == best_fake 00663 && cutpts[x - array_origin].cost_function () < best_cost) { 00664 best_fake = cutpts[x - array_origin].fake_count; 00665 best_cost = cutpts[x - array_origin].cost_function (); 00666 best_left_x = x; 00667 best_right_x = x; 00668 best_count = cutpts[x - array_origin].index (); 00669 } 00670 else if (cutpts[x - array_origin].fake_count == best_fake 00671 && x == best_right_x + 1 00672 && cutpts[x - array_origin].cost_function () == best_cost) { 00673 //exactly equal 00674 best_right_x = x; 00675 } 00676 } 00677 x++; 00678 } 00679 ASSERT_HOST (best_fake < MAX_INT16); 00680 00681 best_end = &cutpts[(best_left_x + best_right_x) / 2 - array_origin]; 00682 // for (x=left_edge-pitch;x<right_edge+pitch;x++) 00683 // { 00684 // tprintf("x=%d, C=%g, s=%g, sq=%g, prev=%d\n", 00685 // x,cutpts[x-array_origin].cost_function(), 00686 // cutpts[x-array_origin].sum(), 00687 // cutpts[x-array_origin].squares(), 00688 // cutpts[x-array_origin].previous()->position()); 00689 // } 00690 occupation_count = -1; 00691 do { 00692 for (x = best_end->position () - pitch + pitch_error; 00693 x < best_end->position () - pitch_error 00694 && projection->pile_count (x) == 0; x++); 00695 if (x < best_end->position () - pitch_error) 00696 occupation_count++; 00697 //copy it 00698 segpt = new FPSEGPT (best_end); 00699 seg_it.add_before_then_move (segpt); 00700 best_end = best_end->previous (); 00701 } 00702 while (best_end != NULL); 00703 seg_it.move_to_last (); 00704 mean_sum = seg_it.data ()->sum (); 00705 mean_sum = mean_sum * mean_sum / best_count; 00706 if (seg_it.data ()->squares () - mean_sum < 0) 00707 tprintf ("Impossible sqsum=%g, mean=%g, total=%d\n", 00708 seg_it.data ()->squares (), seg_it.data ()->sum (), best_count); 00709 free_mem(mins); 00710 free_mem(cutpts); 00711 return seg_it.data ()->squares () - mean_sum; 00712 }