39 if (word_res->blob_widths.empty()) {
43 tprintf(
"AssociateUtils::ComputeStats() for col=%d, row=%d%s\n", col, row,
44 fixed_pitch ?
" (fixed pitch)" :
"");
47 ROW *blob_row = word_res->blob_row;
49 if (fixed_pitch && blob_row !=
nullptr) {
53 if (blob_row->body_size() > 0.0f) {
54 normalizing_height = word_res->denorm.y_scale() * blob_row->body_size();
57 word_res->denorm.y_scale() * (blob_row->x_height() + blob_row->ascenders());
60 tprintf(
"normalizing height = %g (scale %g xheight %g ascenders %g)\n", normalizing_height,
61 word_res->denorm.y_scale(), blob_row->x_height(), blob_row->ascenders());
64 float wh_ratio = word_res->GetBlobsWidth(col, row) / normalizing_height;
65 if (wh_ratio > max_char_wh_ratio) {
66 stats->bad_shape =
true;
72 int negative_gap_sum = 0;
73 for (
int c = col; c < row; ++c) {
74 int gap = word_res->GetBlobsGap(c);
75 (gap > 0) ? stats->gap_sum += gap : negative_gap_sum += gap;
77 if (stats->gap_sum == 0) {
78 stats->gap_sum = negative_gap_sum;
81 tprintf(
"wh_ratio=%g (max_char_wh_ratio=%g) gap_sum=%d %s\n", wh_ratio, max_char_wh_ratio,
82 stats->gap_sum, stats->bad_shape ?
"bad_shape" :
"");
86 bool end_row = (row == (word_res->ratings->dimension() - 1));
92 float left_gap = word_res->GetBlobsGap(col - 1) / normalizing_height;
93 SEAM *left_seam = word_res->seam_array[col - 1];
94 if ((!end_row && left_gap <
kMinGap) || left_seam->priority() > 0.0f) {
95 stats->bad_shape =
true;
98 tprintf(
"left_gap %g, left_seam %g %s\n", left_gap, left_seam->priority(),
99 stats->bad_shape ?
"bad_shape" :
"");
102 float right_gap = 0.0f;
104 right_gap = word_res->GetBlobsGap(row) / normalizing_height;
105 SEAM *right_seam = word_res->seam_array[row];
106 if (right_gap < kMinGap || right_seam->priority() > 0.0f) {
107 stats->bad_shape =
true;
109 stats->bad_fixed_pitch_right_gap =
true;
113 tprintf(
"right_gap %g right_seam %g %s\n", right_gap, right_seam->priority(),
114 stats->bad_shape ?
"bad_shape" :
"");
123 stats->full_wh_ratio = wh_ratio + right_gap;
124 if (parent_stats !=
nullptr) {
125 stats->full_wh_ratio_total = (parent_stats->full_wh_ratio_total + stats->full_wh_ratio);
126 float mean = stats->full_wh_ratio_total /
static_cast<float>(parent_path_length + 1);
127 stats->full_wh_ratio_var =
128 parent_stats->full_wh_ratio_var + pow(mean - stats->full_wh_ratio, 2);
130 stats->full_wh_ratio_total = stats->full_wh_ratio;
133 tprintf(
"full_wh_ratio %g full_wh_ratio_total %g full_wh_ratio_var %g\n",
134 stats->full_wh_ratio, stats->full_wh_ratio_total, stats->full_wh_ratio_var);
142 if (col == 0 && end_row && wh_ratio > max_char_wh_ratio) {
143 stats->shape_cost += 10;
145 stats->shape_cost += stats->full_wh_ratio_var;
147 tprintf(
"shape_cost %g\n", stats->shape_cost);
void tprintf(const char *format,...)
static const float kMinGap
static float FixedPitchWidthCost(float norm_width, float right_gap, bool end_pos, float max_char_wh_ratio)