41 {
42 stats->Clear();
43
46 return;
47 }
48 if (debug) {
49 tprintf(
"AssociateUtils::ComputeStats() for col=%d, row=%d%s\n",
50 col, row, fixed_pitch ? " (fixed pitch)" : "");
51 }
54
55 if (fixed_pitch && blob_row != nullptr) {
56
57
58
61 } else {
64 }
65 if (debug) {
66 tprintf(
"normalizing height = %g (scale %g xheight %g ascenders %g)\n",
69 }
70 }
71 float wh_ratio = word_res->
GetBlobsWidth(col, row) / normalizing_height;
72 if (wh_ratio > max_char_wh_ratio) stats->bad_shape = true;
73
74
75
76
77 int negative_gap_sum = 0;
78 for (int c = col; c < row; ++c) {
80 (gap > 0) ? stats->gap_sum += gap : negative_gap_sum += gap;
81 }
82 if (stats->gap_sum == 0) stats->gap_sum = negative_gap_sum;
83 if (debug) {
84 tprintf(
"wh_ratio=%g (max_char_wh_ratio=%g) gap_sum=%d %s\n",
85 wh_ratio, max_char_wh_ratio, stats->gap_sum,
86 stats->bad_shape ? "bad_shape" : "");
87 }
88
89 if (fixed_pitch) {
91
92
93
94
95 if (col > 0) {
96 float left_gap = word_res->
GetBlobsGap(col - 1) / normalizing_height;
99 stats->bad_shape = true;
100 }
101 if (debug) {
102 tprintf(
"left_gap %g, left_seam %g %s\n", left_gap,
103 left_seam->
priority(), stats->bad_shape ?
"bad_shape" :
"");
104 }
105 }
106 float right_gap = 0.0f;
107 if (!end_row) {
108 right_gap = word_res->
GetBlobsGap(row) / normalizing_height;
110 if (right_gap < kMinGap || right_seam->priority() > 0.0f) {
111 stats->bad_shape = true;
112 if (right_gap <
kMinGap) stats->bad_fixed_pitch_right_gap =
true;
113 }
114 if (debug) {
115 tprintf(
"right_gap %g right_seam %g %s\n", right_gap,
116 right_seam->
priority(), stats->bad_shape ?
"bad_shape" :
"");
117 }
118 }
119
120
121
122
123
124
125 stats->full_wh_ratio = wh_ratio + right_gap;
126 if (parent_stats != nullptr) {
127 stats->full_wh_ratio_total =
128 (parent_stats->full_wh_ratio_total + stats->full_wh_ratio);
129 float mean =
130 stats->full_wh_ratio_total / static_cast<float>(parent_path_length+1);
131 stats->full_wh_ratio_var =
132 parent_stats->full_wh_ratio_var + pow(mean-stats->full_wh_ratio, 2);
133 } else {
134 stats->full_wh_ratio_total = stats->full_wh_ratio;
135 }
136 if (debug) {
137 tprintf(
"full_wh_ratio %g full_wh_ratio_total %g full_wh_ratio_var %g\n",
138 stats->full_wh_ratio, stats->full_wh_ratio_total,
139 stats->full_wh_ratio_var);
140 }
141
142 stats->shape_cost =
144
145
146
147
148 if (col == 0 && end_row && wh_ratio > max_char_wh_ratio) {
149 stats->shape_cost += 10;
150 }
151 stats->shape_cost += stats->full_wh_ratio_var;
152 if (debug)
tprintf(
"shape_cost %g\n", stats->shape_cost);
153 }
154}
DLLSYM void tprintf(const char *format,...)
int GetBlobsGap(int blob_index)
GenericVector< int > blob_widths
GenericVector< SEAM * > seam_array
int GetBlobsWidth(int start_blob, int last_blob)
static const float kMinGap
static float FixedPitchWidthCost(float norm_width, float right_gap, bool end_pos, float max_char_wh_ratio)