59 const char* description,
64 White, blamer_bundle);
66 BLOB_CHOICE_IT bc_it(choices);
67 for (bc_it.mark_cycle_pt(); !bc_it.cycled_list(); bc_it.forward()) {
68 bc_it.data()->set_matrix_cell(start, end);
76 template<
class BLOB_CHOICE>
84 template<
class BLOB_CHOICE>
108 BLOB_CHOICE_LIST *filtered_choices) {
109 BLOB_CHOICE_IT filtered_choices_it(filtered_choices);
110 BLOB_CHOICE_IT choices_it(choices);
112 for (choices_it.mark_cycle_pt(); !choices_it.cycled_list();
113 choices_it.forward()) {
114 UNICHAR_ID choice_unichar_id = choices_it.data()->unichar_id();
117 if (frag != NULL && frag->
get_pos() == fragment_pos &&
124 filtered_choices_it.add_to_end(b);
128 filtered_choices->sort(SortByUnicharID<BLOB_CHOICE>);
139 inT16 num_frag_parts,
140 BLOB_CHOICE_LIST *choice_lists,
142 BLOB_CHOICE_IT *choice_lists_it =
new BLOB_CHOICE_IT[num_frag_parts];
144 for (
int i = 0; i < num_frag_parts; i++) {
145 choice_lists_it[i].set_to_list(&choice_lists[i]);
146 choice_lists_it[i].mark_cycle_pt();
149 BLOB_CHOICE_LIST *merged_choice = ratings->
get(row, column);
150 if (merged_choice == NULL)
151 merged_choice =
new BLOB_CHOICE_LIST;
153 bool end_of_list =
false;
154 BLOB_CHOICE_IT merged_choice_it(merged_choice);
155 while (!end_of_list) {
158 UNICHAR_ID max_unichar_id = choice_lists_it[0].data()->unichar_id();
159 for (
int i = 0; i < num_frag_parts; i++) {
160 UNICHAR_ID unichar_id = choice_lists_it[i].data()->unichar_id();
161 if (max_unichar_id < unichar_id) {
162 max_unichar_id = unichar_id;
168 for (
int i = 0; i < num_frag_parts; i++) {
169 UNICHAR_ID unichar_id = choice_lists_it[i].data()->unichar_id();
170 while (!choice_lists_it[i].cycled_list() &&
171 unichar_id < max_unichar_id) {
172 choice_lists_it[i].forward();
173 unichar_id = choice_lists_it[i].data()->unichar_id();
175 if (choice_lists_it[i].cycled_list()) {
185 UNICHAR_ID first_unichar_id = choice_lists_it[0].data()->unichar_id();
186 bool same_unichar =
true;
187 for (
int i = 1; i < num_frag_parts; i++) {
188 UNICHAR_ID unichar_id = choice_lists_it[i].data()->unichar_id();
189 if (unichar_id != first_unichar_id) {
190 same_unichar =
false;
197 UNICHAR_ID merged_unichar_id = first_unichar_id;
199 choice_lists_it[0].data()->fonts();
200 float merged_min_xheight = choice_lists_it[0].data()->min_xheight();
201 float merged_max_xheight = choice_lists_it[0].data()->max_xheight();
202 float positive_yshift = 0, negative_yshift = 0;
203 int merged_script_id = choice_lists_it[0].data()->script_id();
206 float merged_rating = 0, merged_certainty = 0;
207 for (
int i = 0; i < num_frag_parts; i++) {
208 float rating = choice_lists_it[i].data()->rating();
209 float certainty = choice_lists_it[i].data()->certainty();
211 if (i == 0 || certainty < merged_certainty)
212 merged_certainty = certainty;
213 merged_rating += rating;
215 choice_lists_it[i].forward();
216 if (choice_lists_it[i].cycled_list())
219 choice_lists_it[i].data()->max_xheight(),
220 &merged_min_xheight, &merged_max_xheight);
221 float yshift = choice_lists_it[i].data()->yshift();
222 if (yshift > positive_yshift) positive_yshift = yshift;
223 if (yshift < negative_yshift) negative_yshift = yshift;
227 choice_lists_it[i].data()->fonts();
228 for (
int f = 0; f < frag_fonts.
size(); ++f) {
230 for (merged_f = 0; merged_f < merged_fonts.
size() &&
231 merged_fonts[merged_f].fontinfo_id != frag_fonts[f].fontinfo_id;
233 if (merged_f == merged_fonts.
size()) {
235 }
else if (merged_fonts[merged_f].score > frag_fonts[f].score) {
236 merged_fonts[merged_f].score = frag_fonts[f].score;
241 float merged_yshift = positive_yshift != 0
242 ? (negative_yshift != 0 ? 0 : positive_yshift)
253 merged_choice_it.add_to_end(choice);
261 if (merged_choice->empty())
262 delete merged_choice;
264 ratings->
put(row, column, merged_choice);
266 delete [] choice_lists_it;
284 BLOB_CHOICE_LIST *choice_lists) {
285 if (current_frag == num_frag_parts) {
287 choice_lists, ratings);
291 for (
inT16 x = current_row; x < num_blobs; x++) {
292 BLOB_CHOICE_LIST *choices = ratings->
get(current_row, x);
297 &choice_lists[current_frag]);
298 if (!choice_lists[current_frag].empty()) {
300 num_blobs, ratings, choice_lists);
301 choice_lists[current_frag].clear();
315 for (
inT16 start = 0; start < num_blobs; start++) {
319 ratings, choice_lists);
324 for (
inT16 x = 0; x < num_blobs; x++) {
325 for (
inT16 y = x; y < num_blobs; y++) {
326 BLOB_CHOICE_LIST *choices = ratings->
get(x, y);
327 if (choices != NULL) {
328 BLOB_CHOICE_IT choices_it(choices);
329 for (choices_it.mark_cycle_pt(); !choices_it.cycled_list();
330 choices_it.forward()) {
331 UNICHAR_ID choice_unichar_id = choices_it.data()->unichar_id();
335 delete choices_it.extract();
void merge_and_put_fragment_lists(inT16 row, inT16 column, inT16 num_frag_parts, BLOB_CHOICE_LIST *choice_lists, MATRIX *ratings)
virtual BLOB_CHOICE_LIST * classify_piece(const GenericVector< SEAM *> &seams, inT16 start, inT16 end, const char *description, TWERD *word, BlamerBundle *blamer_bundle)
int SortByRating(const void *void1, const void *void2)
int SortByUnicharID(const void *void1, const void *void2)
GenericVector< TBLOB * > blobs
static void BreakPieces(const GenericVector< SEAM *> &seams, const GenericVector< TBLOB *> &blobs, int first, int last)
void fill_filtered_fragment_list(BLOB_CHOICE_LIST *choices, int fragment_pos, int num_frag_parts, BLOB_CHOICE_LIST *filtered_choices)
void IntersectRange(const T &lower1, const T &upper1, T *lower2, T *upper2)
static void JoinPieces(const GenericVector< SEAM *> &seams, const GenericVector< TBLOB *> &blobs, int first, int last)
void set_fonts(const GenericVector< tesseract::ScoredFont > &fonts)
UNICHAR_ID unichar_id() const
void put(ICOORD pos, const T &thing)
const char * get_unichar() const
void print_ratings_list(const char *msg, BLOB_CHOICE_LIST *ratings, const UNICHARSET ¤t_unicharset)
void set_unichar_id(UNICHAR_ID newunichar_id)
void merge_fragments(MATRIX *ratings, inT16 num_blobs)
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)
UNICHAR_ID TESS_API unichar_to_id(const char *const unichar_repr) const
BLOB_CHOICE_LIST * classify_blob(TBLOB *blob, const char *string, C_COL color, BlamerBundle *blamer_bundle)
static const int kMaxChunks
const CHAR_FRAGMENT * get_fragment(UNICHAR_ID unichar_id) const