SAMP_CHAN_T biquad_filter_chan( // Create filtered output sample for one channel SAMP_CHAN_T inp_chan_samp, // Unfiltered input sample at channel precision BIQUAD_CHAN_S * bq_chan_ps, // Pointer to structure containing current BiQuad data BIQUAD_COEF_S * bq_coef_ps // pointer to structure containing BiQuad coefficients for current channel ) // Return Filtered Output Sample { FILT_T inp_full_samp; // reduced precision input sample S32_T inp_redu_samp; // reduced precision input sample FILT_T out_full_samp; // full precision filtered output sample FILT_T clip_full_samp; // full precision sample, clipped to reduced precision range, returned to channel S32_T tap_cnt; // filter-tap counter inp_full_samp = (FILT_T)inp_chan_samp + (FILT_T)bq_chan_ps->inp_err; // Add-in Input diffusion error inp_redu_samp = (inp_full_samp + (FILT_T)HALF_HEAD) >> HEAD_BITS; // Compute reduced precision input sample bq_chan_ps->inp_err = (COEF_T)(inp_full_samp - ((FILT_T)inp_redu_samp << HEAD_BITS)); // Update diffusion error // Compute Intermediate IIR filter value bq_chan_ps->iir[0] = fix_point_mult( &(bq_coef_ps->a[0]) ,(FILT_T)inp_redu_samp ); for (tap_cnt=1; tap_cnt<NUM_FILT_TAPS; tap_cnt++) { bq_chan_ps->iir[0] -= fix_point_mult( &(bq_coef_ps->a[tap_cnt]) ,bq_chan_ps->iir[tap_cnt] ); } // for tap_cnt // Compute BiQuad filtered output value from intermediate IIR values bq_chan_ps->filt[0] = fix_point_mult( &(bq_coef_ps->b[0]) ,bq_chan_ps->iir[0] ); for (tap_cnt=1; tap_cnt<NUM_FILT_TAPS; tap_cnt++) { bq_chan_ps->filt[0] += fix_point_mult( &(bq_coef_ps->b[tap_cnt]) ,bq_chan_ps->iir[tap_cnt] ); } // for tap_cnt // Update previous stored results for (tap_cnt=(NUM_FILT_TAPS - 1); tap_cnt>0; tap_cnt--) { bq_chan_ps->iir[tap_cnt] = bq_chan_ps->iir[tap_cnt-1]; bq_chan_ps->filt[tap_cnt] = bq_chan_ps->filt[tap_cnt-1]; } // for tap_cnt out_full_samp = (bq_chan_ps->filt[0] << HEAD_BITS); // Compute full precision filtered output sample clip_full_samp = clip_sample( out_full_samp ); // Clip or full precision sample into channel range. return (SAMP_CHAN_T)clip_full_samp; } // biquad_filter_chan
void adapt_to_good_samples(WERD_RES *word, CHAR_SAMPLES_LIST *char_clusters, CHAR_SAMPLE_LIST *chars_waiting) { PBLOB_LIST *blobs = word->outword->blob_list (); PBLOB_IT blob_it(blobs); inT16 i; CHAR_SAMPLE *sample; CHAR_SAMPLES_IT c_it = char_clusters; CHAR_SAMPLE_IT cw_it = chars_waiting; float score; float best_score; char best_char; CHAR_SAMPLES *best_cluster; PIXROW_LIST *pixrow_list; PIXROW_IT pixrow_it; IMAGELINE *imlines; // lines of the image TBOX pix_box; // box of imlines // extent WERD copy_outword; // copy to denorm TBOX b_box; PBLOB_IT copy_blob_it; PIXROW *pixrow = NULL; static inT32 word_number = 0; #ifndef GRAPHICS_DISABLED ScrollView* demo_win = NULL; #endif inT32 resolution = page_image.get_res (); word_number++; if (tessedit_test_cluster_input) return; if (word->word->bounding_box ().height () > resolution / 3) return; if (char_clusters->length () == 0) { #ifndef SECURE_NAMES if (tessedit_cluster_debug) tprintf ("No clusters to use for adaption\n"); #endif return; } if (!cw_it.empty ()) { complete_clustering(char_clusters, chars_waiting); print_em_stats(char_clusters, chars_waiting); } if ((!word_adaptable (word, tessedit_cluster_adaption_mode) && word->reject_map.reject_count () != 0) || tessedit_mm_use_rejmap) { if (tessedit_cluster_debug) { tprintf ("\nChecking: \"%s\" MAP ", word->best_choice->string ().string ()); word->reject_map.print (debug_fp); tprintf ("\n"); } copy_outword = *(word->outword); copy_outword.baseline_denormalise (&word->denorm); copy_blob_it.set_to_list (copy_outword.blob_list ()); char_clip_word(©_outword, page_image, pixrow_list, imlines, pix_box); pixrow_it.set_to_list (pixrow_list); pixrow_it.move_to_first (); // For debugging only b_box = copy_outword.bounding_box (); pixrow = pixrow_it.data (); blob_it.move_to_first (); copy_blob_it.move_to_first (); for (i = 0; word->best_choice->string ()[i] != '\0'; i++, pixrow_it.forward (), blob_it.forward (), copy_blob_it.forward ()) { if (word->reject_map[i].recoverable () || (tessedit_mm_all_rejects && word->reject_map[i].rejected ())) { TBOX copy_box = copy_blob_it.data ()->bounding_box (); if (tessedit_cluster_debug) tprintf ("Sample %c to check found in %s, index %d\n", word->best_choice->string ()[i], word->best_choice->string ().string (), i); if (tessedit_demo_adaption) tprintf ("Sample %c to check found in %s (%d), index %d\n", word->best_choice->string ()[i], word->best_choice->string ().string (), word_number, i); sample = clip_sample (pixrow_it.data (), imlines, pix_box, copy_outword.flag (W_INVERSE), word->best_choice->string ()[i]); if (sample == NULL) { //Clip failed tprintf ("Unable to clip sample from %s, index %d\n", word->best_choice->string ().string (), i); #ifndef SECURE_NAMES if (tessedit_cluster_debug) tprintf ("Sample rejected (no sample)\n"); #endif word->reject_map[i].setrej_mm_reject (); continue; } best_score = MAX_INT32; best_char = '\0'; best_cluster = NULL; for (c_it.mark_cycle_pt (); !c_it.cycled_list (); c_it.forward ()) { if (c_it.data ()->character () != '\0') { score = c_it.data ()->match_score (sample); if (score < best_score) { best_cluster = c_it.data (); best_score = score; best_char = c_it.data ()->character (); } } } if (best_score > tessedit_cluster_t1) { #ifndef SECURE_NAMES if (tessedit_cluster_debug) tprintf ("Sample rejected (score %f)\n", best_score); if (tessedit_demo_adaption) tprintf ("Sample rejected (score %f)\n", best_score); #endif word->reject_map[i].setrej_mm_reject (); } else { if (word->best_choice->string ()[i] == best_char) { #ifndef SECURE_NAMES if (tessedit_cluster_debug) tprintf ("Sample accepted (score %f)\n", best_score); if (tessedit_demo_adaption) tprintf ("Sample accepted (score %f)\n", best_score); #endif if (tessedit_test_adaption) word->reject_map[i].setrej_minimal_rej_accept (); else word->reject_map[i].setrej_mm_accept (); } else { #ifndef SECURE_NAMES if (tessedit_cluster_debug) tprintf ("Sample rejected (char %c, score %f)\n", best_char, best_score); if (tessedit_demo_adaption) tprintf ("Sample rejected (char %c, score %f)\n", best_char, best_score); #endif word->reject_map[i].setrej_mm_reject (); } } if (tessedit_demo_adaption) { if (strcmp (imagebasename.string (), tessedit_demo_file.string ()) != 0 || word_number == tessedit_demo_word1 || word_number == tessedit_demo_word2) { #ifndef GRAPHICS_DISABLED demo_win = display_clip_image(©_outword, page_image, pixrow_list, pix_box); #endif demo_word = word_number; best_cluster->match_score (sample); demo_word = 0; } } } } delete[]imlines; // Free array of imlines delete pixrow_list; if (tessedit_cluster_debug) { tprintf ("\nFinal: \"%s\" MAP ", word->best_choice->string ().string ()); word->reject_map.print (debug_fp); tprintf ("\n"); } } }
void collect_characters_for_adaption(WERD_RES *word, CHAR_SAMPLES_LIST *char_clusters, CHAR_SAMPLE_LIST *chars_waiting) { PBLOB_LIST *blobs = word->outword->blob_list (); PBLOB_IT blob_it(blobs); inT16 i; CHAR_SAMPLE *sample; PIXROW_LIST *pixrow_list; PIXROW_IT pixrow_it; IMAGELINE *imlines; // lines of the image TBOX pix_box; // box of imlines // extent WERD copy_outword; // copy to denorm inT32 resolution = page_image.get_res (); if (word->word->bounding_box ().height () > resolution / 3) return; if (tessedit_demo_adaption) // Make sure not set tessedit_display_mm.set_value (FALSE); if ((word_adaptable (word, tessedit_cluster_adaption_mode) && word->reject_map.reject_count () == 0) || tessedit_mm_use_rejmap) { if (tessedit_test_cluster_input && !tessedit_mm_use_rejmap) return; // Reject map set to acceptable /* Collect information about good matches */ copy_outword = *(word->outword); copy_outword.baseline_denormalise (&word->denorm); char_clip_word(©_outword, page_image, pixrow_list, imlines, pix_box); pixrow_it.set_to_list (pixrow_list); pixrow_it.move_to_first (); blob_it.move_to_first (); for (i = 0; word->best_choice->string ()[i] != '\0'; i++, pixrow_it.forward (), blob_it.forward ()) { if (!(tessedit_mm_use_non_adaption_set && STRING (tessedit_non_adaption_set).contains (word-> best_choice-> string ()[i])) || (tessedit_mm_use_rejmap && word->reject_map[i].accepted ())) { #ifndef SECURE_NAMES if (tessedit_cluster_debug) tprintf ("Sample %c for adaption found in %s, index %d\n", word->best_choice->string ()[i], word->best_choice->string ().string (), i); #endif sample = clip_sample (pixrow_it.data (), imlines, pix_box, copy_outword.flag (W_INVERSE), word->best_choice->string ()[i]); if (sample == NULL) { //Clip failed #ifndef SECURE_NAMES tprintf ("Unable to clip sample from %s, index %d\n", word->best_choice->string ().string (), i); #endif continue; } cluster_sample(sample, char_clusters, chars_waiting); } } delete[]imlines; // Free array of imlines delete pixrow_list; } else if (tessedit_test_cluster_input && !tessedit_mm_use_rejmap) // Set word to all rejects word->reject_map.rej_word_tess_failure (); }
void collect_ems_for_adaption(WERD_RES *word, CHAR_SAMPLES_LIST *char_clusters, CHAR_SAMPLE_LIST *chars_waiting) { PBLOB_LIST *blobs = word->outword->blob_list (); PBLOB_IT blob_it(blobs); inT16 i; CHAR_SAMPLE *sample; PIXROW_LIST *pixrow_list; PIXROW_IT pixrow_it; IMAGELINE *imlines; // lines of the image TBOX pix_box; // box of imlines // extent WERD copy_outword; // copy to denorm PBLOB_IT copy_blob_it; OUTLINE_IT copy_outline_it; inT32 resolution = page_image.get_res (); if (tessedit_reject_ems || tessedit_reject_suspect_ems) return; // Do nothing if (word->word->bounding_box ().height () > resolution / 3) return; if (tessedit_demo_adaption) // Make sure not set tessedit_display_mm.set_value (FALSE); if (word_adaptable (word, tessedit_em_adaption_mode) && word->reject_map.reject_count () == 0 && (strchr (word->best_choice->string ().string (), 'm') != NULL || (tessedit_process_rns && strstr (word->best_choice->string ().string (), "rn") != NULL))) { if (tessedit_process_rns && strstr (word->best_choice->string ().string (), "rn") != NULL) { copy_outword = *(word->outword); copy_blob_it.set_to_list (copy_outword.blob_list ()); i = 0; while (word->best_choice->string ()[i] != '\0') { if (word->best_choice->string ()[i] == 'r' && word->best_choice->string ()[i + 1] == 'n') { copy_outline_it.set_to_list (copy_blob_it.data ()-> out_list ()); copy_outline_it.add_list_after (copy_blob_it. data_relative (1)-> out_list ()); copy_blob_it.forward (); delete (copy_blob_it.extract ()); i++; } copy_blob_it.forward (); i++; } } else copy_outword = *(word->outword); copy_outword.baseline_denormalise (&word->denorm); char_clip_word(©_outword, page_image, pixrow_list, imlines, pix_box); pixrow_it.set_to_list (pixrow_list); pixrow_it.move_to_first (); blob_it.move_to_first (); for (i = 0; word->best_choice->string ()[i] != '\0'; i++, pixrow_it.forward (), blob_it.forward ()) { if (word->best_choice->string ()[i] == 'm' || (word->best_choice->string ()[i] == 'r' && word->best_choice->string ()[i + 1] == 'n')) { #ifndef SECURE_NAMES if (tessedit_cluster_debug) tprintf ("Sample %c for adaption found in %s, index %d\n", word->best_choice->string ()[i], word->best_choice->string ().string (), i); #endif if (tessedit_matrix_match) { sample = clip_sample (pixrow_it.data (), imlines, pix_box, copy_outword.flag (W_INVERSE), word->best_choice->string ()[i]); if (sample == NULL) { //Clip failed #ifndef SECURE_NAMES tprintf ("Unable to clip sample from %s, index %d\n", word->best_choice->string ().string (), i); #endif if (word->best_choice->string ()[i] == 'r') i++; continue; } } else sample = new CHAR_SAMPLE (blob_it.data (), &word->denorm, word->best_choice->string ()[i]); cluster_sample(sample, char_clusters, chars_waiting); if (word->best_choice->string ()[i] == 'r') i++; // Skip next character } } delete[]imlines; // Free array of imlines delete pixrow_list; } }