/********************************************************************** * File: makerow.h (Formerly makerows.h) * Description: Code to arrange blobs into rows of text. * Author: Ray Smith * Created: Mon Sep 21 14:34:48 BST 1992 * * (C) Copyright 1992, Hewlett-Packard Ltd. ** Licensed under the Apache License, Version 2.0 (the "License"); ** you may not use this file except in compliance with the License. ** You may obtain a copy of the License at ** http://www.apache.org/licenses/LICENSE-2.0 ** Unless required by applicable law or agreed to in writing, software ** distributed under the License is distributed on an "AS IS" BASIS, ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ** See the License for the specific language governing permissions and ** limitations under the License. * **********************************************************************/ #ifndef MAKEROW_H #define MAKEROW_H #include "varable.h" #include "ocrblock.h" #include "tessclas.h" #include "blobbox.h" #include "statistc.h" #include "notdll.h" #include "tesseractclass.h" enum OVERLAP_STATE { ASSIGN, //assign it to row REJECT, //reject it - dual overlap NEW_ROW }; enum ROW_CATEGORY { ROW_ASCENDERS_FOUND, ROW_DESCENDERS_FOUND, ROW_UNKNOWN, ROW_INVALID, }; extern BOOL_VAR_H (textord_show_initial_rows, FALSE, "Display row accumulation"); extern BOOL_VAR_H (textord_show_parallel_rows, FALSE, "Display page correlated rows"); extern BOOL_VAR_H (textord_show_expanded_rows, FALSE, "Display rows after expanding"); extern BOOL_VAR_H (textord_show_final_rows, FALSE, "Display rows after final fitting"); extern BOOL_VAR_H (textord_show_final_blobs, FALSE, "Display blob bounds after pre-ass"); extern BOOL_VAR_H (textord_test_landscape, FALSE, "Tests refer to land/port"); extern BOOL_VAR_H (textord_parallel_baselines, TRUE, "Force parallel baselines"); extern BOOL_VAR_H (textord_straight_baselines, FALSE, "Force straight baselines"); extern BOOL_VAR_H (textord_quadratic_baselines, FALSE, "Use quadratic splines"); extern BOOL_VAR_H (textord_old_baselines, TRUE, "Use old baseline algorithm"); extern BOOL_VAR_H (textord_old_xheight, TRUE, "Use old xheight algorithm"); extern BOOL_VAR_H (textord_fix_xheight_bug, TRUE, "Use spline baseline"); extern BOOL_VAR_H (textord_fix_makerow_bug, TRUE, "Prevent multiple baselines"); extern BOOL_VAR_H (textord_cblob_blockocc, TRUE, "Use new projection for underlines"); extern BOOL_VAR_H (textord_debug_xheights, FALSE, "Test xheight algorithms"); extern INT_VAR_H (textord_test_x, 0, "coord of test pt"); extern INT_VAR_H (textord_test_y, 0, "coord of test pt"); extern INT_VAR_H (textord_min_blobs_in_row, 4, "Min blobs before gradient counted"); extern INT_VAR_H (textord_spline_minblobs, 8, "Min blobs in each spline segment"); extern INT_VAR_H (textord_spline_medianwin, 6, "Size of window for spline segmentation"); extern INT_VAR_H (textord_min_xheight, 10, "Min credible pixel xheight"); extern double_VAR_H (textord_spline_shift_fraction, 0.02, "Fraction of line spacing for quad"); extern double_VAR_H (textord_spline_outlier_fraction, 0.1, "Fraction of line spacing for outlier"); extern double_VAR_H (textord_skew_ile, 0.5, "Ile of gradients for page skew"); extern double_VAR_H (textord_skew_lag, 0.75, "Lag for skew on row accumulation"); extern double_VAR_H (textord_linespace_iqrlimit, 0.2, "Max iqr/median for linespace"); extern double_VAR_H (textord_width_limit, 8, "Max width of blobs to make rows"); extern double_VAR_H (textord_chop_width, 1.5, "Max width before chopping"); extern double_VAR_H (textord_merge_desc, 0.25, "Fraction of linespace for desc drop"); extern double_VAR_H (textord_merge_x, 0.5, "Fraction of linespace for x height"); extern double_VAR_H (textord_merge_asc, 0.25, "Fraction of linespace for asc height"); extern double_VAR_H (textord_minxh, 0.25, "fraction of linesize for min xheight"); extern double_VAR_H (textord_min_linesize, 1.25, "* blob height for initial linesize"); extern double_VAR_H (textord_excess_blobsize, 1.3, "New row made if blob makes row this big"); extern double_VAR_H (textord_occupancy_threshold, 0.4, "Fraction of neighbourhood"); extern double_VAR_H (textord_underline_width, 2.0, "Multiple of line_size for underline"); extern double_VAR_H(textord_min_blob_height_fraction, 0.75, "Min blob height/top to include blob top into xheight stats"); extern double_VAR_H (textord_xheight_mode_fraction, 0.4, "Min pile height to make xheight"); extern double_VAR_H (textord_ascheight_mode_fraction, 0.15, "Min pile height to make ascheight"); extern double_VAR_H (textord_ascx_ratio_min, 1.2, "Min cap/xheight"); extern double_VAR_H (textord_ascx_ratio_max, 1.7, "Max cap/xheight"); extern double_VAR_H (textord_descx_ratio_min, 0.15, "Min desc/xheight"); extern double_VAR_H (textord_descx_ratio_max, 0.6, "Max desc/xheight"); extern double_VAR_H (textord_xheight_error_margin, 0.1, "Accepted variation"); inline void get_min_max_xheight(double block_linesize, int *min_height, int *max_height) { *min_height = static_cast(floor(block_linesize * textord_minxh)); if (*min_height < textord_min_xheight) *min_height = textord_min_xheight; *max_height = static_cast(ceil(block_linesize * 3)); } inline ROW_CATEGORY get_row_category(const TO_ROW *row) { if (row->xheight <= 0) return ROW_INVALID; return (row->ascrise > 0) ? ROW_ASCENDERS_FOUND : (row->descdrop != 0) ? ROW_DESCENDERS_FOUND : ROW_UNKNOWN; } inline bool within_error_margin(float test, float num, float margin) { return (test >= num * (1 - margin) && test <= num * (1 + margin)); } void fill_heights(TO_ROW *row, float gradient, int min_height, int max_height, STATS *heights, STATS *floating_heights); float make_single_row(ICOORD page_tr, TO_BLOCK* block, TO_BLOCK_LIST* blocks, tesseract::Tesseract* tess); float make_rows( //make rows ICOORD page_tr, //top right BLOCK_LIST *blocks, //block list TO_BLOCK_LIST *land_blocks, //rotated for landscape TO_BLOCK_LIST *port_blocks, //output list tesseract::Tesseract* tess ); void make_initial_textrows( //find lines ICOORD page_tr, TO_BLOCK *block, //block to do FCOORD rotation, //for drawing BOOL8 testing_on //correct orientation ); void fit_lms_line( //sort function TO_ROW *row //row to fit ); void compute_page_skew( //get average gradient TO_BLOCK_LIST *blocks, //list of blocks float &page_m, //average gradient float &page_err //average error ); void cleanup_rows( //find lines ICOORD page_tr, //top right TO_BLOCK *block, //block to do float gradient, //gradient to fit FCOORD rotation, //for drawing inT32 block_edge, //edge of block BOOL8 testing_on, //correct orientation tesseract::Tesseract* tess ); void delete_non_dropout_rows( //find lines TO_BLOCK *block, //block to do float gradient, //global skew FCOORD rotation, //deskew vector inT32 block_edge, //left edge BOOL8 testing_on //correct orientation ); BOOL8 find_best_dropout_row( //find neighbours TO_ROW *row, //row to test inT32 distance, //dropout dist float dist_limit, //threshold distance inT32 line_index, //index of row TO_ROW_IT *row_it, //current position BOOL8 testing_on //correct orientation ); TBOX deskew_block_coords( //block box TO_BLOCK *block, //block to do float gradient //global skew ); void compute_line_occupation( //project blobs TO_BLOCK *block, //block to do float gradient, //global skew inT32 min_y, //min coord in block inT32 max_y, //in block inT32 *occupation, //output projection inT32 *deltas //derivative ); void compute_occupation_threshold( //project blobs inT32 low_window, //below result point inT32 high_window, //above result point inT32 line_count, //array sizes inT32 *occupation, //input projection inT32 *thresholds //output thresholds ); void compute_dropout_distances( //project blobs inT32 *occupation, //input projection inT32 *thresholds, //output thresholds inT32 line_count //array sizes ); void expand_rows( //find lines ICOORD page_tr, //top right TO_BLOCK *block, //block to do float gradient, //gradient to fit FCOORD rotation, //for drawing inT32 block_edge, //edge of block BOOL8 testing_on //correct orientation ); void adjust_row_limits( //tidy limits TO_BLOCK *block //block to do ); void compute_row_stats( //find lines TO_BLOCK *block, //block to do BOOL8 testing_on //correct orientation ); void compute_block_xheight( //find lines TO_BLOCK *block, //block to do float gradient, //global skew tesseract::Tesseract* tess ); float median_block_xheight( //find lines TO_BLOCK *block, //block to do float gradient //global skew ); void compute_row_xheight( //find lines TO_ROW *row, //row to do float gradient, //global skew int block_height, //a guess of block xheight tesseract::Tesseract* tess ); int compute_xheight_from_modes( STATS *heights, STATS *floating_heights, int min_height, int max_height, float *xheight, float *ascrise); inT32 compute_row_descdrop( //find lines TO_ROW *row, //row to do float gradient, // global skew int xheight_blob_count, STATS *heights ); inT32 compute_height_modes( //find lines STATS *heights, //stats to search inT32 min_height, //bottom of range inT32 max_height, //top of range inT32 *modes, //output array inT32 maxmodes //size of modes ); void correct_row_xheight( //fix bad values TO_ROW *row, //row to fix float xheight, //average values float ascrise, float descdrop); void separate_underlines( //make rough chars TO_BLOCK *block, //block to do float gradient, //skew angle FCOORD rotation, //inverse landscape BOOL8 testing_on //correct orientation ); void pre_associate_blobs( //make rough chars ICOORD page_tr, //top right TO_BLOCK *block, //block to do FCOORD rotation, //inverse landscape BOOL8 testing_on //correct orientation ); void fit_parallel_rows( //find lines TO_BLOCK *block, //block to do float gradient, //gradient to fit FCOORD rotation, //for drawing inT32 block_edge, //edge of block BOOL8 testing_on //correct orientation ); void fit_parallel_lms( //sort function float gradient, //forced gradient TO_ROW *row //row to fit ); void make_spline_rows( //find lines TO_BLOCK *block, //block to do float gradient, //gradient to fit FCOORD rotation, //for drawing inT32 block_edge, //edge of block BOOL8 testing_on, //correct orientation tesseract::Tesseract* tess ); void make_baseline_spline( //sort function TO_ROW *row, //row to fit TO_BLOCK *block //block it came from ); BOOL8 segment_baseline ( //split baseline TO_ROW * row, //row to fit TO_BLOCK * block, //block it came from inT32 & segments, //no fo segments inT32 xstarts[] //coords of segments ); double *linear_spline_baseline ( //split baseline TO_ROW * row, //row to fit TO_BLOCK * block, //block it came from inT32 & segments, //no fo segments inT32 xstarts[] //coords of segments ); void assign_blobs_to_rows( //find lines TO_BLOCK *block, //block to do float *gradient, //block skew int pass, //identification BOOL8 reject_misses, //chuck big ones out BOOL8 make_new_rows, //add rows for unmatched BOOL8 drawing_skew //draw smoothed skew ); //find best row OVERLAP_STATE most_overlapping_row(TO_ROW_IT *row_it, //iterator TO_ROW *&best_row, //output row float top, //top of blob float bottom, //bottom of blob float rowsize, //max row size BOOL8 testing_blob //test stuff ); int blob_x_order( //sort function const void *item1, //items to compare const void *item2); int row_y_order( //sort function const void *item1, //items to compare const void *item2); int row_spacing_order( //sort function const void *item1, //items to compare const void *item2); void mark_repeated_chars(TO_ROW *row, float block_xheight, tesseract::Tesseract *tess); #endif