40 #include "config_auto.h"
60 const char* description,
65 White, blamer_bundle);
67 BLOB_CHOICE_IT bc_it(choices);
68 for (bc_it.mark_cycle_pt(); !bc_it.cycled_list(); bc_it.forward()) {
69 bc_it.data()->set_matrix_cell(start, end);
77 template<
class BLOB_CHOICE>
85 template<
class BLOB_CHOICE>
109 BLOB_CHOICE_LIST *filtered_choices) {
110 BLOB_CHOICE_IT filtered_choices_it(filtered_choices);
111 BLOB_CHOICE_IT choices_it(choices);
113 for (choices_it.mark_cycle_pt(); !choices_it.cycled_list();
114 choices_it.forward()) {
115 UNICHAR_ID choice_unichar_id = choices_it.data()->unichar_id();
118 if (frag !=
NULL && frag->
get_pos() == fragment_pos &&
125 filtered_choices_it.add_to_end(b);
129 filtered_choices->sort(SortByUnicharID<BLOB_CHOICE>);
140 inT16 num_frag_parts,
141 BLOB_CHOICE_LIST *choice_lists,
143 BLOB_CHOICE_IT *choice_lists_it =
new BLOB_CHOICE_IT[num_frag_parts];
145 for (
int i = 0; i < num_frag_parts; i++) {
146 choice_lists_it[i].set_to_list(&choice_lists[i]);
147 choice_lists_it[i].mark_cycle_pt();
150 BLOB_CHOICE_LIST *merged_choice = ratings->
get(row, column);
151 if (merged_choice ==
NULL)
152 merged_choice =
new BLOB_CHOICE_LIST;
154 bool end_of_list =
false;
155 BLOB_CHOICE_IT merged_choice_it(merged_choice);
156 while (!end_of_list) {
159 UNICHAR_ID max_unichar_id = choice_lists_it[0].data()->unichar_id();
160 for (
int i = 0; i < num_frag_parts; i++) {
161 UNICHAR_ID unichar_id = choice_lists_it[i].data()->unichar_id();
162 if (max_unichar_id < unichar_id) {
163 max_unichar_id = unichar_id;
169 for (
int i = 0; i < num_frag_parts; i++) {
170 UNICHAR_ID unichar_id = choice_lists_it[i].data()->unichar_id();
171 while (!choice_lists_it[i].cycled_list() &&
172 unichar_id < max_unichar_id) {
173 choice_lists_it[i].forward();
174 unichar_id = choice_lists_it[i].data()->unichar_id();
176 if (choice_lists_it[i].cycled_list()) {
186 UNICHAR_ID first_unichar_id = choice_lists_it[0].data()->unichar_id();
187 bool same_unichar =
true;
188 for (
int i = 1; i < num_frag_parts; i++) {
189 UNICHAR_ID unichar_id = choice_lists_it[i].data()->unichar_id();
190 if (unichar_id != first_unichar_id) {
191 same_unichar =
false;
198 UNICHAR_ID merged_unichar_id = first_unichar_id;
200 choice_lists_it[0].data()->fonts();
201 float merged_min_xheight = choice_lists_it[0].data()->min_xheight();
202 float merged_max_xheight = choice_lists_it[0].data()->max_xheight();
203 float positive_yshift = 0, negative_yshift = 0;
204 int merged_script_id = choice_lists_it[0].data()->script_id();
207 float merged_rating = 0, merged_certainty = 0;
208 for (
int i = 0; i < num_frag_parts; i++) {
209 float rating = choice_lists_it[i].data()->rating();
210 float certainty = choice_lists_it[i].data()->certainty();
212 if (i == 0 || certainty < merged_certainty)
213 merged_certainty = certainty;
214 merged_rating += rating;
216 choice_lists_it[i].forward();
217 if (choice_lists_it[i].cycled_list())
220 choice_lists_it[i].data()->max_xheight(),
221 &merged_min_xheight, &merged_max_xheight);
222 float yshift = choice_lists_it[i].data()->yshift();
223 if (yshift > positive_yshift) positive_yshift = yshift;
224 if (yshift < negative_yshift) negative_yshift = yshift;
228 choice_lists_it[i].data()->fonts();
229 for (
int f = 0; f < frag_fonts.
size(); ++f) {
231 for (merged_f = 0; merged_f < merged_fonts.
size() &&
232 merged_fonts[merged_f].fontinfo_id != frag_fonts[f].fontinfo_id;
234 if (merged_f == merged_fonts.
size()) {
236 }
else if (merged_fonts[merged_f].score > frag_fonts[f].score) {
237 merged_fonts[merged_f].score = frag_fonts[f].score;
242 float merged_yshift = positive_yshift != 0
243 ? (negative_yshift != 0 ? 0 : positive_yshift)
254 merged_choice_it.add_to_end(choice);
262 if (merged_choice->empty())
263 delete merged_choice;
265 ratings->
put(row, column, merged_choice);
267 delete [] choice_lists_it;
286 BLOB_CHOICE_LIST *choice_lists) {
287 if (current_frag == num_frag_parts) {
289 choice_lists, ratings);
293 for (
inT16 x = current_row; x < num_blobs; x++) {
294 BLOB_CHOICE_LIST *choices = ratings->
get(current_row, x);
299 &choice_lists[current_frag]);
300 if (!choice_lists[current_frag].empty()) {
302 num_blobs, ratings, choice_lists);
303 choice_lists[current_frag].clear();
317 for (
inT16 start = 0; start < num_blobs; start++) {
321 ratings, choice_lists);
326 for (
inT16 x = 0; x < num_blobs; x++) {
327 for (
inT16 y = x; y < num_blobs; y++) {
328 BLOB_CHOICE_LIST *choices = ratings->
get(x, y);
329 if (choices !=
NULL) {
330 BLOB_CHOICE_IT choices_it(choices);
331 for (choices_it.mark_cycle_pt(); !choices_it.cycled_list();
332 choices_it.forward()) {
333 UNICHAR_ID choice_unichar_id = choices_it.data()->unichar_id();
337 delete choices_it.extract();
const UNICHAR_ID unichar_to_id(const char *const unichar_repr) const
int SortByUnicharID(const void *void1, const void *void2)
T get(int column, int row) const
void IntersectRange(const T &lower1, const T &upper1, T *lower2, T *upper2)
void put(int column, int row, const T &thing)
static const int kMaxChunks
void print_ratings_list(const char *msg, BLOB_CHOICE_LIST *ratings, const UNICHARSET ¤t_unicharset)
const CHAR_FRAGMENT * get_fragment(UNICHAR_ID unichar_id) const
void fill_filtered_fragment_list(BLOB_CHOICE_LIST *choices, int fragment_pos, int num_frag_parts, BLOB_CHOICE_LIST *filtered_choices)
virtual BLOB_CHOICE_LIST * classify_piece(const GenericVector< SEAM * > &seams, inT16 start, inT16 end, const char *description, TWERD *word, BlamerBundle *blamer_bundle)
void get_fragment_lists(inT16 current_frag, inT16 current_row, inT16 start, inT16 num_frag_parts, inT16 num_blobs, MATRIX *ratings, BLOB_CHOICE_LIST *choice_lists)
static void JoinPieces(const GenericVector< SEAM * > &seams, const GenericVector< TBLOB * > &blobs, int first, int last)
const char * get_unichar() const
GenericVector< TBLOB * > blobs
void merge_and_put_fragment_lists(inT16 row, inT16 column, inT16 num_frag_parts, BLOB_CHOICE_LIST *choice_lists, MATRIX *ratings)
void merge_fragments(MATRIX *ratings, inT16 num_blobs)
void set_fonts(const GenericVector< tesseract::ScoredFont > &fonts)
static void BreakPieces(const GenericVector< SEAM * > &seams, const GenericVector< TBLOB * > &blobs, int first, int last)
int SortByRating(const void *void1, const void *void2)
UNICHAR_ID unichar_id() const
BLOB_CHOICE_LIST * classify_blob(TBLOB *blob, const char *string, C_COL color, BlamerBundle *blamer_bundle)
void set_unichar_id(UNICHAR_ID newunichar_id)