tesseract  5.0.0
tesseractclass.cpp
Go to the documentation of this file.
1 // File: tesseractclass.cpp
3 // Description: The Tesseract class. It holds/owns everything needed
4 // to run Tesseract on a single language, and also a set of
5 // sub-Tesseracts to run sub-languages. For thread safety, *every*
6 // variable that was previously global or static (except for
7 // constant data, and some visual debugging flags) has been moved
8 // in here, directly, or indirectly.
9 // This makes it safe to run multiple Tesseracts in different
10 // threads in parallel, and keeps the different language
11 // instances separate.
12 // Some global functions remain, but they are isolated re-entrant
13 // functions that operate on their arguments. Functions that work
14 // on variable data have been moved to an appropriate class based
15 // mostly on the directory hierarchy. For more information see
16 // slide 6 of "2ArchitectureAndDataStructures" in
17 // https://drive.google.com/file/d/0B7l10Bj_LprhbUlIUFlCdGtDYkE/edit?usp=sharing
18 // Some global data and related functions still exist in the
19 // training-related code, but they don't interfere with normal
20 // recognition operation.
21 // Author: Ray Smith
22 //
23 // (C) Copyright 2008, Google Inc.
24 // Licensed under the Apache License, Version 2.0 (the "License");
25 // you may not use this file except in compliance with the License.
26 // You may obtain a copy of the License at
27 // http://www.apache.org/licenses/LICENSE-2.0
28 // Unless required by applicable law or agreed to in writing, software
29 // distributed under the License is distributed on an "AS IS" BASIS,
30 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
31 // See the License for the specific language governing permissions and
32 // limitations under the License.
33 //
35 
36 // Include automatically generated configuration file if running autoconf.
37 #ifdef HAVE_CONFIG_H
38 # include "config_auto.h"
39 #endif
40 
41 #include "tesseractclass.h"
42 
43 #include <allheaders.h>
44 #include "edgblob.h"
45 #ifndef DISABLED_LEGACY_ENGINE
46 # include "equationdetect.h"
47 #endif
48 #include "lstmrecognizer.h"
49 #include "thresholder.h" // for ThresholdMethod
50 
51 namespace tesseract {
52 
54  : BOOL_MEMBER(tessedit_resegment_from_boxes, false,
55  "Take segmentation and labeling from box file", this->params())
56  , BOOL_MEMBER(tessedit_resegment_from_line_boxes, false,
57  "Conversion of word/line box file to char box file", this->params())
58  , BOOL_MEMBER(tessedit_train_from_boxes, false, "Generate training data from boxed chars",
59  this->params())
60  , BOOL_MEMBER(tessedit_make_boxes_from_boxes, false, "Generate more boxes from boxed chars",
61  this->params())
62  , BOOL_MEMBER(tessedit_train_line_recognizer, false,
63  "Break input into lines and remap boxes if present", this->params())
64  , BOOL_MEMBER(tessedit_dump_pageseg_images, false,
65  "Dump intermediate images made during page segmentation", this->params())
66  , BOOL_MEMBER(tessedit_do_invert, true, "Try inverting the image in `LSTMRecognizeWord`",
67  this->params())
68  ,
69  // The default for pageseg_mode is the old behaviour, so as not to
70  // upset anything that relies on that.
71  INT_MEMBER(tessedit_pageseg_mode, PSM_SINGLE_BLOCK,
72  "Page seg mode: 0=osd only, 1=auto+osd, 2=auto_only, 3=auto, "
73  "4=column,"
74  " 5=block_vert, 6=block, 7=line, 8=word, 9=word_circle, 10=char,"
75  "11=sparse_text, 12=sparse_text+osd, 13=raw_line"
76  " (Values from PageSegMode enum in tesseract/publictypes.h)",
77  this->params())
78  , INT_MEMBER(thresholding_method,
79  static_cast<int>(ThresholdMethod::Otsu),
80  "Thresholding method: 0 = Otsu, 1 = LeptonicaOtsu, 2 = "
81  "Sauvola",
82  this->params())
83  , BOOL_MEMBER(thresholding_debug, false,
84  "Debug the thresholding process",
85  this->params())
86  , double_MEMBER(thresholding_window_size, 0.33,
87  "Window size for measuring local statistics (to be "
88  "multiplied by image DPI). "
89  "This parameter is used by the Sauvola thresolding method",
90  this->params())
91  , double_MEMBER(thresholding_kfactor, 0.34,
92  "Factor for reducing threshold due to variance. "
93  "This parameter is used by the Sauvola thresolding method."
94  " Normal range: 0.2-0.5",
95  this->params())
96  , double_MEMBER(thresholding_tile_size, 0.33,
97  "Desired tile size (to be multiplied by image DPI). "
98  "This parameter is used by the LeptonicaOtsu thresolding "
99  "method",
100  this->params())
101  , double_MEMBER(thresholding_smooth_kernel_size, 0.0,
102  "Size of convolution kernel applied to threshold array "
103  "(to be multiplied by image DPI). Use 0 for no smoothing. "
104  "This parameter is used by the LeptonicaOtsu thresolding "
105  "method",
106  this->params())
107  , double_MEMBER(thresholding_score_fraction, 0.1,
108  "Fraction of the max Otsu score. "
109  "This parameter is used by the LeptonicaOtsu thresolding "
110  "method. "
111  "For standard Otsu use 0.0, otherwise 0.1 is recommended",
112  this->params())
113  , INT_INIT_MEMBER(tessedit_ocr_engine_mode, tesseract::OEM_DEFAULT,
114  "Which OCR engine(s) to run (Tesseract, LSTM, both)."
115  " Defaults to loading and running the most accurate"
116  " available.",
117  this->params())
118  , STRING_MEMBER(tessedit_char_blacklist, "", "Blacklist of chars not to recognize",
119  this->params())
120  , STRING_MEMBER(tessedit_char_whitelist, "", "Whitelist of chars to recognize", this->params())
121  , STRING_MEMBER(tessedit_char_unblacklist, "",
122  "List of chars to override tessedit_char_blacklist", this->params())
123  , BOOL_MEMBER(tessedit_ambigs_training, false, "Perform training for ambiguities",
124  this->params())
125  , INT_MEMBER(pageseg_devanagari_split_strategy, tesseract::ShiroRekhaSplitter::NO_SPLIT,
126  "Whether to use the top-line splitting process for Devanagari "
127  "documents while performing page-segmentation.",
128  this->params())
129  , INT_MEMBER(ocr_devanagari_split_strategy, tesseract::ShiroRekhaSplitter::NO_SPLIT,
130  "Whether to use the top-line splitting process for Devanagari "
131  "documents while performing ocr.",
132  this->params())
133  , STRING_MEMBER(tessedit_write_params_to_file, "", "Write all parameters to the given file.",
134  this->params())
135  , BOOL_MEMBER(tessedit_adaption_debug, false,
136  "Generate and print debug"
137  " information for adaption",
138  this->params())
139  , INT_MEMBER(bidi_debug, 0, "Debug level for BiDi", this->params())
140  , INT_MEMBER(applybox_debug, 1, "Debug level", this->params())
141  , INT_MEMBER(applybox_page, 0, "Page number to apply boxes from", this->params())
142  , STRING_MEMBER(applybox_exposure_pattern, ".exp",
143  "Exposure value follows"
144  " this pattern in the image filename. The name of the image"
145  " files are expected to be in the form"
146  " [lang].[fontname].exp[num].tif",
147  this->params())
148  , BOOL_MEMBER(applybox_learn_chars_and_char_frags_mode, false,
149  "Learn both character fragments (as is done in the"
150  " special low exposure mode) as well as unfragmented"
151  " characters.",
152  this->params())
153  , BOOL_MEMBER(applybox_learn_ngrams_mode, false,
154  "Each bounding box"
155  " is assumed to contain ngrams. Only learn the ngrams"
156  " whose outlines overlap horizontally.",
157  this->params())
158  , BOOL_MEMBER(tessedit_display_outwords, false, "Draw output words", this->params())
159  , BOOL_MEMBER(tessedit_dump_choices, false, "Dump char choices", this->params())
160  , BOOL_MEMBER(tessedit_timing_debug, false, "Print timing stats", this->params())
161  , BOOL_MEMBER(tessedit_fix_fuzzy_spaces, true, "Try to improve fuzzy spaces", this->params())
162  , BOOL_MEMBER(tessedit_unrej_any_wd, false, "Don't bother with word plausibility",
163  this->params())
164  , BOOL_MEMBER(tessedit_fix_hyphens, true, "Crunch double hyphens?", this->params())
165  , BOOL_MEMBER(tessedit_enable_doc_dict, true, "Add words to the document dictionary",
166  this->params())
167  , BOOL_MEMBER(tessedit_debug_fonts, false, "Output font info per char", this->params())
168  , INT_MEMBER(tessedit_font_id, 0, "Font ID to use or zero", this->params())
169  , BOOL_MEMBER(tessedit_debug_block_rejection, false, "Block and Row stats", this->params())
170  , BOOL_MEMBER(tessedit_enable_bigram_correction, true,
171  "Enable correction based on the word bigram dictionary.", this->params())
172  , BOOL_MEMBER(tessedit_enable_dict_correction, false,
173  "Enable single word correction based on the dictionary.", this->params())
174  , INT_MEMBER(tessedit_bigram_debug, 0, "Amount of debug output for bigram correction.",
175  this->params())
176  , BOOL_MEMBER(enable_noise_removal, true,
177  "Remove and conditionally reassign small outlines when they"
178  " confuse layout analysis, determining diacritics vs noise",
179  this->params())
180  , INT_MEMBER(debug_noise_removal, 0, "Debug reassignment of small outlines", this->params())
181  ,
182  // Worst (min) certainty, for which a diacritic is allowed to make the
183  // base
184  // character worse and still be included.
185  double_MEMBER(noise_cert_basechar, -8.0, "Hingepoint for base char certainty", this->params())
186  ,
187  // Worst (min) certainty, for which a non-overlapping diacritic is allowed
188  // to make the base character worse and still be included.
189  double_MEMBER(noise_cert_disjoint, -1.0, "Hingepoint for disjoint certainty", this->params())
190  ,
191  // Worst (min) certainty, for which a diacritic is allowed to make a new
192  // stand-alone blob.
193  double_MEMBER(noise_cert_punc, -3.0, "Threshold for new punc char certainty", this->params())
194  ,
195  // Factor of certainty margin for adding diacritics to not count as worse.
196  double_MEMBER(noise_cert_factor, 0.375, "Scaling on certainty diff from Hingepoint",
197  this->params())
198  , INT_MEMBER(noise_maxperblob, 8, "Max diacritics to apply to a blob", this->params())
199  , INT_MEMBER(noise_maxperword, 16, "Max diacritics to apply to a word", this->params())
200  , INT_MEMBER(debug_x_ht_level, 0, "Reestimate debug", this->params())
201  , STRING_MEMBER(chs_leading_punct, "('`\"", "Leading punctuation", this->params())
202  , STRING_MEMBER(chs_trailing_punct1, ").,;:?!", "1st Trailing punctuation", this->params())
203  , STRING_MEMBER(chs_trailing_punct2, ")'`\"", "2nd Trailing punctuation", this->params())
204  , double_MEMBER(quality_rej_pc, 0.08, "good_quality_doc lte rejection limit", this->params())
205  , double_MEMBER(quality_blob_pc, 0.0, "good_quality_doc gte good blobs limit", this->params())
206  , double_MEMBER(quality_outline_pc, 1.0, "good_quality_doc lte outline error limit",
207  this->params())
208  , double_MEMBER(quality_char_pc, 0.95, "good_quality_doc gte good char limit", this->params())
209  , INT_MEMBER(quality_min_initial_alphas_reqd, 2, "alphas in a good word", this->params())
210  , INT_MEMBER(tessedit_tess_adaption_mode, 0x27, "Adaptation decision algorithm for tess",
211  this->params())
212  , BOOL_MEMBER(tessedit_minimal_rej_pass1, false, "Do minimal rejection on pass 1 output",
213  this->params())
214  , BOOL_MEMBER(tessedit_test_adaption, false, "Test adaption criteria", this->params())
215  , BOOL_MEMBER(test_pt, false, "Test for point", this->params())
216  , double_MEMBER(test_pt_x, 99999.99, "xcoord", this->params())
217  , double_MEMBER(test_pt_y, 99999.99, "ycoord", this->params())
218  , INT_MEMBER(multilang_debug_level, 0, "Print multilang debug info.", this->params())
219  , INT_MEMBER(paragraph_debug_level, 0, "Print paragraph debug info.", this->params())
220  , BOOL_MEMBER(paragraph_text_based, true,
221  "Run paragraph detection on the post-text-recognition "
222  "(more accurate)",
223  this->params())
224  , BOOL_MEMBER(lstm_use_matrix, 1, "Use ratings matrix/beam search with lstm", this->params())
225  , STRING_MEMBER(outlines_odd, "%| ", "Non standard number of outlines", this->params())
226  , STRING_MEMBER(outlines_2, "ij!?%\":;", "Non standard number of outlines", this->params())
227  , BOOL_MEMBER(tessedit_good_quality_unrej, true, "Reduce rejection on good docs",
228  this->params())
229  , BOOL_MEMBER(tessedit_use_reject_spaces, true, "Reject spaces?", this->params())
230  , double_MEMBER(tessedit_reject_doc_percent, 65.00, "%rej allowed before rej whole doc",
231  this->params())
232  , double_MEMBER(tessedit_reject_block_percent, 45.00, "%rej allowed before rej whole block",
233  this->params())
234  , double_MEMBER(tessedit_reject_row_percent, 40.00, "%rej allowed before rej whole row",
235  this->params())
236  , double_MEMBER(tessedit_whole_wd_rej_row_percent, 70.00,
237  "Number of row rejects in whole word rejects"
238  " which prevents whole row rejection",
239  this->params())
240  , BOOL_MEMBER(tessedit_preserve_blk_rej_perfect_wds, true,
241  "Only rej partially rejected words in block rejection", this->params())
242  , BOOL_MEMBER(tessedit_preserve_row_rej_perfect_wds, true,
243  "Only rej partially rejected words in row rejection", this->params())
244  , BOOL_MEMBER(tessedit_dont_blkrej_good_wds, false, "Use word segmentation quality metric",
245  this->params())
246  , BOOL_MEMBER(tessedit_dont_rowrej_good_wds, false, "Use word segmentation quality metric",
247  this->params())
248  , INT_MEMBER(tessedit_preserve_min_wd_len, 2, "Only preserve wds longer than this",
249  this->params())
250  , BOOL_MEMBER(tessedit_row_rej_good_docs, true, "Apply row rejection to good docs",
251  this->params())
252  , double_MEMBER(tessedit_good_doc_still_rowrej_wd, 1.1,
253  "rej good doc wd if more than this fraction rejected", this->params())
254  , BOOL_MEMBER(tessedit_reject_bad_qual_wds, true, "Reject all bad quality wds", this->params())
255  , BOOL_MEMBER(tessedit_debug_doc_rejection, false, "Page stats", this->params())
256  , BOOL_MEMBER(tessedit_debug_quality_metrics, false, "Output data to debug file",
257  this->params())
258  , BOOL_MEMBER(bland_unrej, false, "unrej potential with no checks", this->params())
259  , double_MEMBER(quality_rowrej_pc, 1.1, "good_quality_doc gte good char limit", this->params())
260  , BOOL_MEMBER(unlv_tilde_crunching, false, "Mark v.bad words for tilde crunch", this->params())
261  , BOOL_MEMBER(hocr_font_info, false, "Add font info to hocr output", this->params())
262  , BOOL_MEMBER(hocr_char_boxes, false, "Add coordinates for each character to hocr output",
263  this->params())
264  , BOOL_MEMBER(crunch_early_merge_tess_fails, true, "Before word crunch?", this->params())
265  , BOOL_MEMBER(crunch_early_convert_bad_unlv_chs, false, "Take out ~^ early?", this->params())
266  , double_MEMBER(crunch_terrible_rating, 80.0, "crunch rating lt this", this->params())
267  , BOOL_MEMBER(crunch_terrible_garbage, true, "As it says", this->params())
268  , double_MEMBER(crunch_poor_garbage_cert, -9.0, "crunch garbage cert lt this", this->params())
269  , double_MEMBER(crunch_poor_garbage_rate, 60, "crunch garbage rating lt this", this->params())
270  , double_MEMBER(crunch_pot_poor_rate, 40, "POTENTIAL crunch rating lt this", this->params())
271  , double_MEMBER(crunch_pot_poor_cert, -8.0, "POTENTIAL crunch cert lt this", this->params())
272  , double_MEMBER(crunch_del_rating, 60, "POTENTIAL crunch rating lt this", this->params())
273  , double_MEMBER(crunch_del_cert, -10.0, "POTENTIAL crunch cert lt this", this->params())
274  , double_MEMBER(crunch_del_min_ht, 0.7, "Del if word ht lt xht x this", this->params())
275  , double_MEMBER(crunch_del_max_ht, 3.0, "Del if word ht gt xht x this", this->params())
276  , double_MEMBER(crunch_del_min_width, 3.0, "Del if word width lt xht x this", this->params())
277  , double_MEMBER(crunch_del_high_word, 1.5, "Del if word gt xht x this above bl", this->params())
278  , double_MEMBER(crunch_del_low_word, 0.5, "Del if word gt xht x this below bl", this->params())
279  , double_MEMBER(crunch_small_outlines_size, 0.6, "Small if lt xht x this", this->params())
280  , INT_MEMBER(crunch_rating_max, 10, "For adj length in rating per ch", this->params())
281  , INT_MEMBER(crunch_pot_indicators, 1, "How many potential indicators needed", this->params())
282  , BOOL_MEMBER(crunch_leave_ok_strings, true, "Don't touch sensible strings", this->params())
283  , BOOL_MEMBER(crunch_accept_ok, true, "Use acceptability in okstring", this->params())
284  , BOOL_MEMBER(crunch_leave_accept_strings, false, "Don't pot crunch sensible strings",
285  this->params())
286  , BOOL_MEMBER(crunch_include_numerals, false, "Fiddle alpha figures", this->params())
287  , INT_MEMBER(crunch_leave_lc_strings, 4, "Don't crunch words with long lower case strings",
288  this->params())
289  , INT_MEMBER(crunch_leave_uc_strings, 4, "Don't crunch words with long lower case strings",
290  this->params())
291  , INT_MEMBER(crunch_long_repetitions, 3, "Crunch words with long repetitions", this->params())
292  , INT_MEMBER(crunch_debug, 0, "As it says", this->params())
293  , INT_MEMBER(fixsp_non_noise_limit, 1, "How many non-noise blbs either side?", this->params())
294  , double_MEMBER(fixsp_small_outlines_size, 0.28, "Small if lt xht x this", this->params())
295  , BOOL_MEMBER(tessedit_prefer_joined_punct, false, "Reward punctuation joins", this->params())
296  , INT_MEMBER(fixsp_done_mode, 1, "What constitutes done for spacing", this->params())
297  , INT_MEMBER(debug_fix_space_level, 0, "Contextual fixspace debug", this->params())
298  , STRING_MEMBER(numeric_punctuation, ".,", "Punct. chs expected WITHIN numbers", this->params())
299  , INT_MEMBER(x_ht_acceptance_tolerance, 8,
300  "Max allowed deviation of blob top outside of font data", this->params())
301  , INT_MEMBER(x_ht_min_change, 8, "Min change in xht before actually trying it", this->params())
302  , INT_MEMBER(superscript_debug, 0, "Debug level for sub & superscript fixer", this->params())
303  , double_MEMBER(superscript_worse_certainty, 2.0,
304  "How many times worse "
305  "certainty does a superscript position glyph need to be for "
306  "us to try classifying it as a char with a different "
307  "baseline?",
308  this->params())
309  , double_MEMBER(superscript_bettered_certainty, 0.97,
310  "What reduction in "
311  "badness do we think sufficient to choose a superscript "
312  "over what we'd thought. For example, a value of 0.6 means "
313  "we want to reduce badness of certainty by at least 40%",
314  this->params())
315  , double_MEMBER(superscript_scaledown_ratio, 0.4,
316  "A superscript scaled down more than this is unbelievably "
317  "small. For example, 0.3 means we expect the font size to "
318  "be no smaller than 30% of the text line font size.",
319  this->params())
320  , double_MEMBER(subscript_max_y_top, 0.5,
321  "Maximum top of a character measured as a multiple of "
322  "x-height above the baseline for us to reconsider whether "
323  "it's a subscript.",
324  this->params())
325  , double_MEMBER(superscript_min_y_bottom, 0.3,
326  "Minimum bottom of a character measured as a multiple of "
327  "x-height above the baseline for us to reconsider whether "
328  "it's a superscript.",
329  this->params())
330  , BOOL_MEMBER(tessedit_write_block_separators, false, "Write block separators in output",
331  this->params())
332  , BOOL_MEMBER(tessedit_write_rep_codes, false, "Write repetition char code", this->params())
333  , BOOL_MEMBER(tessedit_write_unlv, false, "Write .unlv output file", this->params())
334  , BOOL_MEMBER(tessedit_create_txt, false, "Write .txt output file", this->params())
335  , BOOL_MEMBER(tessedit_create_hocr, false, "Write .html hOCR output file", this->params())
336  , BOOL_MEMBER(tessedit_create_alto, false, "Write .xml ALTO file", this->params())
337  , BOOL_MEMBER(tessedit_create_lstmbox, false, "Write .box file for LSTM training",
338  this->params())
339  , BOOL_MEMBER(tessedit_create_tsv, false, "Write .tsv output file", this->params())
340  , BOOL_MEMBER(tessedit_create_wordstrbox, false, "Write WordStr format .box output file",
341  this->params())
342  , BOOL_MEMBER(tessedit_create_pdf, false, "Write .pdf output file", this->params())
343  , BOOL_MEMBER(textonly_pdf, false, "Create PDF with only one invisible text layer",
344  this->params())
345  , INT_MEMBER(jpg_quality, 85, "Set JPEG quality level", this->params())
346  , INT_MEMBER(user_defined_dpi, 0, "Specify DPI for input image", this->params())
347  , INT_MEMBER(min_characters_to_try, 50, "Specify minimum characters to try during OSD",
348  this->params())
349  , STRING_MEMBER(unrecognised_char, "|", "Output char for unidentified blobs", this->params())
350  , INT_MEMBER(suspect_level, 99, "Suspect marker level", this->params())
351  , INT_MEMBER(suspect_short_words, 2, "Don't suspect dict wds longer than this", this->params())
352  , BOOL_MEMBER(suspect_constrain_1Il, false, "UNLV keep 1Il chars rejected", this->params())
353  , double_MEMBER(suspect_rating_per_ch, 999.9, "Don't touch bad rating limit", this->params())
354  , double_MEMBER(suspect_accept_rating, -999.9, "Accept good rating limit", this->params())
355  , BOOL_MEMBER(tessedit_minimal_rejection, false, "Only reject tess failures", this->params())
356  , BOOL_MEMBER(tessedit_zero_rejection, false, "Don't reject ANYTHING", this->params())
357  , BOOL_MEMBER(tessedit_word_for_word, false, "Make output have exactly one word per WERD",
358  this->params())
359  , BOOL_MEMBER(tessedit_zero_kelvin_rejection, false, "Don't reject ANYTHING AT ALL",
360  this->params())
361  , INT_MEMBER(tessedit_reject_mode, 0, "Rejection algorithm", this->params())
362  , BOOL_MEMBER(tessedit_rejection_debug, false, "Adaption debug", this->params())
363  , BOOL_MEMBER(tessedit_flip_0O, true, "Contextual 0O O0 flips", this->params())
364  , double_MEMBER(tessedit_lower_flip_hyphen, 1.5, "Aspect ratio dot/hyphen test", this->params())
365  , double_MEMBER(tessedit_upper_flip_hyphen, 1.8, "Aspect ratio dot/hyphen test", this->params())
366  , BOOL_MEMBER(rej_trust_doc_dawg, false, "Use DOC dawg in 11l conf. detector", this->params())
367  , BOOL_MEMBER(rej_1Il_use_dict_word, false, "Use dictword test", this->params())
368  , BOOL_MEMBER(rej_1Il_trust_permuter_type, true, "Don't double check", this->params())
369  , BOOL_MEMBER(rej_use_tess_accepted, true, "Individual rejection control", this->params())
370  , BOOL_MEMBER(rej_use_tess_blanks, true, "Individual rejection control", this->params())
371  , BOOL_MEMBER(rej_use_good_perm, true, "Individual rejection control", this->params())
372  , BOOL_MEMBER(rej_use_sensible_wd, false, "Extend permuter check", this->params())
373  , BOOL_MEMBER(rej_alphas_in_number_perm, false, "Extend permuter check", this->params())
374  , double_MEMBER(rej_whole_of_mostly_reject_word_fract, 0.85, "if >this fract", this->params())
375  , INT_MEMBER(tessedit_image_border, 2, "Rej blbs near image edge limit", this->params())
376  , STRING_MEMBER(ok_repeated_ch_non_alphanum_wds, "-?*\075", "Allow NN to unrej", this->params())
377  , STRING_MEMBER(conflict_set_I_l_1, "Il1[]", "Il1 conflict set", this->params())
378  , INT_MEMBER(min_sane_x_ht_pixels, 8, "Reject any x-ht lt or eq than this", this->params())
379  , BOOL_MEMBER(tessedit_create_boxfile, false, "Output text with boxes", this->params())
380  , INT_MEMBER(tessedit_page_number, -1, "-1 -> All pages, else specific page to process",
381  this->params())
382  , BOOL_MEMBER(tessedit_write_images, false, "Capture the image from the IPE", this->params())
383  , BOOL_MEMBER(interactive_display_mode, false, "Run interactively?", this->params())
384  , STRING_MEMBER(file_type, ".tif", "Filename extension", this->params())
385  , BOOL_MEMBER(tessedit_override_permuter, true, "According to dict_word", this->params())
386  , STRING_MEMBER(tessedit_load_sublangs, "", "List of languages to load with this one",
387  this->params())
388  , BOOL_MEMBER(tessedit_use_primary_params_model, false,
389  "In multilingual mode use params model of the"
390  " primary language",
391  this->params())
392  , double_MEMBER(min_orientation_margin, 7.0, "Min acceptable orientation margin",
393  this->params())
394  , BOOL_MEMBER(textord_tabfind_show_vlines, false, "Debug line finding", this->params())
395  , BOOL_MEMBER(textord_use_cjk_fp_model, false, "Use CJK fixed pitch model", this->params())
396  , BOOL_MEMBER(poly_allow_detailed_fx, false,
397  "Allow feature extractors to see the original outline", this->params())
398  , BOOL_INIT_MEMBER(tessedit_init_config_only, false,
399  "Only initialize with the config file. Useful if the "
400  "instance is not going to be used for OCR but say only "
401  "for layout analysis.",
402  this->params())
403 #ifndef DISABLED_LEGACY_ENGINE
404  , BOOL_MEMBER(textord_equation_detect, false, "Turn on equation detector", this->params())
405 #endif // ndef DISABLED_LEGACY_ENGINE
406  , BOOL_MEMBER(textord_tabfind_vertical_text, true, "Enable vertical detection", this->params())
407  , BOOL_MEMBER(textord_tabfind_force_vertical_text, false, "Force using vertical text page mode",
408  this->params())
409  , double_MEMBER(textord_tabfind_vertical_text_ratio, 0.5,
410  "Fraction of textlines deemed vertical to use vertical page "
411  "mode",
412  this->params())
413  , double_MEMBER(textord_tabfind_aligned_gap_fraction, 0.75,
414  "Fraction of height used as a minimum gap for aligned blobs.", this->params())
415  , INT_MEMBER(tessedit_parallelize, 0, "Run in parallel where possible", this->params())
416  , BOOL_MEMBER(preserve_interword_spaces, false, "Preserve multiple interword spaces",
417  this->params())
418  , STRING_MEMBER(page_separator, "\f", "Page separator (default is form feed control character)",
419  this->params())
420  , INT_MEMBER(lstm_choice_mode, 0,
421  "Allows to include alternative symbols choices in the hOCR output. "
422  "Valid input values are 0, 1 and 2. 0 is the default value. "
423  "With 1 the alternative symbol choices per timestep are included. "
424  "With 2 alternative symbol choices are extracted from the CTC "
425  "process instead of the lattice. The choices are mapped per "
426  "character.",
427  this->params())
428  , INT_MEMBER(lstm_choice_iterations, 5,
429  "Sets the number of cascading iterations for the Beamsearch in "
430  "lstm_choice_mode. Note that lstm_choice_mode must be set to a "
431  "value greater than 0 to produce results.",
432  this->params())
433  , double_MEMBER(lstm_rating_coefficient, 5,
434  "Sets the rating coefficient for the lstm choices. The smaller the "
435  "coefficient, the better are the ratings for each choice and less "
436  "information is lost due to the cut off at 0. The standard value is "
437  "5",
438  this->params())
439  , BOOL_MEMBER(pageseg_apply_music_mask, false,
440  "Detect music staff and remove intersecting components", this->params())
441  ,
442 
443  backup_config_file_(nullptr)
444  , pix_binary_(nullptr)
445  , pix_grey_(nullptr)
446  , pix_original_(nullptr)
447  , pix_thresholds_(nullptr)
448  , source_resolution_(0)
449  , textord_(this)
450  , right_to_left_(false)
451  , scaled_color_(nullptr)
452  , scaled_factor_(-1)
453  , deskew_(1.0f, 0.0f)
454  , reskew_(1.0f, 0.0f)
455  , most_recently_used_(this)
456  , font_table_size_(0)
457 #ifndef DISABLED_LEGACY_ENGINE
458  , equ_detect_(nullptr)
459 #endif // ndef DISABLED_LEGACY_ENGINE
460  , lstm_recognizer_(nullptr)
461  , train_line_page_num_(0) {}
462 
464  Clear();
465  pix_original_.destroy();
466  end_tesseract();
467  for (auto *lang : sub_langs_) {
468  delete lang;
469  }
470  delete lstm_recognizer_;
471  lstm_recognizer_ = nullptr;
472 }
473 
475  if (0 == Classify::getDict().NumDawgs() && AnyLSTMLang()) {
476  if (lstm_recognizer_ && lstm_recognizer_->GetDict()) {
477  return *lstm_recognizer_->GetDict();
478  }
479  }
480  return Classify::getDict();
481 }
482 
484  std::string debug_name = imagebasename + "_debug.pdf";
485  pixa_debug_.WritePDF(debug_name.c_str());
486  pix_binary_.destroy();
487  pix_grey_.destroy();
488  pix_thresholds_.destroy();
489  scaled_color_.destroy();
490  deskew_ = FCOORD(1.0f, 0.0f);
491  reskew_ = FCOORD(1.0f, 0.0f);
492  splitter_.Clear();
493  scaled_factor_ = -1;
494  for (auto &sub_lang : sub_langs_) {
495  sub_lang->Clear();
496  }
497 }
498 
499 #ifndef DISABLED_LEGACY_ENGINE
500 
502  equ_detect_ = detector;
503  equ_detect_->SetLangTesseract(this);
504 }
505 
506 // Clear all memory of adaption for this and all subclassifiers.
509  for (auto &sub_lang : sub_langs_) {
510  sub_lang->ResetAdaptiveClassifierInternal();
511  }
512 }
513 
514 #endif // ndef DISABLED_LEGACY_ENGINE
515 
516 // Clear the document dictionary for this and all subclassifiers.
519  for (auto &sub_lang : sub_langs_) {
520  sub_lang->getDict().ResetDocumentDictionary();
521  }
522 }
523 
525  // Set the white and blacklists (if any)
526  unicharset.set_black_and_whitelist(tessedit_char_blacklist.c_str(),
527  tessedit_char_whitelist.c_str(),
528  tessedit_char_unblacklist.c_str());
529  if (lstm_recognizer_) {
530  UNICHARSET &lstm_unicharset = lstm_recognizer_->GetUnicharset();
531  lstm_unicharset.set_black_and_whitelist(tessedit_char_blacklist.c_str(),
532  tessedit_char_whitelist.c_str(),
533  tessedit_char_unblacklist.c_str());
534  }
535  // Black and white lists should apply to all loaded classifiers.
536  for (auto &sub_lang : sub_langs_) {
537  sub_lang->unicharset.set_black_and_whitelist(tessedit_char_blacklist.c_str(),
538  tessedit_char_whitelist.c_str(),
539  tessedit_char_unblacklist.c_str());
540  if (sub_lang->lstm_recognizer_) {
541  UNICHARSET &lstm_unicharset = sub_lang->lstm_recognizer_->GetUnicharset();
542  lstm_unicharset.set_black_and_whitelist(tessedit_char_blacklist.c_str(),
543  tessedit_char_whitelist.c_str(),
544  tessedit_char_unblacklist.c_str());
545  }
546  }
547 }
548 
549 // Perform steps to prepare underlying binary image/other data structures for
550 // page segmentation.
552  textord_.set_use_cjk_fp_model(textord_use_cjk_fp_model);
553  // Find the max splitter strategy over all langs.
554  auto max_pageseg_strategy = static_cast<ShiroRekhaSplitter::SplitStrategy>(
555  static_cast<int32_t>(pageseg_devanagari_split_strategy));
556  for (auto &sub_lang : sub_langs_) {
557  auto pageseg_strategy = static_cast<ShiroRekhaSplitter::SplitStrategy>(
558  static_cast<int32_t>(sub_lang->pageseg_devanagari_split_strategy));
559  if (pageseg_strategy > max_pageseg_strategy) {
560  max_pageseg_strategy = pageseg_strategy;
561  }
562  sub_lang->pix_binary_.destroy();
563  sub_lang->pix_binary_ = pix_binary().clone();
564  }
565  // Perform shiro-rekha (top-line) splitting and replace the current image by
566  // the newly split image.
567  splitter_.set_orig_pix(pix_binary());
568  splitter_.set_pageseg_split_strategy(max_pageseg_strategy);
569  if (splitter_.Split(true, &pixa_debug_)) {
570  ASSERT_HOST(splitter_.splitted_image());
571  pix_binary_.destroy();
572  pix_binary_ = splitter_.splitted_image().clone();
573  }
574 }
575 
576 // Perform steps to prepare underlying binary image/other data structures for
577 // OCR. The current segmentation is required by this method.
578 // Note that this method resets pix_binary_ to the original binarized image,
579 // which may be different from the image actually used for OCR depending on the
580 // value of devanagari_ocr_split_strategy.
581 void Tesseract::PrepareForTessOCR(BLOCK_LIST *block_list, Tesseract *osd_tess, OSResults *osr) {
582  // Find the max splitter strategy over all langs.
583  auto max_ocr_strategy = static_cast<ShiroRekhaSplitter::SplitStrategy>(
584  static_cast<int32_t>(ocr_devanagari_split_strategy));
585  for (auto &sub_lang : sub_langs_) {
586  auto ocr_strategy = static_cast<ShiroRekhaSplitter::SplitStrategy>(
587  static_cast<int32_t>(sub_lang->ocr_devanagari_split_strategy));
588  if (ocr_strategy > max_ocr_strategy) {
589  max_ocr_strategy = ocr_strategy;
590  }
591  }
592  // Utilize the segmentation information available.
593  splitter_.set_segmentation_block_list(block_list);
594  splitter_.set_ocr_split_strategy(max_ocr_strategy);
595  // Run the splitter for OCR
596  bool split_for_ocr = splitter_.Split(false, &pixa_debug_);
597  // Restore pix_binary to the binarized original pix for future reference.
598  ASSERT_HOST(splitter_.orig_pix());
599  pix_binary_.destroy();
600  pix_binary_ = splitter_.orig_pix().clone();
601  // If the pageseg and ocr strategies are different, refresh the block list
602  // (from the last SegmentImage call) with blobs from the real image to be used
603  // for OCR.
604  if (splitter_.HasDifferentSplitStrategies()) {
605  BLOCK block("", true, 0, 0, 0, 0, pixGetWidth(pix_binary_), pixGetHeight(pix_binary_));
606  Image pix_for_ocr = split_for_ocr ? splitter_.splitted_image() : splitter_.orig_pix();
607  extract_edges(pix_for_ocr, &block);
608  splitter_.RefreshSegmentationWithNewBlobs(block.blob_list());
609  }
610  // The splitter isn't needed any more after this, so save memory by clearing.
611  splitter_.Clear();
612 }
613 
614 } // namespace tesseract
#define ASSERT_HOST(x)
Definition: errcode.h:59
#define INT_MEMBER(name, val, comment, vec)
Definition: params.h:368
#define INT_INIT_MEMBER(name, val, comment, vec)
Definition: params.h:376
#define BOOL_INIT_MEMBER(name, val, comment, vec)
Definition: params.h:378
#define double_MEMBER(name, val, comment, vec)
Definition: params.h:374
#define STRING_MEMBER(name, val, comment, vec)
Definition: params.h:372
#define BOOL_MEMBER(name, val, comment, vec)
Definition: params.h:370
@ PSM_SINGLE_BLOCK
Assume a single uniform block of text. (Default.)
Definition: publictypes.h:168
void extract_edges(Image pix, BLOCK *block)
Definition: edgblob.cpp:347
void SetLangTesseract(Tesseract *lang_tesseract)
void SetEquationDetect(EquationDetect *detector)
Dict & getDict() override
void PrepareForTessOCR(BLOCK_LIST *block_list, Tesseract *osd_tess, OSResults *osr)
Image pix_binary() const
bool AnyLSTMLang() const
void WritePDF(const char *filename)
Definition: debugpixa.h:42
Image clone() const
Definition: image.cpp:24
void destroy()
Definition: image.cpp:32
C_BLOB_LIST * blob_list()
get blobs
Definition: ocrblock.h:123
std::string imagebasename
Definition: ccutil.h:58
UNICHARSET unicharset
Definition: ccutil.h:61
std::string lang
Definition: ccutil.h:59
void set_black_and_whitelist(const char *blacklist, const char *whitelist, const char *unblacklist)
void ResetAdaptiveClassifierInternal()
Definition: adaptmatch.cpp:596
virtual Dict & getDict()
Definition: classify.h:98
void ResetDocumentDictionary()
Definition: dict.h:297
const UNICHARSET & GetUnicharset() const
const Dict * GetDict() const
void set_pageseg_split_strategy(SplitStrategy strategy)
void RefreshSegmentationWithNewBlobs(C_BLOB_LIST *new_blobs)
bool Split(bool split_for_pageseg, DebugPixa *pixa_debug)
void set_segmentation_block_list(BLOCK_LIST *block_list)
void set_ocr_split_strategy(SplitStrategy strategy)
void set_use_cjk_fp_model(bool flag)
Definition: textord.h:101