38 #include "config_auto.h" 58 const char* description,
63 White, blamer_bundle);
65 BLOB_CHOICE_IT bc_it(choices);
66 for (bc_it.mark_cycle_pt(); !bc_it.cycled_list(); bc_it.forward()) {
67 bc_it.data()->set_matrix_cell(start, end);
75 template<
class BLOB_CHOICE>
83 template<
class BLOB_CHOICE>
107 BLOB_CHOICE_LIST *filtered_choices) {
108 BLOB_CHOICE_IT filtered_choices_it(filtered_choices);
109 BLOB_CHOICE_IT choices_it(choices);
111 for (choices_it.mark_cycle_pt(); !choices_it.cycled_list();
112 choices_it.forward()) {
113 UNICHAR_ID choice_unichar_id = choices_it.data()->unichar_id();
116 if (frag !=
nullptr && frag->
get_pos() == fragment_pos &&
123 filtered_choices_it.add_to_end(b);
127 filtered_choices->sort(SortByUnicharID<BLOB_CHOICE>);
138 int16_t num_frag_parts,
139 BLOB_CHOICE_LIST *choice_lists,
141 BLOB_CHOICE_IT *choice_lists_it =
new BLOB_CHOICE_IT[num_frag_parts];
143 for (
int i = 0; i < num_frag_parts; i++) {
144 choice_lists_it[i].set_to_list(&choice_lists[i]);
145 choice_lists_it[i].mark_cycle_pt();
148 BLOB_CHOICE_LIST *merged_choice = ratings->
get(row, column);
149 if (merged_choice ==
nullptr)
150 merged_choice =
new BLOB_CHOICE_LIST;
152 bool end_of_list =
false;
153 BLOB_CHOICE_IT merged_choice_it(merged_choice);
154 while (!end_of_list) {
157 UNICHAR_ID max_unichar_id = choice_lists_it[0].data()->unichar_id();
158 for (
int i = 0; i < num_frag_parts; i++) {
159 UNICHAR_ID unichar_id = choice_lists_it[i].data()->unichar_id();
160 if (max_unichar_id < unichar_id) {
161 max_unichar_id = unichar_id;
167 for (
int i = 0; i < num_frag_parts; i++) {
168 UNICHAR_ID unichar_id = choice_lists_it[i].data()->unichar_id();
169 while (!choice_lists_it[i].cycled_list() &&
170 unichar_id < max_unichar_id) {
171 choice_lists_it[i].forward();
172 unichar_id = choice_lists_it[i].data()->unichar_id();
174 if (choice_lists_it[i].cycled_list()) {
184 UNICHAR_ID first_unichar_id = choice_lists_it[0].data()->unichar_id();
185 bool same_unichar =
true;
186 for (
int i = 1; i < num_frag_parts; i++) {
187 UNICHAR_ID unichar_id = choice_lists_it[i].data()->unichar_id();
188 if (unichar_id != first_unichar_id) {
189 same_unichar =
false;
196 UNICHAR_ID merged_unichar_id = first_unichar_id;
198 choice_lists_it[0].data()->fonts();
199 float merged_min_xheight = choice_lists_it[0].data()->min_xheight();
200 float merged_max_xheight = choice_lists_it[0].data()->max_xheight();
201 float positive_yshift = 0, negative_yshift = 0;
202 int merged_script_id = choice_lists_it[0].data()->script_id();
205 float merged_rating = 0, merged_certainty = 0;
206 for (
int i = 0; i < num_frag_parts; i++) {
207 float rating = choice_lists_it[i].data()->rating();
208 float certainty = choice_lists_it[i].data()->certainty();
210 if (i == 0 || certainty < merged_certainty)
211 merged_certainty = certainty;
212 merged_rating += rating;
214 choice_lists_it[i].forward();
215 if (choice_lists_it[i].cycled_list())
218 choice_lists_it[i].data()->max_xheight(),
219 &merged_min_xheight, &merged_max_xheight);
220 float yshift = choice_lists_it[i].data()->yshift();
221 if (yshift > positive_yshift) positive_yshift = yshift;
222 if (yshift < negative_yshift) negative_yshift = yshift;
226 choice_lists_it[i].data()->fonts();
227 for (
int f = 0; f < frag_fonts.
size(); ++f) {
229 for (merged_f = 0; merged_f < merged_fonts.
size() &&
230 merged_fonts[merged_f].fontinfo_id != frag_fonts[f].fontinfo_id;
232 if (merged_f == merged_fonts.
size()) {
234 }
else if (merged_fonts[merged_f].score > frag_fonts[f].score) {
235 merged_fonts[merged_f].score = frag_fonts[f].score;
240 float merged_yshift = positive_yshift != 0
241 ? (negative_yshift != 0 ? 0 : positive_yshift)
252 merged_choice_it.add_to_end(choice);
260 if (merged_choice->empty())
261 delete merged_choice;
263 ratings->
put(row, column, merged_choice);
265 delete [] choice_lists_it;
281 int16_t start, int16_t num_frag_parts,
282 int16_t num_blobs,
MATRIX *ratings,
283 BLOB_CHOICE_LIST *choice_lists) {
284 if (current_frag == num_frag_parts) {
286 choice_lists, ratings);
290 for (int16_t x = current_row; x < num_blobs; x++) {
291 BLOB_CHOICE_LIST *choices = ratings->
get(current_row, x);
292 if (choices ==
nullptr)
296 &choice_lists[current_frag]);
297 if (!choice_lists[current_frag].empty()) {
299 num_blobs, ratings, choice_lists);
300 choice_lists[current_frag].clear();
314 for (int16_t start = 0; start < num_blobs; start++) {
318 ratings, choice_lists);
323 for (int16_t x = 0; x < num_blobs; x++) {
324 for (int16_t y = x; y < num_blobs; y++) {
325 BLOB_CHOICE_LIST *choices = ratings->
get(x, y);
326 if (choices !=
nullptr) {
327 BLOB_CHOICE_IT choices_it(choices);
328 for (choices_it.mark_cycle_pt(); !choices_it.cycled_list();
329 choices_it.forward()) {
330 UNICHAR_ID choice_unichar_id = choices_it.data()->unichar_id();
334 delete choices_it.extract();
void set_fonts(const GenericVector< tesseract::ScoredFont > &fonts)
static void JoinPieces(const GenericVector< SEAM *> &seams, const GenericVector< TBLOB *> &blobs, int first, int last)
static void BreakPieces(const GenericVector< SEAM *> &seams, const GenericVector< TBLOB *> &blobs, int first, int last)
void merge_and_put_fragment_lists(int16_t row, int16_t column, int16_t num_frag_parts, BLOB_CHOICE_LIST *choice_lists, MATRIX *ratings)
UNICHAR_ID unichar_to_id(const char *const unichar_repr) const
const char * get_unichar() const
int SortByRating(const void *void1, const void *void2)
int SortByUnicharID(const void *void1, const void *void2)
void set_unichar_id(UNICHAR_ID newunichar_id)
BLOB_CHOICE_LIST * classify_blob(TBLOB *blob, const char *string, C_COL color, BlamerBundle *blamer_bundle)
void put(ICOORD pos, const T &thing)
GenericVector< TBLOB * > blobs
const CHAR_FRAGMENT * get_fragment(UNICHAR_ID unichar_id) const
void IntersectRange(const T &lower1, const T &upper1, T *lower2, T *upper2)
void print_ratings_list(const char *msg, BLOB_CHOICE_LIST *ratings, const UNICHARSET ¤t_unicharset)
void merge_fragments(MATRIX *ratings, int16_t num_blobs)
virtual BLOB_CHOICE_LIST * classify_piece(const GenericVector< SEAM *> &seams, int16_t start, int16_t end, const char *description, TWERD *word, BlamerBundle *blamer_bundle)
UNICHAR_ID unichar_id() const
void get_fragment_lists(int16_t current_frag, int16_t current_row, int16_t start, int16_t num_frag_parts, int16_t num_blobs, MATRIX *ratings, BLOB_CHOICE_LIST *choice_lists)
void fill_filtered_fragment_list(BLOB_CHOICE_LIST *choices, int fragment_pos, int num_frag_parts, BLOB_CHOICE_LIST *filtered_choices)
static const int kMaxChunks