Skip to content

Commit

Permalink
trying to add user words/patterns again:
Browse files Browse the repository at this point in the history
- pass in ParamsVectors from Tesseract
  (carrying values from langdata/config/api)
  into LSTMRecognizer::Load and LoadDictionary
- after LSTMRecognizer's Dict is initialised
  (with default values), reset the variables
  user_{words,patterns}_{suffix,file} from the
  corresponding entries in the passed vector
  • Loading branch information
bertsky committed Mar 15, 2019
1 parent 0a36b38 commit 297d7d8
Show file tree
Hide file tree
Showing 5 changed files with 86 additions and 7 deletions.
2 changes: 1 addition & 1 deletion src/ccmain/tessedit.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@ bool Tesseract::init_tesseract_lang_data(
if (mgr->IsComponentAvailable(TESSDATA_LSTM)) {
lstm_recognizer_ = new LSTMRecognizer;
ASSERT_HOST(
lstm_recognizer_->Load(lstm_use_matrix ? language : nullptr, mgr));
lstm_recognizer_->Load(this->params(), lstm_use_matrix ? language : nullptr, mgr));
} else {
tprintf("Error: LSTM requested, but not present!! Loading tesseract.\n");
tessedit_ocr_engine_mode.set_value(OEM_TESSERACT_ONLY);
Expand Down
34 changes: 33 additions & 1 deletion src/ccutil/params.h
Original file line number Diff line number Diff line change
Expand Up @@ -155,7 +155,15 @@ class IntParam : public Param {
void ResetToDefault() {
value_ = default_;
}

void ResetFrom(const ParamsVectors* vec) {
for (int i = 0; i < vec->int_params.size(); ++i) {
if (strcmp(vec->int_params[i]->name_str(), name_) == 0) {
//printf("overriding param %s=%d by =%d\n", name_, value_, *vec->int_params[i]);
value_ = *vec->int_params[i];
}
}
}

private:
int32_t value_;
int32_t default_;
Expand All @@ -179,6 +187,14 @@ class BoolParam : public Param {
void ResetToDefault() {
value_ = default_;
}
void ResetFrom(const ParamsVectors* vec) {
for (int i = 0; i < vec->bool_params.size(); ++i) {
if (strcmp(vec->bool_params[i]->name_str(), name_) == 0) {
//printf("overriding param %s=%s by =%s\n", name_, value_ ? "true" : "false", *vec->bool_params[i] ? "true" : "false");
value_ = *vec->bool_params[i];
}
}
}

private:
BOOL8 value_;
Expand Down Expand Up @@ -208,6 +224,14 @@ class StringParam : public Param {
void ResetToDefault() {
value_ = default_;
}
void ResetFrom(const ParamsVectors* vec) {
for (int i = 0; i < vec->string_params.size(); ++i) {
if (strcmp(vec->string_params[i]->name_str(), name_) == 0) {
//printf("overriding param %s=%s by =%s\n", name_, value_, vec->string_params[i]->c_str());
value_ = *vec->string_params[i];
}
}
}

private:
STRING value_;
Expand All @@ -232,6 +256,14 @@ class DoubleParam : public Param {
void ResetToDefault() {
value_ = default_;
}
void ResetFrom(const ParamsVectors* vec) {
for (int i = 0; i < vec->double_params.size(); ++i) {
if (strcmp(vec->double_params[i]->name_str(), name_) == 0) {
//printf("overriding param %s=%f by =%f\n", name_, value_, *vec->double_params[i]);
value_ = *vec->double_params[i];
}
}
}

private:
double value_;
Expand Down
41 changes: 41 additions & 0 deletions src/dict/dict.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,47 @@ void Dict::LoadLSTM(const STRING &lang, TessdataManager *data_file) {
lang, TESSDATA_LSTM_NUMBER_DAWG, dawg_debug_level, data_file);
if (number_dawg) dawgs_ += number_dawg;
}

// stolen from Dict::Load (but needs params_ from Tesseract langdata/config/api):
STRING name;
if (((STRING &)user_words_suffix).length() > 0 ||
((STRING &)user_words_file).length() > 0) {
Trie *trie_ptr = new Trie(DAWG_TYPE_WORD, lang, USER_DAWG_PERM,
getUnicharset().size(), dawg_debug_level);
if (((STRING &)user_words_file).length() > 0) {
name = user_words_file;
} else {
name = getCCUtil()->language_data_path_prefix;
name += user_words_suffix;
}
if (!trie_ptr->read_and_add_word_list(name.string(), getUnicharset(),
Trie::RRP_REVERSE_IF_HAS_RTL)) {
tprintf("Error: failed to load %s\n", name.string());
delete trie_ptr;
} else {
dawgs_ += trie_ptr;
}
}

if (((STRING &)user_patterns_suffix).length() > 0 ||
((STRING &)user_patterns_file).length() > 0) {
Trie *trie_ptr = new Trie(DAWG_TYPE_PATTERN, lang, USER_PATTERN_PERM,
getUnicharset().size(), dawg_debug_level);
trie_ptr->initialize_patterns(&(getUnicharset()));
if (((STRING &)user_patterns_file).length() > 0) {
name = user_patterns_file;
} else {
name = getCCUtil()->language_data_path_prefix;
name += user_patterns_suffix;
}
if (!trie_ptr->read_pattern_list(name.string(), getUnicharset())) {
tprintf("Error: failed to load %s\n", name.string());
delete trie_ptr;
} else {
dawgs_ += trie_ptr;
}
}

}

// Completes the loading process after Load() and/or LoadLSTM().
Expand Down
11 changes: 8 additions & 3 deletions src/lstm/lstmrecognizer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,13 @@ LSTMRecognizer::~LSTMRecognizer() {
}

// Loads a model from mgr, including the dictionary only if lang is not null.
bool LSTMRecognizer::Load(const char* lang, TessdataManager* mgr) {
bool LSTMRecognizer::Load(const ParamsVectors* params, const char* lang, TessdataManager* mgr) {
TFile fp;
if (!mgr->GetComponent(TESSDATA_LSTM, &fp)) return false;
if (!DeSerialize(mgr, &fp)) return false;
if (lang == nullptr) return true;
// Allow it to run without a dictionary.
LoadDictionary(lang, mgr);
LoadDictionary(params, lang, mgr);
return true;
}

Expand Down Expand Up @@ -154,9 +154,14 @@ bool LSTMRecognizer::LoadRecoder(TFile* fp) {
// on the unicharset matching. This enables training to deserialize a model
// from checkpoint or restore without having to go back and reload the
// dictionary.
bool LSTMRecognizer::LoadDictionary(const char* lang, TessdataManager* mgr) {
// Some parameters have to be passed in (from langdata/config/api via Tesseract)
bool LSTMRecognizer::LoadDictionary(const ParamsVectors* params, const char* lang, TessdataManager* mgr) {
delete dict_;
dict_ = new Dict(&ccutil_);
dict_->user_words_file.ResetFrom(params);
dict_->user_words_suffix.ResetFrom(params);
dict_->user_patterns_file.ResetFrom(params);
dict_->user_patterns_suffix.ResetFrom(params);
dict_->SetupForLoad(Dict::GlobalDawgCache());
dict_->LoadLSTM(lang, mgr);
if (dict_->FinishLoad()) return true; // Success.
Expand Down
5 changes: 3 additions & 2 deletions src/lstm/lstmrecognizer.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@
#include "matrix.h"
#include "network.h"
#include "networkscratch.h"
#include "params.h"
#include "recodebeam.h"
#include "series.h"
#include "strngs.h"
Expand Down Expand Up @@ -154,7 +155,7 @@ class LSTMRecognizer {
int null_char() const { return null_char_; }

// Loads a model from mgr, including the dictionary only if lang is not null.
bool Load(const char* lang, TessdataManager* mgr);
bool Load(const ParamsVectors* params, const char* lang, TessdataManager* mgr);

// Writes to the given file. Returns false in case of error.
// If mgr contains a unicharset and recoder, then they are not encoded to fp.
Expand All @@ -174,7 +175,7 @@ class LSTMRecognizer {
// on the unicharset matching. This enables training to deserialize a model
// from checkpoint or restore without having to go back and reload the
// dictionary.
bool LoadDictionary(const char* lang, TessdataManager* mgr);
bool LoadDictionary(const ParamsVectors* params, const char* lang, TessdataManager* mgr);

// Recognizes the line image, contained within image_data, returning the
// recognized tesseract WERD_RES for the words.
Expand Down

0 comments on commit 297d7d8

Please sign in to comment.