2007-03-08 04:03:40 +08:00
|
|
|
/**********************************************************************
|
|
|
|
* File: tessedit.cpp (Formerly tessedit.c)
|
|
|
|
* Description: Main program for merge of tess and editor.
|
|
|
|
* Author: Ray Smith
|
|
|
|
* Created: Tue Jan 07 15:21:46 GMT 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.
|
|
|
|
*
|
|
|
|
**********************************************************************/
|
|
|
|
|
|
|
|
#include "mfcpch.h"
|
|
|
|
//#include <osfcn.h>
|
|
|
|
//#include <signal.h>
|
|
|
|
//#include <time.h>
|
|
|
|
//#include <unistd.h>
|
|
|
|
#include "tfacep.h" //must be before main.h
|
|
|
|
//#include "fileerr.h"
|
|
|
|
#include "stderr.h"
|
|
|
|
#include "basedir.h"
|
|
|
|
#include "tessvars.h"
|
|
|
|
//#include "debgwin.h"
|
|
|
|
//#include "epapdest.h"
|
|
|
|
#include "control.h"
|
|
|
|
#include "imgs.h"
|
|
|
|
#include "reject.h"
|
|
|
|
#include "pageres.h"
|
|
|
|
//#include "gpapdest.h"
|
|
|
|
#include "nwmain.h"
|
|
|
|
#include "pgedit.h"
|
|
|
|
#include "tprintf.h"
|
|
|
|
//#include "ipeerr.h"
|
|
|
|
//#include "restart.h"
|
|
|
|
#include "tessedit.h"
|
|
|
|
//#include "fontfind.h"
|
|
|
|
#include "permute.h"
|
|
|
|
#include "stopper.h"
|
|
|
|
#include "intmatcher.h"
|
|
|
|
#include "chop.h"
|
2007-05-16 09:18:59 +08:00
|
|
|
#include "efio.h"
|
|
|
|
#include "danerror.h"
|
2007-03-08 04:03:40 +08:00
|
|
|
#include "globals.h"
|
2009-07-11 10:03:51 +08:00
|
|
|
#include "tesseractclass.h"
|
2010-11-24 02:34:14 +08:00
|
|
|
#include "params.h"
|
2007-08-31 02:25:18 +08:00
|
|
|
|
2007-03-08 04:03:40 +08:00
|
|
|
#include "notdll.h" //phils nn stuff
|
|
|
|
|
|
|
|
#define VARDIR "configs/" /*variables files */
|
|
|
|
//config under api
|
|
|
|
#define API_CONFIG "configs/api_config"
|
|
|
|
|
2009-07-11 10:03:51 +08:00
|
|
|
ETEXT_DESC *global_monitor = NULL; // progress monitor
|
2007-03-08 04:03:40 +08:00
|
|
|
|
2009-07-11 10:03:51 +08:00
|
|
|
namespace tesseract {
|
2007-03-08 04:03:40 +08:00
|
|
|
|
2009-07-11 10:03:51 +08:00
|
|
|
// Read a "config" file containing a set of variable, value pairs.
|
|
|
|
// Searches the standard places: tessdata/configs, tessdata/tessconfigs
|
|
|
|
// and also accepts a relative or absolute path name.
|
2010-11-24 02:34:14 +08:00
|
|
|
void Tesseract::read_config_file(const char *filename, bool init_only) {
|
2009-07-11 10:03:51 +08:00
|
|
|
STRING path = datadir;
|
|
|
|
path += "configs/";
|
|
|
|
path += filename;
|
|
|
|
FILE* fp;
|
|
|
|
if ((fp = fopen(path.string(), "r")) != NULL) {
|
|
|
|
fclose(fp);
|
|
|
|
} else {
|
|
|
|
path = datadir;
|
|
|
|
path += "tessconfigs/";
|
|
|
|
path += filename;
|
|
|
|
if ((fp = fopen(path.string(), "r")) != NULL) {
|
|
|
|
fclose(fp);
|
|
|
|
} else {
|
|
|
|
path = filename;
|
|
|
|
}
|
|
|
|
}
|
2010-11-24 02:34:14 +08:00
|
|
|
ParamUtils::ReadParamsFile(path.string(), init_only, this->params());
|
2009-07-11 10:03:51 +08:00
|
|
|
}
|
2007-03-08 04:03:40 +08:00
|
|
|
|
2009-07-11 10:03:51 +08:00
|
|
|
// Returns false if a unicharset file for the specified language was not found
|
|
|
|
// or was invalid.
|
|
|
|
// This function initializes TessdataManager. After TessdataManager is
|
|
|
|
// no longer needed, TessdataManager::End() should be called.
|
2010-11-24 02:34:14 +08:00
|
|
|
//
|
|
|
|
// This function sets tessedit_oem_mode to the given OcrEngineMode oem, unless
|
|
|
|
// it is OEM_DEFAULT, in which case the value of the variable will be obtained
|
|
|
|
// from the language-specific config file (stored in [lang].traineddata), from
|
|
|
|
// the config files specified on the command line or left as the default
|
|
|
|
// OEM_TESSERACT_ONLY if none of the configs specify this variable.
|
2009-07-11 10:03:51 +08:00
|
|
|
bool Tesseract::init_tesseract_lang_data(
|
|
|
|
const char *arg0, const char *textbase, const char *language,
|
2010-11-24 02:34:14 +08:00
|
|
|
OcrEngineMode oem, char **configs, int configs_size,
|
|
|
|
bool configs_init_only) {
|
2009-07-11 10:03:51 +08:00
|
|
|
// Set the basename, compute the data directory.
|
|
|
|
main_setup(arg0, textbase);
|
2007-05-16 09:18:59 +08:00
|
|
|
|
|
|
|
// Set the language data path prefix
|
2009-07-11 10:03:51 +08:00
|
|
|
lang = language != NULL ? language : "eng";
|
2007-05-16 09:18:59 +08:00
|
|
|
language_data_path_prefix = datadir;
|
2009-07-11 10:03:51 +08:00
|
|
|
language_data_path_prefix += lang;
|
2007-07-18 09:15:07 +08:00
|
|
|
language_data_path_prefix += ".";
|
2007-05-16 09:18:59 +08:00
|
|
|
|
2009-07-11 10:03:51 +08:00
|
|
|
// Initialize TessdataManager.
|
|
|
|
STRING tessdata_path = language_data_path_prefix + kTrainedDataSuffix;
|
2010-11-24 02:34:14 +08:00
|
|
|
tessdata_manager.Init(tessdata_path.string(),
|
|
|
|
tessdata_manager_debug_level);
|
2007-07-18 09:15:07 +08:00
|
|
|
|
2009-07-11 10:03:51 +08:00
|
|
|
// If a language specific config file (lang.config) exists, load it in.
|
|
|
|
if (tessdata_manager.SeekToStart(TESSDATA_LANG_CONFIG)) {
|
2010-11-24 02:34:14 +08:00
|
|
|
ParamUtils::ReadParamsFromFp(
|
|
|
|
tessdata_manager.GetDataFilePtr(),
|
|
|
|
tessdata_manager.GetEndOffset(TESSDATA_LANG_CONFIG),
|
|
|
|
false, this->params());
|
|
|
|
if (tessdata_manager_debug_level) {
|
2009-07-11 10:03:51 +08:00
|
|
|
tprintf("Loaded language config file\n");
|
|
|
|
}
|
|
|
|
}
|
2007-03-08 04:03:40 +08:00
|
|
|
|
2010-11-24 02:34:14 +08:00
|
|
|
// Load tesseract variables from config files. This is done after loading
|
|
|
|
// language-specific variables from [lang].traineddata file, so that custom
|
|
|
|
// config files can override values in [lang].traineddata file.
|
|
|
|
for (int i = 0; i < configs_size; ++i) {
|
|
|
|
read_config_file(configs[i], configs_init_only);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (((STRING &)tessedit_write_params_to_file).length() > 0) {
|
|
|
|
FILE *params_file = fopen(tessedit_write_params_to_file.string(), "w");
|
|
|
|
if (params_file != NULL) {
|
|
|
|
ParamUtils::PrintParams(params_file, this->params());
|
|
|
|
fclose(params_file);
|
|
|
|
if (tessdata_manager_debug_level > 0) {
|
|
|
|
tprintf("Wrote parameters to %s\n",
|
|
|
|
tessedit_write_params_to_file.string());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
tprintf("Failed to open %s for writing params.\n",
|
|
|
|
tessedit_write_params_to_file.string());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Determine which ocr engine(s) should be loaded and used for recognition.
|
|
|
|
if (oem != OEM_DEFAULT) tessedit_ocr_engine_mode.set_value(oem);
|
|
|
|
if (tessdata_manager_debug_level) {
|
|
|
|
tprintf("Loading Tesseract/Cube with tessedit_ocr_engine_mode %d\n",
|
|
|
|
static_cast<int>(tessedit_ocr_engine_mode));
|
|
|
|
}
|
|
|
|
|
2009-07-11 10:03:51 +08:00
|
|
|
// Load the unicharset
|
|
|
|
if (!tessdata_manager.SeekToStart(TESSDATA_UNICHARSET) ||
|
|
|
|
!unicharset.load_from_file(tessdata_manager.GetDataFilePtr())) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (unicharset.size() > MAX_NUM_CLASSES) {
|
|
|
|
tprintf("Error: Size of unicharset is greater than MAX_NUM_CLASSES\n");
|
|
|
|
return false;
|
|
|
|
}
|
2010-11-24 02:34:14 +08:00
|
|
|
right_to_left_ = unicharset.any_right_to_left();
|
|
|
|
if (tessdata_manager_debug_level) tprintf("Loaded unicharset\n");
|
2007-03-08 04:03:40 +08:00
|
|
|
|
2010-11-24 02:34:14 +08:00
|
|
|
if (!tessedit_ambigs_training &&
|
2009-07-11 10:03:51 +08:00
|
|
|
tessdata_manager.SeekToStart(TESSDATA_AMBIGS)) {
|
|
|
|
unichar_ambigs.LoadUnicharAmbigs(
|
|
|
|
tessdata_manager.GetDataFilePtr(),
|
|
|
|
tessdata_manager.GetEndOffset(TESSDATA_AMBIGS),
|
2010-11-24 02:34:14 +08:00
|
|
|
ambigs_debug_level, use_ambigs_for_adaption, &unicharset);
|
|
|
|
if (tessdata_manager_debug_level) tprintf("Loaded ambigs\n");
|
2009-07-11 10:03:51 +08:00
|
|
|
}
|
2010-11-24 02:34:14 +08:00
|
|
|
|
|
|
|
// Load Cube objects if necessary.
|
|
|
|
if (tessedit_ocr_engine_mode == OEM_CUBE_ONLY) {
|
|
|
|
ASSERT_HOST(init_cube_objects(false, &tessdata_manager));
|
|
|
|
if (tessdata_manager_debug_level)
|
|
|
|
tprintf("Loaded Cube w/out combiner\n");
|
|
|
|
} else if (tessedit_ocr_engine_mode == OEM_TESSERACT_CUBE_COMBINED) {
|
|
|
|
ASSERT_HOST(init_cube_objects(true, &tessdata_manager));
|
|
|
|
if (tessdata_manager_debug_level)
|
|
|
|
tprintf("Loaded Cube with combiner\n");
|
|
|
|
}
|
|
|
|
|
2009-07-11 10:03:51 +08:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
int Tesseract::init_tesseract(
|
|
|
|
const char *arg0, const char *textbase, const char *language,
|
2010-11-24 02:34:14 +08:00
|
|
|
OcrEngineMode oem, char **configs, int configs_size,
|
|
|
|
bool configs_init_only) {
|
|
|
|
if (!init_tesseract_lang_data(arg0, textbase, language, oem, configs,
|
|
|
|
configs_size, configs_init_only)) {
|
2009-07-11 10:03:51 +08:00
|
|
|
return -1;
|
|
|
|
}
|
2010-11-24 02:34:14 +08:00
|
|
|
// If only Cube will be used, skip loading Tesseract classifier's
|
|
|
|
// pre-trained templates.
|
|
|
|
bool init_tesseract_classifier =
|
|
|
|
(tessedit_ocr_engine_mode == OEM_TESSERACT_ONLY ||
|
|
|
|
tessedit_ocr_engine_mode == OEM_TESSERACT_CUBE_COMBINED);
|
|
|
|
// If only Cube will be used and if it has its own Unicharset,
|
|
|
|
// skip initializing permuter and loading Tesseract Dawgs.
|
|
|
|
bool init_dict =
|
|
|
|
!(tessedit_ocr_engine_mode == OEM_CUBE_ONLY &&
|
|
|
|
tessdata_manager.SeekToStart(TESSDATA_CUBE_UNICHARSET));
|
|
|
|
program_editup(textbase, init_tesseract_classifier, init_dict);
|
2009-07-11 10:03:51 +08:00
|
|
|
tessdata_manager.End();
|
2007-03-08 04:03:40 +08:00
|
|
|
return 0; //Normal exit
|
|
|
|
}
|
|
|
|
|
2008-04-22 08:32:14 +08:00
|
|
|
// init the LM component
|
2009-07-11 10:03:51 +08:00
|
|
|
int Tesseract::init_tesseract_lm(const char *arg0,
|
2008-04-22 08:32:14 +08:00
|
|
|
const char *textbase,
|
2009-07-11 10:03:51 +08:00
|
|
|
const char *language) {
|
2010-11-24 02:34:14 +08:00
|
|
|
if (!init_tesseract_lang_data(arg0, textbase, language,
|
|
|
|
OEM_TESSERACT_ONLY, NULL, 0, false))
|
|
|
|
return -1;
|
|
|
|
getDict().Load();
|
2009-07-11 10:03:51 +08:00
|
|
|
tessdata_manager.End();
|
|
|
|
return 0;
|
2008-04-22 08:32:14 +08:00
|
|
|
}
|
|
|
|
|
2009-07-11 10:03:51 +08:00
|
|
|
void Tesseract::end_tesseract() {
|
2007-03-08 04:03:40 +08:00
|
|
|
end_recog();
|
|
|
|
}
|
|
|
|
|
2009-07-11 10:03:51 +08:00
|
|
|
/* Define command type identifiers */
|
|
|
|
|
|
|
|
enum CMD_EVENTS
|
|
|
|
{
|
|
|
|
ACTION_1_CMD_EVENT,
|
|
|
|
RECOG_WERDS,
|
|
|
|
RECOG_PSEUDO,
|
|
|
|
ACTION_2_CMD_EVENT
|
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace tesseract
|