38 #include "config_auto.h" 43 #include "allheaders.h" 54 "Take segmentation and labeling from box file",
56 BOOL_MEMBER(tessedit_resegment_from_line_boxes, false,
57 "Conversion of word/line box file to char box file",
60 "Generate training data from boxed chars", this->params()),
62 "Generate more boxes from boxed chars", this->params()),
64 "Break input into lines and remap boxes if present",
67 "Dump intermediate images made during page segmentation",
73 "Page seg mode: 0=osd only, 1=auto+osd, 2=auto_only, 3=auto, 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 publictypes.h)",
79 "Which OCR engine(s) to run (Tesseract, LSTM, both)." 80 " Defaults to loading and running the most accurate" 84 "Blacklist of chars not to recognize", this->params()),
86 "Whitelist of chars to recognize", this->params()),
88 "List of chars to override tessedit_char_blacklist",
91 "Perform training for ambiguities", this->params()),
94 "Whether to use the top-line splitting process for Devanagari " 95 "documents while performing page-segmentation.",
99 "Whether to use the top-line splitting process for Devanagari " 100 "documents while performing ocr.",
103 "Write all parameters to the given file.", this->params()),
105 "Generate and print debug" 106 " information for adaption",
108 INT_MEMBER(bidi_debug, 0,
"Debug level for BiDi", this->params()),
109 INT_MEMBER(applybox_debug, 1,
"Debug level", this->params()),
110 INT_MEMBER(applybox_page, 0,
"Page number to apply boxes from",
113 "Exposure value follows" 114 " this pattern in the image filename. The name of the image" 115 " files are expected to be in the form" 116 " [lang].[fontname].exp[num].tif",
118 BOOL_MEMBER(applybox_learn_chars_and_char_frags_mode, false,
119 "Learn both character fragments (as is done in the" 120 " special low exposure mode) as well as unfragmented" 125 " is assumed to contain ngrams. Only learn the ngrams" 126 " whose outlines overlap horizontally.",
128 BOOL_MEMBER(tessedit_display_outwords, false,
"Draw output words",
130 BOOL_MEMBER(tessedit_dump_choices, false,
"Dump char choices",
132 BOOL_MEMBER(tessedit_timing_debug, false,
"Print timing stats",
135 "Try to improve fuzzy spaces", this->params()),
137 "Don't bother with word plausibility", this->params()),
138 BOOL_MEMBER(tessedit_fix_hyphens, true,
"Crunch double hyphens?",
140 BOOL_MEMBER(tessedit_redo_xheight, true,
"Check/Correct x-height",
143 "Add words to the document dictionary", this->params()),
144 BOOL_MEMBER(tessedit_debug_fonts, false,
"Output font info per char",
146 BOOL_MEMBER(tessedit_debug_block_rejection, false,
"Block and Row stats",
148 BOOL_MEMBER(tessedit_enable_bigram_correction, true,
149 "Enable correction based on the word bigram dictionary.",
151 BOOL_MEMBER(tessedit_enable_dict_correction, false,
152 "Enable single word correction based on the dictionary.",
155 "Amount of debug output for bigram correction.",
158 "Remove and conditionally reassign small outlines when they" 159 " confuse layout analysis, determining diacritics vs noise",
161 INT_MEMBER(debug_noise_removal, 0,
"Debug reassignment of small outlines",
167 "Hingepoint for base char certainty", this->params()),
171 "Hingepoint for disjoint certainty", this->params()),
175 "Threshold for new punc char certainty", this->params()),
178 "Scaling on certainty diff from Hingepoint",
180 INT_MEMBER(noise_maxperblob, 8,
"Max diacritics to apply to a blob",
182 INT_MEMBER(noise_maxperword, 16,
"Max diacritics to apply to a word",
184 INT_MEMBER(debug_x_ht_level, 0,
"Reestimate debug", this->params()),
185 BOOL_MEMBER(debug_acceptable_wds, false,
"Dump word pass/fail chk",
187 STRING_MEMBER(chs_leading_punct,
"('`\"",
"Leading punctuation",
189 STRING_MEMBER(chs_trailing_punct1,
").,;:?!",
"1st Trailing punctuation",
191 STRING_MEMBER(chs_trailing_punct2,
")'`\"",
"2nd Trailing punctuation",
194 "good_quality_doc lte rejection limit", this->params()),
196 "good_quality_doc gte good blobs limit", this->params()),
198 "good_quality_doc lte outline error limit", this->params()),
200 "good_quality_doc gte good char limit", this->params()),
201 INT_MEMBER(quality_min_initial_alphas_reqd, 2,
"alphas in a good word",
204 "Adaptation decision algorithm for tess", this->params()),
206 "Do minimal rejection on pass 1 output", this->params()),
207 BOOL_MEMBER(tessedit_test_adaption, false,
"Test adaption criteria",
209 BOOL_MEMBER(tessedit_matcher_log, false,
"Log matcher activity",
212 "Adaptation decision algorithm for tess", this->params()),
213 BOOL_MEMBER(test_pt, false,
"Test for point", this->params()),
214 double_MEMBER(test_pt_x, 99999.99,
"xcoord", this->params()),
215 double_MEMBER(test_pt_y, 99999.99,
"ycoord", this->params()),
216 INT_MEMBER(multilang_debug_level, 0,
"Print multilang debug info.",
218 INT_MEMBER(paragraph_debug_level, 0,
"Print paragraph debug info.",
221 "Run paragraph detection on the post-text-recognition " 225 "Use ratings matrix/beam search with lstm", this->params()),
226 STRING_MEMBER(outlines_odd,
"%| ",
"Non standard number of outlines",
228 STRING_MEMBER(outlines_2,
"ij!?%\":;",
"Non standard number of outlines",
231 "Allow outline errs in unrejection?", this->params()),
233 "Reduce rejection on good docs", this->params()),
234 BOOL_MEMBER(tessedit_use_reject_spaces, true,
"Reject spaces?",
237 "%rej allowed before rej whole doc", this->params()),
239 "%rej allowed before rej whole block", this->params()),
241 "%rej allowed before rej whole row", this->params()),
243 "Number of row rejects in whole word rejects" 244 " which prevents whole row rejection",
246 BOOL_MEMBER(tessedit_preserve_blk_rej_perfect_wds, true,
247 "Only rej partially rejected words in block rejection",
249 BOOL_MEMBER(tessedit_preserve_row_rej_perfect_wds, true,
250 "Only rej partially rejected words in row rejection",
253 "Use word segmentation quality metric", this->params()),
255 "Use word segmentation quality metric", this->params()),
257 "Only preserve wds longer than this", this->params()),
259 "Apply row rejection to good docs", this->params()),
261 "rej good doc wd if more than this fraction rejected",
264 "Reject all bad quality wds", this->params()),
265 BOOL_MEMBER(tessedit_debug_doc_rejection, false,
"Page stats",
268 "Output data to debug file", this->params()),
269 BOOL_MEMBER(bland_unrej, false,
"unrej potential with no checks",
272 "good_quality_doc gte good char limit", this->params()),
274 "Mark v.bad words for tilde crunch", this->params()),
275 BOOL_MEMBER(hocr_font_info, false,
"Add font info to hocr output",
277 BOOL_MEMBER(hocr_char_boxes, false,
"Add coordinates for each character to hocr output",
279 BOOL_MEMBER(crunch_early_merge_tess_fails, true,
"Before word crunch?",
281 BOOL_MEMBER(crunch_early_convert_bad_unlv_chs, false,
282 "Take out ~^ early?", this->params()),
283 double_MEMBER(crunch_terrible_rating, 80.0,
"crunch rating lt this",
285 BOOL_MEMBER(crunch_terrible_garbage, true,
"As it says", this->params()),
287 "crunch garbage cert lt this", this->params()),
289 "crunch garbage rating lt this", this->params()),
290 double_MEMBER(crunch_pot_poor_rate, 40,
"POTENTIAL crunch rating lt this",
292 double_MEMBER(crunch_pot_poor_cert, -8.0,
"POTENTIAL crunch cert lt this",
294 BOOL_MEMBER(crunch_pot_garbage, true,
"POTENTIAL crunch garbage",
296 double_MEMBER(crunch_del_rating, 60,
"POTENTIAL crunch rating lt this",
298 double_MEMBER(crunch_del_cert, -10.0,
"POTENTIAL crunch cert lt this",
300 double_MEMBER(crunch_del_min_ht, 0.7,
"Del if word ht lt xht x this",
302 double_MEMBER(crunch_del_max_ht, 3.0,
"Del if word ht gt xht x this",
305 "Del if word width lt xht x this", this->params()),
307 "Del if word gt xht x this above bl", this->params()),
309 "Del if word gt xht x this below bl", this->params()),
310 double_MEMBER(crunch_small_outlines_size, 0.6,
"Small if lt xht x this",
312 INT_MEMBER(crunch_rating_max, 10,
"For adj length in rating per ch",
315 "How many potential indicators needed", this->params()),
316 BOOL_MEMBER(crunch_leave_ok_strings, true,
"Don't touch sensible strings",
318 BOOL_MEMBER(crunch_accept_ok, true,
"Use acceptability in okstring",
321 "Don't pot crunch sensible strings", this->params()),
322 BOOL_MEMBER(crunch_include_numerals, false,
"Fiddle alpha figures",
325 "Don't crunch words with long lower case strings",
328 "Don't crunch words with long lower case strings",
331 "Crunch words with long repetitions", this->params()),
332 INT_MEMBER(crunch_debug, 0,
"As it says", this->params()),
334 "How many non-noise blbs either side?", this->params()),
335 double_MEMBER(fixsp_small_outlines_size, 0.28,
"Small if lt xht x this",
338 "Reward punctuation joins", this->params()),
339 INT_MEMBER(fixsp_done_mode, 1,
"What constitues done for spacing",
341 INT_MEMBER(debug_fix_space_level, 0,
"Contextual fixspace debug",
344 "Punct. chs expected WITHIN numbers", this->params()),
346 "Max allowed deviation of blob top outside of font data",
349 "Min change in xht before actually trying it", this->params()),
351 "Debug level for sub & superscript fixer", this->params()),
353 superscript_worse_certainty, 2.0,
354 "How many times worse " 355 "certainty does a superscript position glyph need to be for " 356 "us to try classifying it as a char with a different " 360 superscript_bettered_certainty, 0.97,
362 "badness do we think sufficient to choose a superscript " 363 "over what we'd thought. For example, a value of 0.6 means " 364 "we want to reduce badness of certainty by at least 40%",
367 "A superscript scaled down more than this is unbelievably " 368 "small. For example, 0.3 means we expect the font size to " 369 "be no smaller than 30% of the text line font size.",
372 "Maximum top of a character measured as a multiple of " 373 "x-height above the baseline for us to reconsider whether " 377 "Minimum bottom of a character measured as a multiple of " 378 "x-height above the baseline for us to reconsider whether " 379 "it's a superscript.",
381 BOOL_MEMBER(tessedit_write_block_separators, false,
382 "Write block separators in output", this->params()),
383 BOOL_MEMBER(tessedit_write_rep_codes, false,
"Write repetition char code",
385 BOOL_MEMBER(tessedit_write_unlv, false,
"Write .unlv output file",
387 BOOL_MEMBER(tessedit_create_txt, false,
"Write .txt output file",
389 BOOL_MEMBER(tessedit_create_hocr, false,
"Write .html hOCR output file",
391 BOOL_MEMBER(tessedit_create_alto, false,
"Write .xml ALTO file",
393 BOOL_MEMBER(tessedit_create_lstmbox, false,
"Write .box file for LSTM training",
395 BOOL_MEMBER(tessedit_create_tsv, false,
"Write .tsv output file",
397 BOOL_MEMBER(tessedit_create_wordstrbox, false,
"Write WordStr format .box output file",
399 BOOL_MEMBER(tessedit_create_pdf, false,
"Write .pdf output file",
402 "Create PDF with only one invisible text layer",
404 INT_MEMBER(jpg_quality, 85,
"Set JPEG quality level", this->params()),
405 INT_MEMBER(user_defined_dpi, 0,
"Specify DPI for input image",
408 "Specify minimum characters to try during OSD",
411 "Output char for unidentified blobs", this->params()),
412 INT_MEMBER(suspect_level, 99,
"Suspect marker level", this->params()),
414 "Min suspect level for rejecting spaces", this->params()),
416 "Don't suspect dict wds longer than this", this->params()),
417 BOOL_MEMBER(suspect_constrain_1Il, false,
"UNLV keep 1Il chars rejected",
420 "Don't touch bad rating limit", this->params()),
421 double_MEMBER(suspect_accept_rating, -999.9,
"Accept good rating limit",
424 "Only reject tess failures", this->params()),
425 BOOL_MEMBER(tessedit_zero_rejection, false,
"Don't reject ANYTHING",
428 "Make output have exactly one word per WERD", this->params()),
430 "Don't reject ANYTHING AT ALL", this->params()),
432 "Force all rep chars the same", this->params()),
433 INT_MEMBER(tessedit_reject_mode, 0,
"Rejection algorithm",
435 BOOL_MEMBER(tessedit_rejection_debug, false,
"Adaption debug",
437 BOOL_MEMBER(tessedit_flip_0O, true,
"Contextual 0O O0 flips",
440 "Aspect ratio dot/hyphen test", this->params()),
442 "Aspect ratio dot/hyphen test", this->params()),
444 "Use DOC dawg in 11l conf. detector", this->params()),
445 BOOL_MEMBER(rej_1Il_use_dict_word, false,
"Use dictword test",
447 BOOL_MEMBER(rej_1Il_trust_permuter_type, true,
"Don't double check",
449 BOOL_MEMBER(rej_use_tess_accepted, true,
"Individual rejection control",
451 BOOL_MEMBER(rej_use_tess_blanks, true,
"Individual rejection control",
453 BOOL_MEMBER(rej_use_good_perm, true,
"Individual rejection control",
455 BOOL_MEMBER(rej_use_sensible_wd, false,
"Extend permuter check",
457 BOOL_MEMBER(rej_alphas_in_number_perm, false,
"Extend permuter check",
460 "if >this fract", this->params()),
461 INT_MEMBER(tessedit_image_border, 2,
"Rej blbs near image edge limit",
464 "Allow NN to unrej", this->params()),
465 STRING_MEMBER(conflict_set_I_l_1,
"Il1[]",
"Il1 conflict set",
467 INT_MEMBER(min_sane_x_ht_pixels, 8,
"Reject any x-ht lt or eq than this",
469 BOOL_MEMBER(tessedit_create_boxfile, false,
"Output text with boxes",
473 " , else specific page to process",
476 "Capture the image from the IPE", this->params()),
477 BOOL_MEMBER(interactive_display_mode, false,
"Run interactively?",
479 STRING_MEMBER(file_type,
".tif",
"Filename extension", this->params()),
480 BOOL_MEMBER(tessedit_override_permuter, true,
"According to dict_word",
483 "List of languages to load with this one", this->params()),
484 BOOL_MEMBER(tessedit_use_primary_params_model, false,
485 "In multilingual mode use params model of the" 489 "Min acceptable orientation margin", this->params()),
490 BOOL_MEMBER(textord_tabfind_show_vlines, false,
"Debug line finding",
492 BOOL_MEMBER(textord_use_cjk_fp_model, false,
"Use CJK fixed pitch model",
495 "Allow feature extractors to see the original outline",
498 "Only initialize with the config file. Useful if the " 499 "instance is not going to be used for OCR but say only " 500 "for layout analysis.",
502 BOOL_MEMBER(textord_equation_detect, false,
"Turn on equation detector",
505 "Enable vertical detection", this->params()),
506 BOOL_MEMBER(textord_tabfind_force_vertical_text, false,
507 "Force using vertical text page mode", this->params()),
509 textord_tabfind_vertical_text_ratio, 0.5,
510 "Fraction of textlines deemed vertical to use vertical page " 514 textord_tabfind_aligned_gap_fraction, 0.75,
515 "Fraction of height used as a minimum gap for aligned blobs.",
517 INT_MEMBER(tessedit_parallelize, 0,
"Run in parallel where possible",
520 "Preserve multiple interword spaces", this->params()),
522 "Page separator (default is form feed control character)",
525 "Allows to include alternative symbols choices in the hOCR output. " 526 "Valid input values are 0, 1, 2 and 3. 0 is the default value. " 527 "With 1 the alternative symbol choices per timestep are included. " 528 "With 2 the alternative symbol choices are accumulated per " 532 backup_config_file_(nullptr),
533 pix_binary_(nullptr),
535 pix_original_(nullptr),
536 pix_thresholds_(nullptr),
537 source_resolution_(0),
539 right_to_left_(false),
540 scaled_color_(nullptr),
544 most_recently_used_(this),
546 equ_detect_(nullptr),
547 #ifndef ANDROID_BUILD
548 lstm_recognizer_(nullptr),
550 train_line_page_num_(0) {
555 pixDestroy(&pix_original_);
557 sub_langs_.delete_data_pointers();
558 #ifndef ANDROID_BUILD 559 delete lstm_recognizer_;
560 lstm_recognizer_ =
nullptr;
568 if (lstm_recognizer_ && lstm_recognizer_->
GetDict())
570 return *
const_cast<Dict*
>(lstm_recognizer_->
GetDict());
580 pixDestroy(&pix_binary_);
581 pixDestroy(&pix_grey_);
582 pixDestroy(&pix_thresholds_);
583 pixDestroy(&scaled_color_);
584 deskew_ =
FCOORD(1.0f, 0.0f);
585 reskew_ =
FCOORD(1.0f, 0.0f);
588 for (
int i = 0; i < sub_langs_.size(); ++i)
589 sub_langs_[i]->
Clear();
592 #ifndef DISABLED_LEGACY_ENGINE 595 equ_detect_ = detector;
602 for (
int i = 0; i < sub_langs_.size(); ++i) {
603 sub_langs_[i]->ResetAdaptiveClassifierInternal();
607 #endif //ndef DISABLED_LEGACY_ENGINE 612 for (
int i = 0; i < sub_langs_.size(); ++i) {
613 sub_langs_[i]->getDict().ResetDocumentDictionary();
622 if (lstm_recognizer_) {
629 for (
int i = 0; i < sub_langs_.size(); ++i) {
630 sub_langs_[i]->unicharset.set_black_and_whitelist(
633 if (sub_langs_[i]->lstm_recognizer_) {
634 UNICHARSET& lstm_unicharset =
const_cast<UNICHARSET&
> (sub_langs_[i]->lstm_recognizer_->GetUnicharset());
647 auto max_pageseg_strategy =
650 for (
int i = 0; i < sub_langs_.size(); ++i) {
651 auto pageseg_strategy =
653 static_cast<int32_t
>(sub_langs_[i]->pageseg_devanagari_split_strategy));
654 if (pageseg_strategy > max_pageseg_strategy)
655 max_pageseg_strategy = pageseg_strategy;
656 pixDestroy(&sub_langs_[i]->pix_binary_);
657 sub_langs_[i]->pix_binary_ = pixClone(
pix_binary());
663 if (splitter_.
Split(
true, &pixa_debug_)) {
665 pixDestroy(&pix_binary_);
678 auto max_ocr_strategy =
681 for (
int i = 0; i < sub_langs_.size(); ++i) {
684 static_cast<int32_t
>(sub_langs_[i]->ocr_devanagari_split_strategy));
685 if (ocr_strategy > max_ocr_strategy)
686 max_ocr_strategy = ocr_strategy;
692 bool split_for_ocr = splitter_.
Split(
false, &pixa_debug_);
695 pixDestroy(&pix_binary_);
696 pix_binary_ = pixClone(splitter_.
orig_pix());
701 BLOCK block(
"",
true, 0, 0, 0, 0, pixGetWidth(pix_binary_),
702 pixGetHeight(pix_binary_));
void ResetAdaptiveClassifier()
void ResetAdaptiveClassifierInternal()
const Dict * GetDict() const
#define double_MEMBER(name, val, comment, vec)
void PrepareForTessOCR(BLOCK_LIST *block_list, Tesseract *osd_tess, OSResults *osr)
void ResetDocumentDictionary()
const UNICHARSET & GetUnicharset() const
#define BOOL_MEMBER(name, val, comment, vec)
void SetLangTesseract(Tesseract *lang_tesseract)
int pageseg_devanagari_split_strategy
void extract_edges(Pix *pix, BLOCK *block)
void SetEquationDetect(EquationDetect *detector)
char * tessedit_char_unblacklist
#define INT_MEMBER(name, val, comment, vec)
bool Split(bool split_for_pageseg, DebugPixa *pixa_debug)
bool HasDifferentSplitStrategies() const
void SetBlackAndWhitelist()
char * tessedit_char_blacklist
char * tessedit_char_whitelist
void set_orig_pix(Pix *pix)
#define INT_INIT_MEMBER(name, val, comment, vec)
void set_black_and_whitelist(const char *blacklist, const char *whitelist, const char *unblacklist)
const char * string() const
Dict & getDict() override
void set_pageseg_split_strategy(SplitStrategy strategy)
void set_segmentation_block_list(BLOCK_LIST *block_list)
int ocr_devanagari_split_strategy
void ResetDocumentDictionary()
#define STRING_MEMBER(name, val, comment, vec)
void set_ocr_split_strategy(SplitStrategy strategy)
void RefreshSegmentationWithNewBlobs(C_BLOB_LIST *new_blobs)
Assume a single uniform block of text. (Default.)
void set_use_cjk_fp_model(bool flag)
C_BLOB_LIST * blob_list()
get blobs
void WritePDF(const char *filename)
#define BOOL_INIT_MEMBER(name, val, comment, vec)
bool textord_use_cjk_fp_model