Collects edges into the given bounding box, LLSQ accumulator and/or x_coords, y_coords vectors. For a description of x_coords/y_coords, see GetEdgeCoords above. Startpt to lastpt, inclusive, MUST have the same src_outline member, which may be NULL. The vector from lastpt to its next is included in the accumulation. Hidden edges should be excluded by the caller. The input denorm should be the norma
| 669 | // box is the bounding box of the blob from which the EDGEPTs are taken and |
| 670 | // indices into x_coords, y_coords are offset by box.botleft(). |
| 671 | static void CollectEdgesOfRun(const EDGEPT* startpt, const EDGEPT* lastpt, |
| 672 | const DENORM& denorm, const TBOX& box, |
| 673 | TBOX* bounding_box, |
| 674 | LLSQ* accumulator, |
| 675 | GenericVector<GenericVector<int> > *x_coords, |
| 676 | GenericVector<GenericVector<int> > *y_coords) { |
| 677 | const C_OUTLINE* outline = startpt->src_outline; |
| 678 | int x_limit = box.width() - 1; |
| 679 | int y_limit = box.height() - 1; |
| 680 | if (outline != NULL) { |
| 681 | // Use higher-resolution edge points stored on the outline. |
| 682 | // The outline coordinates may not match the binary image because of the |
| 683 | // rotation for vertical text lines, but the root_denorm IS the matching |
| 684 | // start of the DENORM chain. |
| 685 | const DENORM* root_denorm = denorm.RootDenorm(); |
| 686 | int step_length = outline->pathlength(); |
| 687 | int start_index = startpt->start_step; |
| 688 | // Note that if this run straddles the wrap-around point of the outline, |
| 689 | // that lastpt->start_step may have a lower index than startpt->start_step, |
| 690 | // and we want to use an end_index that allows us to use a positive |
| 691 | // increment, so we add step_length if necessary, but that may be beyond the |
| 692 | // bounds of the outline steps/ due to wrap-around, so we use % step_length |
| 693 | // everywhere, except for start_index. |
| 694 | int end_index = lastpt->start_step + lastpt->step_count; |
| 695 | if (end_index <= start_index) |
| 696 | end_index += step_length; |
| 697 | // pos is the integer coordinates of the binary image steps. |
| 698 | ICOORD pos = outline->position_at_index(start_index); |
| 699 | FCOORD origin(box.left(), box.bottom()); |
| 700 | // f_pos is a floating-point version of pos that offers improved edge |
| 701 | // positioning using greyscale information or smoothing of edge steps. |
| 702 | FCOORD f_pos = outline->sub_pixel_pos_at_index(pos, start_index); |
| 703 | // pos_normed is f_pos after the appropriate normalization, and relative |
| 704 | // to origin. |
| 705 | // prev_normed is the previous value of pos_normed. |
| 706 | FCOORD prev_normed; |
| 707 | denorm.NormTransform(root_denorm, f_pos, &prev_normed); |
| 708 | prev_normed -= origin; |
| 709 | for (int index = start_index; index < end_index; ++index) { |
| 710 | ICOORD step = outline->step(index % step_length); |
| 711 | // Only use the point if its edge strength is positive. This excludes |
| 712 | // points that don't provide useful information, eg |
| 713 | // ___________ |
| 714 | // |___________ |
| 715 | // The vertical step provides only noisy, damaging information, as even |
| 716 | // with a greyscale image, the positioning of the edge there may be a |
| 717 | // fictitious extrapolation, so previous processing has eliminated it. |
| 718 | if (outline->edge_strength_at_index(index % step_length) > 0) { |
| 719 | FCOORD f_pos = outline->sub_pixel_pos_at_index(pos, |
| 720 | index % step_length); |
| 721 | FCOORD pos_normed; |
| 722 | denorm.NormTransform(root_denorm, f_pos, &pos_normed); |
| 723 | pos_normed -= origin; |
| 724 | // Accumulate the information that is selected by the caller. |
| 725 | if (bounding_box != NULL) { |
| 726 | SegmentBBox(pos_normed, prev_normed, bounding_box); |
| 727 | } |
| 728 | if (accumulator != NULL) { |
no test coverage detected