Skip to content

Commit bc2b919

Browse files
committed
Integrated Timesteps per symbol into ChoiceIterator
Signed-off-by: Noah Metzger <[email protected]>
1 parent 754e38d commit bc2b919

File tree

2 files changed

+67
-53
lines changed

2 files changed

+67
-53
lines changed

src/ccmain/ltrresultiterator.cpp

+57-53
Original file line numberDiff line numberDiff line change
@@ -28,14 +28,13 @@
2828
namespace tesseract {
2929

3030
LTRResultIterator::LTRResultIterator(PAGE_RES* page_res, Tesseract* tesseract,
31-
int scale, int scaled_yres,
32-
int rect_left, int rect_top,
33-
int rect_width, int rect_height)
34-
: PageIterator(page_res, tesseract, scale, scaled_yres,
35-
rect_left, rect_top, rect_width, rect_height),
36-
line_separator_("\n"),
37-
paragraph_separator_("\n") {
38-
}
31+
int scale, int scaled_yres, int rect_left,
32+
int rect_top, int rect_width,
33+
int rect_height)
34+
: PageIterator(page_res, tesseract, scale, scaled_yres, rect_left, rect_top,
35+
rect_width, rect_height),
36+
line_separator_("\n"),
37+
paragraph_separator_("\n") {}
3938

4039
// Destructor.
4140
// It is defined here, so the compiler can create a single vtable
@@ -57,9 +56,9 @@ char* LTRResultIterator::GetUTF8Text(PageIteratorLevel level) const {
5756
} else {
5857
bool eol = false; // end of line?
5958
bool eop = false; // end of paragraph?
60-
do { // for each paragraph in a block
61-
do { // for each text line in a paragraph
62-
do { // for each word in a text line
59+
do { // for each paragraph in a block
60+
do { // for each text line in a paragraph
61+
do { // for each word in a text line
6362
best_choice = res_it.word()->best_choice;
6463
ASSERT_HOST(best_choice != nullptr);
6564
text += best_choice->unichar_string();
@@ -70,7 +69,7 @@ char* LTRResultIterator::GetUTF8Text(PageIteratorLevel level) const {
7069
text.truncate_at(text.length() - 1);
7170
text += line_separator_;
7271
eop = res_it.block() != res_it.prev_block() ||
73-
res_it.row()->row->para() != res_it.prev_row()->row->para();
72+
res_it.row()->row->para() != res_it.prev_row()->row->para();
7473
} while (level != RIL_TEXTLINE && !eop);
7574
if (eop) text += paragraph_separator_;
7675
} while (level == RIL_BLOCK && res_it.block() == res_it.prev_block());
@@ -82,12 +81,12 @@ char* LTRResultIterator::GetUTF8Text(PageIteratorLevel level) const {
8281
}
8382

8483
// Set the string inserted at the end of each text line. "\n" by default.
85-
void LTRResultIterator::SetLineSeparator(const char *new_line) {
84+
void LTRResultIterator::SetLineSeparator(const char* new_line) {
8685
line_separator_ = new_line;
8786
}
8887

8988
// Set the string inserted at the end of each paragraph. "\n" by default.
90-
void LTRResultIterator::SetParagraphSeparator(const char *new_para) {
89+
void LTRResultIterator::SetParagraphSeparator(const char* new_para) {
9190
paragraph_separator_ = new_para;
9291
}
9392

@@ -131,7 +130,7 @@ float LTRResultIterator::Confidence(PageIteratorLevel level) const {
131130
break;
132131
case RIL_WORD:
133132
mean_certainty += best_choice->certainty();
134-
++certainty_count;
133+
++certainty_count;
135134
break;
136135
case RIL_SYMBOL:
137136
mean_certainty += best_choice->certainty(blob_index_);
@@ -163,26 +162,23 @@ void LTRResultIterator::RowAttributes(float* row_height, float* descenders,
163162
// the iterator itself, ie rendered invalid by various members of
164163
// TessBaseAPI, including Init, SetImage, End or deleting the TessBaseAPI.
165164
// Pointsize is returned in printers points (1/72 inch.)
166-
const char* LTRResultIterator::WordFontAttributes(bool* is_bold,
167-
bool* is_italic,
168-
bool* is_underlined,
169-
bool* is_monospace,
170-
bool* is_serif,
171-
bool* is_smallcaps,
172-
int* pointsize,
173-
int* font_id) const {
165+
const char* LTRResultIterator::WordFontAttributes(
166+
bool* is_bold, bool* is_italic, bool* is_underlined, bool* is_monospace,
167+
bool* is_serif, bool* is_smallcaps, int* pointsize, int* font_id) const {
174168
const char* result = nullptr;
175169

176170
if (it_->word() == nullptr) {
177171
// Already at the end!
178172
*pointsize = 0;
179173
} else {
180174
float row_height = it_->row()->row->x_height() +
181-
it_->row()->row->ascenders() - it_->row()->row->descenders();
175+
it_->row()->row->ascenders() -
176+
it_->row()->row->descenders();
182177
// Convert from pixels to printers points.
183-
*pointsize = scaled_yres_ > 0
184-
? static_cast<int>(row_height * kPointsPerInch / scaled_yres_ + 0.5)
185-
: 0;
178+
*pointsize =
179+
scaled_yres_ > 0
180+
? static_cast<int>(row_height * kPointsPerInch / scaled_yres_ + 0.5)
181+
: 0;
186182
const FontInfo* font_info = it_->word()->fontinfo;
187183
if (font_info) {
188184
// Font information available.
@@ -212,7 +208,8 @@ const char* LTRResultIterator::WordFontAttributes(bool* is_bold,
212208

213209
// Returns the name of the language used to recognize this word.
214210
const char* LTRResultIterator::WordRecognitionLanguage() const {
215-
if (it_->word() == nullptr || it_->word()->tesseract == nullptr) return nullptr;
211+
if (it_->word() == nullptr || it_->word()->tesseract == nullptr)
212+
return nullptr;
216213
return it_->word()->tesseract->lang.string();
217214
}
218215

@@ -221,12 +218,9 @@ StrongScriptDirection LTRResultIterator::WordDirection() const {
221218
if (it_->word() == nullptr) return DIR_NEUTRAL;
222219
bool has_rtl = it_->word()->AnyRtlCharsInWord();
223220
bool has_ltr = it_->word()->AnyLtrCharsInWord();
224-
if (has_rtl && !has_ltr)
225-
return DIR_RIGHT_TO_LEFT;
226-
if (has_ltr && !has_rtl)
227-
return DIR_LEFT_TO_RIGHT;
228-
if (!has_ltr && !has_rtl)
229-
return DIR_NEUTRAL;
221+
if (has_rtl && !has_ltr) return DIR_RIGHT_TO_LEFT;
222+
if (has_ltr && !has_rtl) return DIR_LEFT_TO_RIGHT;
223+
if (!has_ltr && !has_rtl) return DIR_NEUTRAL;
230224
return DIR_MIX;
231225
}
232226

@@ -259,20 +253,21 @@ bool LTRResultIterator::HasBlamerInfo() const {
259253

260254
// Returns the pointer to ParamsTrainingBundle stored in the BlamerBundle
261255
// of the current word.
262-
const void *LTRResultIterator::GetParamsTrainingBundle() const {
263-
return (it_->word() != nullptr && it_->word()->blamer_bundle != nullptr) ?
264-
&(it_->word()->blamer_bundle->params_training_bundle()) : nullptr;
256+
const void* LTRResultIterator::GetParamsTrainingBundle() const {
257+
return (it_->word() != nullptr && it_->word()->blamer_bundle != nullptr)
258+
? &(it_->word()->blamer_bundle->params_training_bundle())
259+
: nullptr;
265260
}
266261

267262
// Returns the pointer to the string with blamer information for this word.
268263
// Assumes that the word's blamer_bundle is not nullptr.
269-
const char *LTRResultIterator::GetBlamerDebug() const {
264+
const char* LTRResultIterator::GetBlamerDebug() const {
270265
return it_->word()->blamer_bundle->debug().string();
271266
}
272267

273268
// Returns the pointer to the string with misadaption information for this word.
274269
// Assumes that the word's blamer_bundle is not nullptr.
275-
const char *LTRResultIterator::GetBlamerMisadaptionDebug() const {
270+
const char* LTRResultIterator::GetBlamerMisadaptionDebug() const {
276271
return it_->word()->blamer_bundle->misadaption_debug().string();
277272
}
278273

@@ -288,7 +283,7 @@ bool LTRResultIterator::HasTruthString() const {
288283

289284
// Returns true if the given string is equivalent to the truth string for
290285
// the current word.
291-
bool LTRResultIterator::EquivalentToTruth(const char *str) const {
286+
bool LTRResultIterator::EquivalentToTruth(const char* str) const {
292287
if (!HasTruthString()) return false;
293288
ASSERT_HOST(it_->word()->uch_set != nullptr);
294289
WERD_CHOICE str_wd(str, *(it_->word()->uch_set));
@@ -312,7 +307,7 @@ char* LTRResultIterator::WordNormedUTF8Text() const {
312307
if (it_->word() == nullptr) return nullptr; // Already at the end!
313308
STRING ocr_text;
314309
WERD_CHOICE* best_choice = it_->word()->best_choice;
315-
const UNICHARSET *unicharset = it_->word()->uch_set;
310+
const UNICHARSET* unicharset = it_->word()->uch_set;
316311
ASSERT_HOST(best_choice != nullptr);
317312
for (int i = 0; i < best_choice->length(); ++i) {
318313
ocr_text += unicharset->get_normed_unichar(best_choice->unichar_id(i));
@@ -325,7 +320,7 @@ char* LTRResultIterator::WordNormedUTF8Text() const {
325320

326321
// Returns a pointer to serialized choice lattice.
327322
// Fills lattice_size with the number of bytes in lattice data.
328-
const char *LTRResultIterator::WordLattice(int *lattice_size) const {
323+
const char* LTRResultIterator::WordLattice(int* lattice_size) const {
329324
if (it_->word() == nullptr) return nullptr; // Already at the end!
330325
if (it_->word()->blamer_bundle == nullptr) return nullptr;
331326
*lattice_size = it_->word()->blamer_bundle->lattice_size();
@@ -338,7 +333,7 @@ const char *LTRResultIterator::WordLattice(int *lattice_size) const {
338333
bool LTRResultIterator::SymbolIsSuperscript() const {
339334
if (cblob_it_ == nullptr && it_->word() != nullptr)
340335
return it_->word()->best_choice->BlobPosition(blob_index_) ==
341-
SP_SUPERSCRIPT;
336+
SP_SUPERSCRIPT;
342337
return false;
343338
}
344339

@@ -372,40 +367,49 @@ ChoiceIterator::ChoiceIterator(const LTRResultIterator& result_it) {
372367
} else {
373368
choice_it_ = nullptr;
374369
}
370+
if (&word_res_->symbol_steps != nullptr && !word_res_->symbol_steps.empty()) {
371+
symbol_step_it_ = word_res_->symbol_steps.begin();
372+
}
375373
}
376374

377-
ChoiceIterator::~ChoiceIterator() {
378-
delete choice_it_;
379-
}
375+
ChoiceIterator::~ChoiceIterator() { delete choice_it_; }
380376

381377
// Moves to the next choice for the symbol and returns false if there
382378
// are none left.
383379
bool ChoiceIterator::Next() {
384-
if (choice_it_ == nullptr)
385-
return false;
380+
if (choice_it_ == nullptr) return false;
381+
if (&word_res_->symbol_steps != nullptr) {
382+
if (symbol_step_it_ == word_res_->symbol_steps.end()) {
383+
symbol_step_it_ = word_res_->symbol_steps.begin();
384+
} else {
385+
symbol_step_it_++;
386+
}
387+
}
386388
choice_it_->forward();
387389
return !choice_it_->cycled_list();
388390
}
389391

390392
// Returns the null terminated UTF-8 encoded text string for the current
391393
// choice. Do NOT use delete [] to free after use.
392394
const char* ChoiceIterator::GetUTF8Text() const {
393-
if (choice_it_ == nullptr)
394-
return nullptr;
395+
if (choice_it_ == nullptr) return nullptr;
395396
UNICHAR_ID id = choice_it_->data()->unichar_id();
396397
return word_res_->uch_set->id_to_unichar_ext(id);
397398
}
398399

399400
// Returns the confidence of the current choice.
400401
// The number should be interpreted as a percent probability. (0.0f-100.0f)
401402
float ChoiceIterator::Confidence() const {
402-
if (choice_it_ == nullptr)
403-
return 0.0f;
403+
if (choice_it_ == nullptr) return 0.0f;
404404
float confidence = 100 + 5 * choice_it_->data()->certainty();
405405
if (confidence < 0.0f) confidence = 0.0f;
406406
if (confidence > 100.0f) confidence = 100.0f;
407407
return confidence;
408408
}
409409

410-
410+
std::vector<std::vector<std::pair<const char*, float>>>*
411+
ChoiceIterator::Timesteps() const {
412+
if (&word_res_->symbol_steps == nullptr) return nullptr;
413+
return &*symbol_step_it_;
414+
}
411415
} // namespace tesseract.

src/ccmain/ltrresultiterator.h

+10
Original file line numberDiff line numberDiff line change
@@ -212,11 +212,21 @@ class ChoiceIterator {
212212
// The number should be interpreted as a percent probability. (0.0f-100.0f)
213213
float Confidence() const;
214214

215+
// Returns a vector containing all timesteps, which belong to the currently
216+
// selected symbol. A timestep is a vector containing pairs of symbols and
217+
// floating point numbers. The number states the probability for the
218+
// corresponding symbol.
219+
std::vector<std::vector<std::pair<const char*, float>>>*
220+
Timesteps() const;
221+
215222
private:
216223
// Pointer to the WERD_RES object owned by the API.
217224
WERD_RES* word_res_;
218225
// Iterator over the blob choices.
219226
BLOB_CHOICE_IT* choice_it_;
227+
//Iterator over the symbol steps.
228+
std::vector<std::vector<std::vector<std::pair<const char*, float>>>>::iterator
229+
symbol_step_it_;
220230
};
221231

222232
} // namespace tesseract.

0 commit comments

Comments
 (0)