Tesseract 3.02

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
tesseractclass.cpp
Go to the documentation of this file.
1
2 // File: tesseractclass.cpp
3 // Description: An instance of Tesseract. For thread safety, *every*
4 // global variable goes in here, directly, or indirectly.
5 // Author: Ray Smith
6 // Created: Fri Mar 07 08:17:01 PST 2008
7 //
8 // (C) Copyright 2008, Google Inc.
9 // Licensed under the Apache License, Version 2.0 (the "License");
10 // you may not use this file except in compliance with the License.
11 // You may obtain a copy of the License at
12 // http://www.apache.org/licenses/LICENSE-2.0
13 // Unless required by applicable law or agreed to in writing, software
14 // distributed under the License is distributed on an "AS IS" BASIS,
15 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 // See the License for the specific language governing permissions and
17 // limitations under the License.
18 //
20
21 #include "tesseractclass.h"
22
23 #include "allheaders.h"
24 #include "cube_reco_context.h"
25 #include "edgblob.h"
26 #include "equationdetect.h"
27 #include "globals.h"
28 #include "tesseract_cube_combiner.h"
29
30 // Include automatically generated configuration file if running autoconf.
31 #ifdef HAVE_CONFIG_H
32 #include "config_auto.h"
33 #endif
34
35 namespace tesseract {
36
37 Tesseract::Tesseract()
38 : BOOL_MEMBER(tessedit_resegment_from_boxes, false,
39 "Take segmentation and labeling from box file",
40 this->params()),
41 BOOL_MEMBER(tessedit_resegment_from_line_boxes, false,
42 "Conversion of word/line box file to char box file",
43 this->params()),
44 BOOL_MEMBER(tessedit_train_from_boxes, false,
45 "Generate training data from boxed chars", this->params()),
46 BOOL_MEMBER(tessedit_make_boxes_from_boxes, false,
47 "Generate more boxes from boxed chars", this->params()),
48 BOOL_MEMBER(tessedit_dump_pageseg_images, false,
49 "Dump intermediate images made during page segmentation",
50 this->params()),
51 // The default for pageseg_mode is the old behaviour, so as not to
52 // upset anything that relies on that.
53 INT_MEMBER(tessedit_pageseg_mode, PSM_SINGLE_BLOCK,
54 "Page seg mode: 0=osd only, 1=auto+osd, 2=auto, 3=col, 4=block,"
55 " 5=line, 6=word, 7=char"
56 " (Values from PageSegMode enum in publictypes.h)",
57 this->params()),
58 INT_INIT_MEMBER(tessedit_ocr_engine_mode, tesseract::OEM_TESSERACT_ONLY,
59 "Which OCR engine(s) to run (Tesseract, Cube, both)."
60 " Defaults to loading and running only Tesseract"
61 " (no Cube,no combiner)."
62 " Values from OcrEngineMode enum in tesseractclass.h)",
63 this->params()),
64 STRING_MEMBER(tessedit_char_blacklist, "",
65 "Blacklist of chars not to recognize", this->params()),
66 STRING_MEMBER(tessedit_char_whitelist, "",
67 "Whitelist of chars to recognize", this->params()),
68 BOOL_MEMBER(tessedit_ambigs_training, false,
69 "Perform training for ambiguities", this->params()),
70 INT_MEMBER(pageseg_devanagari_split_strategy,
71 tesseract::ShiroRekhaSplitter::NO_SPLIT,
72 "Whether to use the top-line splitting process for Devanagari "
73 "documents while performing page-segmentation.", this->params()),
74 INT_MEMBER(ocr_devanagari_split_strategy,
75 tesseract::ShiroRekhaSplitter::NO_SPLIT,
76 "Whether to use the top-line splitting process for Devanagari "
77 "documents while performing ocr.", this->params()),
78 STRING_MEMBER(tessedit_write_params_to_file, "",
79 "Write all parameters to the given file.", this->params()),
80 BOOL_MEMBER(tessedit_adapt_to_char_fragments, true,
81 "Adapt to words that contain "
82 " a character composed form fragments", this->params()),
83 BOOL_MEMBER(tessedit_adaption_debug, false, "Generate and print debug"
84 " information for adaption", this->params()),
85 INT_MEMBER(bidi_debug, 0, "Debug level for BiDi", this->params()),
86 INT_MEMBER(applybox_debug, 1, "Debug level", this->params()),
87 INT_MEMBER(applybox_page, 0,
88 "Page number to apply boxes from", this->params()),
89 STRING_MEMBER(applybox_exposure_pattern, ".exp", "Exposure value follows"
90 " this pattern in the image filename. The name of the image"
91 " files are expected to be in the form"
92 " [lang].[fontname].exp[num].tif", this->params()),
93 BOOL_MEMBER(applybox_learn_chars_and_char_frags_mode, false,
94 "Learn both character fragments (as is done in the"
95 " special low exposure mode) as well as unfragmented"
96 " characters.", this->params()),
97 BOOL_MEMBER(applybox_learn_ngrams_mode, false, "Each bounding box"
98 " is assumed to contain ngrams. Only learn the ngrams"
99 " whose outlines overlap horizontally.", this->params()),
100 BOOL_MEMBER(tessedit_display_outwords, false,
101 "Draw output words", this->params()),
102 BOOL_MEMBER(tessedit_training_tess, false,
103 "Call Tess to learn blobs", this->params()),
104 BOOL_MEMBER(tessedit_dump_choices, false,
105 "Dump char choices", this->params()),
106 BOOL_MEMBER(tessedit_fix_fuzzy_spaces, true,
107 "Try to improve fuzzy spaces", this->params()),
108 BOOL_MEMBER(tessedit_unrej_any_wd, false,
109 "Dont bother with word plausibility", this->params()),
110 BOOL_MEMBER(tessedit_fix_hyphens, true,
111 "Crunch double hyphens?", this->params()),
112 BOOL_MEMBER(tessedit_redo_xheight, true,
113 "Check/Correct x-height", this->params()),
114 BOOL_MEMBER(tessedit_enable_doc_dict, true,
115 "Add words to the document dictionary", this->params()),
116 BOOL_MEMBER(tessedit_debug_fonts, false,
117 "Output font info per char", this->params()),
118 BOOL_MEMBER(tessedit_debug_block_rejection, false,
119 "Block and Row stats", this->params()),
120 BOOL_MEMBER(tessedit_enable_bigram_correction, false,
121 "Enable correction based on the word bigram dictionary.",
122 this->params()),
123 INT_MEMBER(tessedit_bigram_debug, 0,
124 "Amount of debug output for bigram correction.",
125 this->params()),
126 INT_MEMBER(debug_x_ht_level, 0, "Reestimate debug", this->params()),
127 BOOL_MEMBER(debug_acceptable_wds, false,
128 "Dump word pass/fail chk", this->params()),
129 STRING_MEMBER(chs_leading_punct, "('`\"",
130 "Leading punctuation", this->params()),
131 STRING_MEMBER(chs_trailing_punct1, ").,;:?!",
132 "1st Trailing punctuation", this->params()),
133 STRING_MEMBER(chs_trailing_punct2, ")'`\"",
134 "2nd Trailing punctuation", this->params()),
135 double_MEMBER(quality_rej_pc, 0.08,
136 "good_quality_doc lte rejection limit", this->params()),
137 double_MEMBER(quality_blob_pc, 0.0,
138 "good_quality_doc gte good blobs limit", this->params()),
139 double_MEMBER(quality_outline_pc, 1.0,
140 "good_quality_doc lte outline error limit", this->params()),
141 double_MEMBER(quality_char_pc, 0.95,
142 "good_quality_doc gte good char limit", this->params()),
143 INT_MEMBER(quality_min_initial_alphas_reqd, 2,
144 "alphas in a good word", this->params()),
145 BOOL_MEMBER(tessedit_tess_adapt_to_rejmap, false,
146 "Use reject map to control Tesseract adaption", this->params()),
147 INT_MEMBER(tessedit_tess_adaption_mode, 0x27,
148 "Adaptation decision algorithm for tess", this->params()),
149 BOOL_MEMBER(tessedit_minimal_rej_pass1, false,
150 "Do minimal rejection on pass 1 output", this->params()),
151 BOOL_MEMBER(tessedit_test_adaption, false,
152 "Test adaption criteria", this->params()),
153 BOOL_MEMBER(tessedit_matcher_log, false,
154 "Log matcher activity", this->params()),
155 INT_MEMBER(tessedit_test_adaption_mode, 3,
156 "Adaptation decision algorithm for tess", this->params()),
157 BOOL_MEMBER(save_blob_choices, false,
158 "Save the results of the recognition step (blob_choices)"
159 " within the corresponding WERD_CHOICE", this->params()),
160 BOOL_MEMBER(test_pt, false, "Test for point", this->params()),
161 double_MEMBER(test_pt_x, 99999.99, "xcoord", this->params()),
162 double_MEMBER(test_pt_y, 99999.99, "ycoord", this->params()),
163 INT_MEMBER(paragraph_debug_level, 0, "Print paragraph debug info.",
164 this->params()),
165 INT_MEMBER(cube_debug_level, 0, "Print cube debug info.", this->params()),
166 STRING_MEMBER(outlines_odd, "%| ", "Non standard number of outlines",
167 this->params()),
168 STRING_MEMBER(outlines_2, "ij!?%\":;",
169 "Non standard number of outlines", this->params()),
170 BOOL_MEMBER(docqual_excuse_outline_errs, false,
171 "Allow outline errs in unrejection?", this->params()),
172 BOOL_MEMBER(tessedit_good_quality_unrej, true,
173 "Reduce rejection on good docs", this->params()),
174 BOOL_MEMBER(tessedit_use_reject_spaces, true,
175 "Reject spaces?", this->params()),
176 double_MEMBER(tessedit_reject_doc_percent, 65.00,
177 "%rej allowed before rej whole doc", this->params()),
178 double_MEMBER(tessedit_reject_block_percent, 45.00,
179 "%rej allowed before rej whole block", this->params()),
180 double_MEMBER(tessedit_reject_row_percent, 40.00,
181 "%rej allowed before rej whole row", this->params()),
182 double_MEMBER(tessedit_whole_wd_rej_row_percent, 70.00,
183 "Number of row rejects in whole word rejects"
184 "which prevents whole row rejection", this->params()),
185 BOOL_MEMBER(tessedit_preserve_blk_rej_perfect_wds, true,
186 "Only rej partially rejected words in block rejection",
187 this->params()),
188 BOOL_MEMBER(tessedit_preserve_row_rej_perfect_wds, true,
189 "Only rej partially rejected words in row rejection",
190 this->params()),
191 BOOL_MEMBER(tessedit_dont_blkrej_good_wds, false,
192 "Use word segmentation quality metric", this->params()),
193 BOOL_MEMBER(tessedit_dont_rowrej_good_wds, false,
194 "Use word segmentation quality metric", this->params()),
195 INT_MEMBER(tessedit_preserve_min_wd_len, 2,
196 "Only preserve wds longer than this", this->params()),
197 BOOL_MEMBER(tessedit_row_rej_good_docs, true,
198 "Apply row rejection to good docs", this->params()),
199 double_MEMBER(tessedit_good_doc_still_rowrej_wd, 1.1,
200 "rej good doc wd if more than this fraction rejected",
201 this->params()),
202 BOOL_MEMBER(tessedit_reject_bad_qual_wds, true,
203 "Reject all bad quality wds", this->params()),
204 BOOL_MEMBER(tessedit_debug_doc_rejection, false,
205 "Page stats", this->params()),
206 BOOL_MEMBER(tessedit_debug_quality_metrics, false,
207 "Output data to debug file", this->params()),
208 BOOL_MEMBER(bland_unrej, false,
209 "unrej potential with no chekcs", this->params()),
210 double_MEMBER(quality_rowrej_pc, 1.1,
211 "good_quality_doc gte good char limit", this->params()),
212 BOOL_MEMBER(unlv_tilde_crunching, true,
213 "Mark v.bad words for tilde crunch", this->params()),
214 BOOL_MEMBER(crunch_early_merge_tess_fails, true,
215 "Before word crunch?", this->params()),
216 BOOL_MEMBER(crunch_early_convert_bad_unlv_chs, false,
217 "Take out ~^ early?", this->params()),
218 double_MEMBER(crunch_terrible_rating, 80.0,
219 "crunch rating lt this", this->params()),
220 BOOL_MEMBER(crunch_terrible_garbage, true, "As it says", this->params()),
221 double_MEMBER(crunch_poor_garbage_cert, -9.0,
222 "crunch garbage cert lt this", this->params()),
223 double_MEMBER(crunch_poor_garbage_rate, 60,
224 "crunch garbage rating lt this", this->params()),
225 double_MEMBER(crunch_pot_poor_rate, 40,
226 "POTENTIAL crunch rating lt this", this->params()),
227 double_MEMBER(crunch_pot_poor_cert, -8.0,
228 "POTENTIAL crunch cert lt this", this->params()),
229 BOOL_MEMBER(crunch_pot_garbage, true,
230 "POTENTIAL crunch garbage", this->params()),
231 double_MEMBER(crunch_del_rating, 60,
232 "POTENTIAL crunch rating lt this", this->params()),
233 double_MEMBER(crunch_del_cert, -10.0,
234 "POTENTIAL crunch cert lt this", this->params()),
235 double_MEMBER(crunch_del_min_ht, 0.7,
236 "Del if word ht lt xht x this", this->params()),
237 double_MEMBER(crunch_del_max_ht, 3.0,
238 "Del if word ht gt xht x this", this->params()),
239 double_MEMBER(crunch_del_min_width, 3.0,
240 "Del if word width lt xht x this", this->params()),
241 double_MEMBER(crunch_del_high_word, 1.5,
242 "Del if word gt xht x this above bl", this->params()),
243 double_MEMBER(crunch_del_low_word, 0.5,
244 "Del if word gt xht x this below bl", this->params()),
245 double_MEMBER(crunch_small_outlines_size, 0.6,
246 "Small if lt xht x this", this->params()),
247 INT_MEMBER(crunch_rating_max, 10,
248 "For adj length in rating per ch", this->params()),
249 INT_MEMBER(crunch_pot_indicators, 1,
250 "How many potential indicators needed", this->params()),
251 BOOL_MEMBER(crunch_leave_ok_strings, true,
252 "Dont touch sensible strings", this->params()),
253 BOOL_MEMBER(crunch_accept_ok, true,
254 "Use acceptability in okstring", this->params()),
255 BOOL_MEMBER(crunch_leave_accept_strings, false,
256 "Dont pot crunch sensible strings", this->params()),
257 BOOL_MEMBER(crunch_include_numerals, false,
258 "Fiddle alpha figures", this->params()),
259 INT_MEMBER(crunch_leave_lc_strings, 4,
260 "Dont crunch words with long lower case strings",
261 this->params()),
262 INT_MEMBER(crunch_leave_uc_strings, 4,
263 "Dont crunch words with long lower case strings",
264 this->params()),
265 INT_MEMBER(crunch_long_repetitions, 3,
266 "Crunch words with long repetitions", this->params()),
267 INT_MEMBER(crunch_debug, 0, "As it says", this->params()),
268 INT_MEMBER(fixsp_non_noise_limit, 1,
269 "How many non-noise blbs either side?", this->params()),
270 double_MEMBER(fixsp_small_outlines_size, 0.28,
271 "Small if lt xht x this", this->params()),
272 BOOL_MEMBER(tessedit_prefer_joined_punct, false,
273 "Reward punctation joins", this->params()),
274 INT_MEMBER(fixsp_done_mode, 1,
275 "What constitues done for spacing", this->params()),
276 INT_MEMBER(debug_fix_space_level, 0,
277 "Contextual fixspace debug", this->params()),
278 STRING_MEMBER(numeric_punctuation, ".,",
279 "Punct. chs expected WITHIN numbers", this->params()),
280 INT_MEMBER(x_ht_acceptance_tolerance, 8,
281 "Max allowed deviation of blob top outside of font data",
282 this->params()),
283 INT_MEMBER(x_ht_min_change, 8,
284 "Min change in xht before actually trying it", this->params()),
285 BOOL_MEMBER(tessedit_write_block_separators, false,
286 "Write block separators in output", this->params()),
287 BOOL_MEMBER(tessedit_write_rep_codes, false,
288 "Write repetition char code", this->params()),
289 BOOL_MEMBER(tessedit_write_unlv, false,
290 "Write .unlv output file", this->params()),
291 BOOL_MEMBER(tessedit_create_hocr, false,
292 "Write .html hOCR output file", this->params()),
293 STRING_MEMBER(unrecognised_char, "|",
294 "Output char for unidentified blobs", this->params()),
295 INT_MEMBER(suspect_level, 99, "Suspect marker level", this->params()),
296 INT_MEMBER(suspect_space_level, 100,
297 "Min suspect level for rejecting spaces", this->params()),
298 INT_MEMBER(suspect_short_words, 2,
299 "Dont Suspect dict wds longer than this", this->params()),
300 BOOL_MEMBER(suspect_constrain_1Il, false,
301 "UNLV keep 1Il chars rejected", this->params()),
302 double_MEMBER(suspect_rating_per_ch, 999.9,
303 "Dont touch bad rating limit", this->params()),
304 double_MEMBER(suspect_accept_rating, -999.9,
305 "Accept good rating limit", this->params()),
306 BOOL_MEMBER(tessedit_minimal_rejection, false,
307 "Only reject tess failures", this->params()),
308 BOOL_MEMBER(tessedit_zero_rejection, false,
309 "Dont reject ANYTHING", this->params()),
310 BOOL_MEMBER(tessedit_word_for_word, false,
311 "Make output have exactly one word per WERD", this->params()),
312 BOOL_MEMBER(tessedit_zero_kelvin_rejection, false,
313 "Dont reject ANYTHING AT ALL", this->params()),
314 BOOL_MEMBER(tessedit_consistent_reps, true,
315 "Force all rep chars the same", this->params()),
316 INT_MEMBER(tessedit_reject_mode, 0, "Rejection algorithm", this->params()),
317 INT_MEMBER(tessedit_ok_mode, 5,
318 "Acceptance decision algorithm", this->params()),
319 BOOL_MEMBER(tessedit_rejection_debug, false,
320 "Adaption debug", this->params()),
321 BOOL_MEMBER(tessedit_flip_0O, true,
322 "Contextual 0O O0 flips", this->params()),
323 double_MEMBER(tessedit_lower_flip_hyphen, 1.5,
324 "Aspect ratio dot/hyphen test", this->params()),
325 double_MEMBER(tessedit_upper_flip_hyphen, 1.8,
326 "Aspect ratio dot/hyphen test", this->params()),
327 BOOL_MEMBER(rej_trust_doc_dawg, false,
328 "Use DOC dawg in 11l conf. detector", this->params()),
329 BOOL_MEMBER(rej_1Il_use_dict_word, false,
330 "Use dictword test", this->params()),
331 BOOL_MEMBER(rej_1Il_trust_permuter_type, true,
332 "Dont double check", this->params()),
333 BOOL_MEMBER(rej_use_tess_accepted, true,
334 "Individual rejection control", this->params()),
335 BOOL_MEMBER(rej_use_tess_blanks, true,
336 "Individual rejection control", this->params()),
337 BOOL_MEMBER(rej_use_good_perm, true,
338 "Individual rejection control", this->params()),
339 BOOL_MEMBER(rej_use_sensible_wd, false,
340 "Extend permuter check", this->params()),
341 BOOL_MEMBER(rej_alphas_in_number_perm, false,
342 "Extend permuter check", this->params()),
343 double_MEMBER(rej_whole_of_mostly_reject_word_fract, 0.85,
344 "if >this fract", this->params()),
345 INT_MEMBER(tessedit_image_border, 2,
346 "Rej blbs near image edge limit", this->params()),
347 STRING_MEMBER(ok_repeated_ch_non_alphanum_wds, "-?*\075",
348 "Allow NN to unrej", this->params()),
349 STRING_MEMBER(conflict_set_I_l_1, "Il1[]",
350 "Il1 conflict set", this->params()),
351 INT_MEMBER(min_sane_x_ht_pixels, 8,
352 "Reject any x-ht lt or eq than this", this->params()),
353 BOOL_MEMBER(tessedit_create_boxfile, false,
354 "Output text with boxes", this->params()),
355 INT_MEMBER(tessedit_page_number, -1, "-1 -> All pages"
356 " , else specifc page to process", this->params()),
357 BOOL_MEMBER(tessedit_write_images, false,
358 "Capture the image from the IPE", this->params()),
359 BOOL_MEMBER(interactive_display_mode, false, "Run interactively?",
360 this->params()),
361 STRING_MEMBER(file_type, ".tif", "Filename extension", this->params()),
362 BOOL_MEMBER(tessedit_override_permuter, true,
363 "According to dict_word", this->params()),
364 INT_MEMBER(tessdata_manager_debug_level, 0, "Debug level for"
365 " TessdataManager functions.", this->params()),
366 STRING_MEMBER(tessedit_load_sublangs, "",
367 "List of languages to load with this one", this->params()),
368 double_MEMBER(min_orientation_margin, 7.0,
369 "Min acceptable orientation margin", this->params()),
370 BOOL_MEMBER(textord_tabfind_show_vlines, false, "Debug line finding",
371 this->params()),
372 BOOL_MEMBER(textord_use_cjk_fp_model, FALSE, "Use CJK fixed pitch model",
373 this->params()),
374 BOOL_INIT_MEMBER(tessedit_init_config_only, false,
375 "Only initialize with the config file. Useful if the "
376 "instance is not going to be used for OCR but say only "
377 "for layout analysis.", this->params()),
378 BOOL_MEMBER(textord_equation_detect, false, "Turn on equation detector",
379 this->params()),
380 backup_config_file_(NULL),
381 pix_binary_(NULL),
382 cube_binary_(NULL),
383 pix_grey_(NULL),
384 source_resolution_(0),
385 textord_(this),
386 right_to_left_(false),
387 scaled_color_(NULL),
388 scaled_factor_(-1),
389 deskew_(1.0f, 0.0f),
390 reskew_(1.0f, 0.0f),
391 most_recently_used_(this),
392 font_table_size_(0),
393 cube_cntxt_(NULL),
394 tess_cube_combiner_(NULL),
395 equ_detect_(NULL) {
396 }
397
398 Tesseract::~Tesseract() {
399 Clear();
400 end_tesseract();
401 sub_langs_.delete_data_pointers();
402 // Delete cube objects.
403 if (cube_cntxt_ != NULL) {
404 delete cube_cntxt_;
405 cube_cntxt_ = NULL;
406 }
407 if (tess_cube_combiner_ != NULL) {
408 delete tess_cube_combiner_;
409 tess_cube_combiner_ = NULL;
410 }
411 }
412
413 void Tesseract::Clear() {
414 pixDestroy(&pix_binary_);
415 pixDestroy(&cube_binary_);
416 pixDestroy(&pix_grey_);
417 pixDestroy(&scaled_color_);
418 deskew_ = FCOORD(1.0f, 0.0f);
419 reskew_ = FCOORD(1.0f, 0.0f);
420 splitter_.Clear();
421 scaled_factor_ = -1;
422 ResetFeaturesHaveBeenExtracted();
423 for (int i = 0; i < sub_langs_.size(); ++i)
424 sub_langs_[i]->Clear();
425 }
426
427 void Tesseract::SetEquationDetect(EquationDetect* detector) {
428 equ_detect_ = detector;
429 equ_detect_->SetLangTesseract(this);
430 }
431
432 // Clear all memory of adaption for this and all subclassifiers.
433 void Tesseract::ResetAdaptiveClassifier() {
434 ResetAdaptiveClassifierInternal();
435 for (int i = 0; i < sub_langs_.size(); ++i) {
436 sub_langs_[i]->ResetAdaptiveClassifierInternal();
437 }
438 }
439
440 // Clear the document dictionary for this and all subclassifiers.
441 void Tesseract::ResetDocumentDictionary() {
442 getDict().ResetDocumentDictionary();
443 for (int i = 0; i < sub_langs_.size(); ++i) {
444 sub_langs_[i]->getDict().ResetDocumentDictionary();
445 }
446 }
447
448 void Tesseract::SetBlackAndWhitelist() {
449 // Set the white and blacklists (if any)
450 unicharset.set_black_and_whitelist(tessedit_char_blacklist.string(),
451 tessedit_char_whitelist.string());
452 // Black and white lists should apply to all loaded classifiers.
453 for (int i = 0; i < sub_langs_.size(); ++i) {
454 sub_langs_[i]->unicharset.set_black_and_whitelist(
455 tessedit_char_blacklist.string(), tessedit_char_whitelist.string());
456 }
457 }
458
459 // Perform steps to prepare underlying binary image/other data structures for
460 // page segmentation.
461 void Tesseract::PrepareForPageseg() {
462 textord_.set_use_cjk_fp_model(textord_use_cjk_fp_model);
463 pixDestroy(&cube_binary_);
464 cube_binary_ = pixClone(pix_binary());
465 // Find the max splitter strategy over all langs.
466 ShiroRekhaSplitter::SplitStrategy max_pageseg_strategy =
467 static_cast< ShiroRekhaSplitter::SplitStrategy >(
468 static_cast< inT32 >(pageseg_devanagari_split_strategy));
469 for (int i = 0; i < sub_langs_.size(); ++i) {
470 ShiroRekhaSplitter::SplitStrategy pageseg_strategy =
471 static_cast< ShiroRekhaSplitter::SplitStrategy >(
472 static_cast< inT32 >(sub_langs_[i]->pageseg_devanagari_split_strategy));
473 if (pageseg_strategy > max_pageseg_strategy)
474 max_pageseg_strategy = pageseg_strategy;
475 // Clone the cube image to all the sub langs too.
476 pixDestroy(&sub_langs_[i]->cube_binary_);
477 sub_langs_[i]->cube_binary_ = pixClone(pix_binary());
478 pixDestroy(&sub_langs_[i]->pix_binary_);
479 sub_langs_[i]->pix_binary_ = pixClone(pix_binary());
480 }
481 // Perform shiro-rekha (top-line) splitting and replace the current image by
482 // the newly splitted image.
483 splitter_.set_orig_pix(pix_binary());
484 splitter_.set_pageseg_split_strategy(max_pageseg_strategy);
485 if (splitter_.Split(true)) {
486 ASSERT_HOST(splitter_.splitted_image());
487 pixDestroy(&pix_binary_);
488 pix_binary_ = pixClone(splitter_.splitted_image());
489 }
490 }
491
492 // Perform steps to prepare underlying binary image/other data structures for
493 // OCR. The current segmentation is required by this method.
494 // Note that this method resets pix_binary_ to the original binarized image,
495 // which may be different from the image actually used for OCR depending on the
496 // value of devanagari_ocr_split_strategy.
497 void Tesseract::PrepareForTessOCR(BLOCK_LIST* block_list,
498 Tesseract* osd_tess, OSResults* osr) {
499 // Find the max splitter strategy over all langs.
500 ShiroRekhaSplitter::SplitStrategy max_ocr_strategy =
501 static_cast< ShiroRekhaSplitter::SplitStrategy >(
502 static_cast< inT32 >(ocr_devanagari_split_strategy));
503 for (int i = 0; i < sub_langs_.size(); ++i) {
504 ShiroRekhaSplitter::SplitStrategy ocr_strategy =
505 static_cast< ShiroRekhaSplitter::SplitStrategy >(
506 static_cast< inT32 >(sub_langs_[i]->ocr_devanagari_split_strategy));
507 if (ocr_strategy > max_ocr_strategy)
508 max_ocr_strategy = ocr_strategy;
509 }
510 // Utilize the segmentation information available.
511 splitter_.set_segmentation_block_list(block_list);
512 splitter_.set_ocr_split_strategy(max_ocr_strategy);
513 // Run the splitter for OCR
514 bool split_for_ocr = splitter_.Split(false);
515 // Restore pix_binary to the binarized original pix for future reference.
516 ASSERT_HOST(splitter_.orig_pix());
517 pixDestroy(&pix_binary_);
518 pix_binary_ = pixClone(splitter_.orig_pix());
519 // If the pageseg and ocr strategies are different, refresh the block list
520 // (from the last SegmentImage call) with blobs from the real image to be used
521 // for OCR.
522 if (splitter_.HasDifferentSplitStrategies()) {
523 BLOCK block("", TRUE, 0, 0, 0, 0, pixGetWidth(pix_binary_),
524 pixGetHeight(pix_binary_));
525 Pix* pix_for_ocr = split_for_ocr ? splitter_.splitted_image() :
526 splitter_.orig_pix();
527 extract_edges(pix_for_ocr, &block);
528 splitter_.RefreshSegmentationWithNewBlobs(block.blob_list());
529 }
530 // The splitter isn't needed any more after this, so save memory by clearing.
531 splitter_.Clear();
532 }
533
534 } // namespace tesseract