21 #include "allheaders.h" 46 const STRING& output_basename,
47 BLOCK_LIST *block_list) {
48 STRING lstmf_name = output_basename +
".lstmf";
53 tprintf(
"Failed to read training data from %s!\n", lstmf_name.
string());
63 tprintf(
"Failed to read boxes from %s\n", input_imagename.
string());
69 tprintf(
"Failed to write training data to %s!\n", lstmf_name.
string());
78 BLOCK_LIST *block_list,
80 int box_count = boxes.
size();
85 while (end_box < texts.
size() && texts[end_box] ==
"\t") ++end_box;
86 for (
int start_box = end_box; start_box < box_count; start_box = end_box) {
88 TBOX line_box = boxes[start_box];
89 STRING line_str = texts[start_box];
90 for (end_box = start_box + 1; end_box < box_count && texts[end_box] !=
"\t";
92 line_box += boxes[end_box];
93 line_str += texts[end_box];
96 BLOCK* best_block = NULL;
98 BLOCK_IT b_it(block_list);
99 for (b_it.mark_cycle_pt(); !b_it.cycled_list(); b_it.forward()) {
100 BLOCK* block = b_it.data();
107 if (overlap_box.
area() > best_overlap) {
108 best_overlap = overlap_box.
area();
114 if (best_block == NULL) {
115 tprintf(
"No block overlapping textline: %s\n", line_str.
string());
117 imagedata =
GetLineData(line_box, boxes, texts, start_box, end_box,
120 if (imagedata != NULL)
124 while (end_box < texts.
size() && texts[end_box] ==
"\t") ++end_box;
134 int start_box,
int end_box,
135 const BLOCK& block) {
139 if (image_data == NULL)
return NULL;
146 for (
int b = start_box; b < end_box; ++b) {
148 box.
rotate(block_rotation);
155 image_data->
AddBoxes(line_boxes, line_texts, page_numbers);
166 int padding,
TBOX* revised_box)
const {
168 wbox.
pad(padding, padding);
172 int num_rotations = 0;
186 int width = pixGetWidth(pix);
187 int height = pixGetHeight(pix);
188 TBOX image_box(0, 0, width, height);
190 *revised_box &= image_box;
191 if (revised_box->
null_box())
return NULL;
192 Box* clip_box = boxCreate(revised_box->
left(), height - revised_box->
top(),
194 Pix* box_pix = pixClipRectangle(pix, clip_box, NULL);
195 if (box_pix == NULL)
return NULL;
196 boxDestroy(&clip_box);
197 if (num_rotations > 0) {
198 Pix* rot_pix = pixRotateOrth(box_pix, num_rotations);
199 pixDestroy(&box_pix);
203 int depth = pixGetDepth(box_pix);
206 grey = pixConvertTo8(box_pix,
false);
207 pixDestroy(&box_pix);
210 bool vertical_text =
false;
211 if (num_rotations > 0) {
214 revised_box->
rotate(rotation);
215 if (num_rotations != 2)
216 vertical_text =
true;
218 return new ImageData(vertical_text, box_pix);
221 #ifndef ANDROID_BUILD 241 if (im_data == NULL)
return;
243 kWorstDictCertainty / kCertaintyScale,
258 const Dict* stopper_dict = lstm_recognizer_->
GetDict();
259 if (stopper_dict ==
nullptr) stopper_dict = &
getDict();
260 bool any_nonspace_delimited =
false;
261 for (
int w = 0; w < words->
size(); ++w) {
265 any_nonspace_delimited =
true;
269 for (
int w = 0; w < words->
size(); ++w) {
305 tprintf(
"Best choice certainty=%g, space=%g, scaled=%g, final=%g\n",
316 any_nonspace_delimited ||
317 (word_certainty >= kWorstDictCertainty &&
321 if (
getDict().stopper_debug_level >= 1) {
322 tprintf(
"Deleting word with certainty %g\n", word_certainty);
331 #endif // ANDROID_BUILD ImageData * GetRectImage(const TBOX &box, const BLOCK &block, int padding, TBOX *revised_box) const
void AddBoxes(const GenericVector< TBOX > &boxes, const GenericVector< STRING > &texts, const GenericVector< int > &box_pages)
void set_certainty(float new_val)
bool ContainsAnyNonSpaceDelimited() const
TBOX intersection(const TBOX &box) const
const float kNonDictionaryPenalty
void RecognizeLine(const ImageData &image_data, bool invert, bool debug, double worst_dict_cert, bool use_alternates, const UNICHARSET *target_unicharset, const TBOX &line_box, float score_ratio, bool one_word, PointerVector< WERD_RES > *words)
void init_to_size(int size, T t)
GenericVector< int > best_state
static const float kMinCertainty
WERD_CHOICE * best_choice
void bounding_box(ICOORD &bottom_left, ICOORD &top_right) const
get box
Treat the image as a single word.
static bool valid_word_permuter(uinT8 perm, bool numbers_ok)
Check all the DAWGs to see if this word is in any of them.
void AddPageToDocument(ImageData *page)
const UNICHARSET & GetUnicharset() const
void LSTMRecognizeWord(const BLOCK &block, ROW *row, WERD_RES *word, PointerVector< WERD_RES > *words)
const char * string() const
int tessedit_pageseg_mode
const float kWorstDictCertainty
TBOX bounding_box() const
tesseract::Tesseract * tesseract
void SearchWords(PointerVector< WERD_RES > *words)
void SetupWordScript(const UNICHARSET &unicharset_in)
void SetupFake(const UNICHARSET &uch)
const float kCertaintyScale
const Dict * GetDict() const
void pad(int xpad, int ypad)
bool LoadDocument(const char *filename, int start_page, inT64 max_memory, FileReader reader)
bool major_overlap(const TBOX &box) const
const UNICHARSET * unicharset() const
int state(int index) const
bool SaveDocument(const char *filename, FileWriter writer)
POLY_BLOCK * poly_block() const
bool ReadAllBoxes(int target_page, bool skip_blanks, const STRING &filename, GenericVector< TBOX > *boxes, GenericVector< STRING > *texts, GenericVector< STRING > *box_texts, GenericVector< int > *pages)
void set_page_number(int num)
void TrainLineRecognizer(const STRING &input_imagename, const STRING &output_basename, BLOCK_LIST *block_list)
FCOORD re_rotation() const
bool AcceptableResult(WERD_RES *word) const
void move(const ICOORD vec)
const ICOORD & botleft() const
void TrainFromBoxes(const GenericVector< TBOX > &boxes, const GenericVector< STRING > &texts, BLOCK_LIST *block_list, DocumentData *training_data)
ImageData * GetLineData(const TBOX &line_box, const GenericVector< TBOX > &boxes, const GenericVector< STRING > &texts, int start_box, int end_box, const BLOCK &block)
float base_line(float xpos) const
void initialise(inT16 length)
void set_permuter(uinT8 perm)
void rotate(const FCOORD &vec)
void WordSearch(WERD_RES *word_res)