MCPcopy Create free account
hub / github.com/creatale/node-dv / ComputeBinaryOffsets

Method ComputeBinaryOffsets

deps/tesseract/ccstruct/coutln.cpp:859–911  ·  view source on GitHub ↗

* Adds sub-pixel resolution EdgeOffsets for the outline using only * a binary image source. * * Runs a sliding window of 5 edge steps over the outline, maintaining a count * of the number of steps in each of the 4 directions in the window, and a * sum of the x or y position of each step (as appropriate to its direction.) * Ignores single-count steps EXCEPT the sharp U-turn and smoothes out t

Source from the content-addressed store, hash-verified

857 * outline, without losing important detail.
858 */
859void C_OUTLINE::ComputeBinaryOffsets() {
860 delete [] offsets;
861 offsets = new EdgeOffset[stepcount];
862 // Count of the number of steps in each direction in the sliding window.
863 int dir_counts[4];
864 // Sum of the positions (y for a horizontal step, x for vertical) in each
865 // direction in the sliding window.
866 int pos_totals[4];
867 memset(dir_counts, 0, sizeof(dir_counts));
868 memset(pos_totals, 0, sizeof(pos_totals));
869 ICOORD pos = start;
870 ICOORD tail_pos = pos;
871 // tail_pos is the trailing position, with the next point to be lost from
872 // the window.
873 tail_pos -= step(stepcount - 1);
874 tail_pos -= step(stepcount - 2);
875 // head_pos is the leading position, with the next point to be added to the
876 // window.
877 ICOORD head_pos = tail_pos;
878 // Set up the initial window with 4 points in [-2, 2)
879 for (int s = -2; s < 2; ++s) {
880 increment_step(s, 1, &head_pos, dir_counts, pos_totals);
881 }
882 for (int s = 0; s < stepcount; pos += step(s++)) {
883 // At step s, s in in the middle of [s-2, s+2].
884 increment_step(s + 2, 1, &head_pos, dir_counts, pos_totals);
885 int dir_index = chain_code(s);
886 ICOORD step_vec = step(s);
887 int best_diff = 0;
888 int offset = 0;
889 // Use only steps that have a count of >=2 OR the strong U-turn with a
890 // single d and 2 at d-1 and 2 at d+1 (mod 4).
891 if (dir_counts[dir_index] >= 2 || (dir_counts[dir_index] == 1 &&
892 dir_counts[Modulo(dir_index - 1, 4)] == 2 &&
893 dir_counts[Modulo(dir_index + 1, 4)] == 2)) {
894 // Valid step direction.
895 best_diff = dir_counts[dir_index];
896 int edge_pos = step_vec.x() == 0 ? pos.x() : pos.y();
897 // The offset proposes that the actual step should be positioned at
898 // the mean position of the steps in the window of the same direction.
899 // See ASCII art above.
900 offset = pos_totals[dir_index] - best_diff * edge_pos;
901 }
902 offsets[s].offset_numerator =
903 static_cast<inT8>(ClipToRange(offset, -MAX_INT8, MAX_INT8));
904 offsets[s].pixel_diff = static_cast<uinT8>(ClipToRange(best_diff, 0 ,
905 MAX_UINT8));
906 // The direction is just the vector from start to end of the window.
907 FCOORD direction(head_pos.x() - tail_pos.x(), head_pos.y() - tail_pos.y());
908 offsets[s].direction = direction.to_direction();
909 increment_step(s - 2, -1, &tail_pos, dir_counts, pos_totals);
910 }
911}
912
913/**
914 * Renders the outline to the given pix, with left and top being

Callers 1

Calls 7

stepFunction · 0.85
chain_codeFunction · 0.85
ModuloFunction · 0.85
ClipToRangeFunction · 0.85
to_directionMethod · 0.80
xMethod · 0.45
yMethod · 0.45

Tested by

no test coverage detected