19 #define _USE_MATH_DEFINES // for M_PI 23 #include "config_auto.h" 37 #include <sys/types.h> 52 #include "allheaders.h" 55 #include "config_auto.h" 66 #ifndef DISABLED_LEGACY_ENGINE 72 #if defined(USE_OPENCL) 93 static BOOL_VAR(stream_filelist,
false,
"Stream a filelist from stdin");
109 static const char* kInputFile =
"noname.tif";
113 static const char* kOldVarsFile =
"failed_vars.txt";
119 static void addAvailableLanguages(
const STRING &datadir,
const STRING &base,
122 const STRING base2 = (base.
string()[0] ==
'\0') ? base : base +
"/";
123 const size_t extlen =
sizeof(kTrainedDataSuffix);
125 WIN32_FIND_DATA data;
126 HANDLE handle = FindFirstFile((datadir + base2 +
"*").
string(), &data);
127 if (handle != INVALID_HANDLE_VALUE) {
130 char *name = data.cFileName;
132 if (name[0] !=
'.') {
133 if ((data.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ==
134 FILE_ATTRIBUTE_DIRECTORY) {
135 addAvailableLanguages(datadir, base2 + name, langs);
137 size_t len = strlen(name);
138 if (len > extlen && name[len - extlen] ==
'.' &&
139 strcmp(&name[len - extlen + 1], kTrainedDataSuffix) == 0) {
140 name[len - extlen] =
'\0';
145 result = FindNextFile(handle, &data);
150 DIR* dir = opendir((datadir + base).
string());
151 if (dir !=
nullptr) {
153 while ((de = readdir(dir))) {
154 char *name = de->d_name;
156 if (name[0] !=
'.') {
158 if (stat((datadir + base2 + name).
string(), &st) == 0 &&
159 (st.st_mode & S_IFDIR) == S_IFDIR) {
160 addAvailableLanguages(datadir, base2 + name, langs);
162 size_t len = strlen(name);
163 if (len > extlen && name[len - extlen] ==
'.' &&
164 strcmp(&name[len - extlen + 1], kTrainedDataSuffix) == 0) {
165 name[len - extlen] =
'\0';
177 static int CompareSTRING(
const void* p1,
const void* p2) {
178 const auto* s1 =
static_cast<const STRING*
>(p1);
179 const auto* s2 =
static_cast<const STRING*
>(p2);
180 return strcmp(s1->c_str(), s2->c_str());
184 : tesseract_(nullptr),
185 osd_tesseract_(nullptr),
186 equ_detect_(nullptr),
191 thresholder_(nullptr),
192 paragraph_models_(nullptr),
193 block_list_(nullptr),
195 input_file_(nullptr),
196 output_file_(nullptr),
200 recognition_done_(false),
216 std::locale::global(std::locale(
""));
228 return PACKAGE_VERSION;
240 ds_device device = OpenclDevice::getDeviceSelection();
241 if (device.type == DS_DEVICE_OPENCL_DEVICE) {
242 *data =
new cl_device_id;
243 memcpy(*data, &device.oclDeviceID,
sizeof(cl_device_id));
244 return sizeof(cl_device_id);
258 tprintf(
"Deprecated method CatchSignals has only a dummy implementation!\n");
293 auto *p = ParamUtils::FindParam<IntParam>(
295 if (p ==
nullptr)
return false;
296 *value = (int32_t)(*p);
301 auto *p = ParamUtils::FindParam<BoolParam>(
303 if (p ==
nullptr)
return false;
309 auto *p = ParamUtils::FindParam<StringParam>(
311 return (p !=
nullptr) ? p->string() :
nullptr;
315 auto *p = ParamUtils::FindParam<DoubleParam>(
317 if (p ==
nullptr)
return false;
318 *value = (double)(*p);
344 bool set_only_non_debug_params) {
345 return Init(datapath, 0, language, oem, configs, configs_size, vars_vec,
346 vars_values, set_only_non_debug_params,
nullptr);
356 bool set_only_non_debug_params,
FileReader reader) {
358 if (language ==
nullptr) language =
"eng";
359 STRING datapath = data_size == 0 ? data : language;
376 bool reset_classifier =
true;
378 reset_classifier =
false;
380 if (reader !=
nullptr)
reader_ = reader;
382 if (data_size != 0) {
388 language,
oem, configs, configs_size, vars_vec, vars_values,
389 set_only_non_debug_params, &mgr) != 0) {
409 #ifndef DISABLED_LEGACY_ENGINE 411 if (reset_classifier) {
414 #endif // ndef DISABLED_LEGACY_ENGINE 442 for (
int i = 0; i < num_subs; ++i)
455 langs->
sort(CompareSTRING);
460 #ifndef DISABLED_LEGACY_ENGINE 475 #endif // ndef DISABLED_LEGACY_ENGINE 484 #ifndef DISABLED_LEGACY_ENGINE 540 int width,
int height) {
541 if (
tesseract_ ==
nullptr || width < kMinRectSize || height < kMinRectSize)
546 int bits_per_pixel = bytes_per_pixel == 0 ? 1 : bytes_per_pixel * 8;
547 SetImage(imagedata, bytes_per_line * 8 / bits_per_pixel, height + top,
548 bytes_per_pixel, bytes_per_line);
554 #ifndef DISABLED_LEGACY_ENGINE 565 #endif // ndef DISABLED_LEGACY_ENGINE 575 int width,
int height,
576 int bytes_per_pixel,
int bytes_per_line) {
579 bytes_per_pixel, bytes_per_line);
588 tprintf(
"Please call SetImage before SetSourceResolution.\n");
601 if (pixGetSpp(pix) == 4 && pixGetInputFormat(pix) == IFF_PNG) {
603 Pix* p1 = pixRemoveAlpha(pix);
605 (void)pixCopy(pix, p1);
656 Pixa** pixa,
int** blockids,
int** paraids) {
658 pixa, blockids, paraids);
701 bool text_only,
bool raw_image,
702 const int raw_padding,
703 Pixa** pixa,
int** blockids,
706 if (page_it ==
nullptr)
708 if (page_it ==
nullptr)
712 int component_count = 0;
713 int left, top, right, bottom;
720 &left, &top, &right, &bottom);
726 level, &left, &top, &right, &bottom);
729 if (get_bbox->
Run() &&
732 }
while (page_it->
Next(level));
734 Boxa* boxa = boxaCreate(component_count);
736 *pixa = pixaCreate(component_count);
737 if (blockids !=
nullptr)
738 *blockids =
new int[component_count];
739 if (paraids !=
nullptr)
740 *paraids =
new int[component_count];
744 int component_index = 0;
747 if (get_bbox->
Run() &&
749 Box* lbox = boxCreate(left, top, right - left, bottom - top);
750 boxaAddBox(boxa, lbox, L_INSERT);
751 if (pixa !=
nullptr) {
759 pixaAddPix(*pixa, pix, L_INSERT);
760 pixaAddBox(*pixa, lbox, L_CLONE);
762 if (paraids !=
nullptr) {
763 (*paraids)[component_index] = paraid;
767 if (blockids !=
nullptr) {
768 (*blockids)[component_index] = blockid;
776 }
while (page_it->
Next(level));
838 #ifndef DISABLED_LEGACY_ENGINE 844 #endif // ndef DISABLED_LEGACY_ENGINE 859 #ifndef DISABLED_LEGACY_ENGINE 864 #endif // ndef DISABLED_LEGACY_ENGINE 879 #ifndef GRAPHICS_DISABLED 881 #endif // GRAPHICS_DISABLED 887 #ifndef DISABLED_LEGACY_ENGINE 897 fclose(training_output_file);
898 #endif // ndef DISABLED_LEGACY_ENGINE 901 bool wait_for_text =
true;
913 #ifndef DISABLED_LEGACY_ENGINE 919 tprintf(
"Please call SetImage before attempting recognition.\n");
936 while (page_res_it.
word() !=
nullptr) {
940 page_res_it.
row()->
row, word_res);
945 #endif // ndef DISABLED_LEGACY_ENGINE 970 bool TessBaseAPI::ProcessPagesFileList(FILE *flist,
972 const char* retry_config,
973 int timeout_millisec,
975 int tessedit_page_number) {
976 if (!flist && !buf)
return false;
977 int page = (tessedit_page_number >= 0) ? tessedit_page_number : 0;
982 buf->
split(
'\n', &lines);
983 if (lines.
empty())
return false;
987 for (
int i = 0; i < page; i++) {
989 if (fgets(pagename,
sizeof(pagename), flist) ==
nullptr)
break;
1001 if (fgets(pagename,
sizeof(pagename), flist) ==
nullptr)
break;
1003 if (page >= lines.
size())
break;
1004 snprintf(pagename,
sizeof(pagename),
"%s", lines[page].c_str());
1007 Pix *pix = pixRead(pagename);
1008 if (pix ==
nullptr) {
1009 tprintf(
"Image file %s cannot be read!\n", pagename);
1012 tprintf(
"Page %d : %s\n", page, pagename);
1013 bool r =
ProcessPage(pix, page, pagename, retry_config,
1014 timeout_millisec, renderer);
1016 if (!r)
return false;
1017 if (tessedit_page_number >= 0)
break;
1028 bool TessBaseAPI::ProcessPagesMultipageTiff(
const l_uint8 *data,
1030 const char* filename,
1031 const char* retry_config,
1032 int timeout_millisec,
1034 int tessedit_page_number) {
1035 #ifndef ANDROID_BUILD 1037 int page = (tessedit_page_number >= 0) ? tessedit_page_number : 0;
1040 if (tessedit_page_number >= 0) {
1041 page = tessedit_page_number;
1042 pix = (data) ? pixReadMemTiff(data, size, page)
1043 : pixReadTiff(filename, page);
1045 pix = (data) ? pixReadMemFromMultipageTiff(data, size, &offset)
1046 : pixReadFromMultipageTiff(filename, &offset);
1048 if (pix ==
nullptr)
break;
1049 tprintf(
"Page %d\n", page + 1);
1051 snprintf(page_str, kMaxIntSize - 1,
"%d", page);
1053 bool r =
ProcessPage(pix, page, filename, retry_config,
1054 timeout_millisec, renderer);
1056 if (!r)
return false;
1057 if (tessedit_page_number >= 0)
break;
1069 int timeout_millisec,
1073 #ifndef DISABLED_LEGACY_ENGINE 1081 #endif // ndef DISABLED_LEGACY_ENGINE 1097 const char* retry_config,
1098 int timeout_millisec,
1100 bool stdInput = !strcmp(filename,
"stdin") || !strcmp(filename,
"-");
1103 if (_setmode(_fileno(stdin), _O_BINARY) == -1)
1104 tprintf(
"ERROR: cin to binary: %s", strerror(errno));
1108 if (stream_filelist) {
1109 return ProcessPagesFileList(stdin,
nullptr, retry_config,
1110 timeout_millisec, renderer,
1118 const l_uint8 *data =
nullptr;
1120 buf.
assign((std::istreambuf_iterator<char>(std::cin)),
1121 (std::istreambuf_iterator<char>()));
1122 data =
reinterpret_cast<const l_uint8 *
>(buf.data());
1125 if (FILE* file = fopen(filename,
"rb")) {
1128 fprintf(stderr,
"Error, cannot read input file %s: %s\n",
1129 filename, strerror(errno));
1136 int r = (stdInput) ?
1137 findFileFormatBuffer(data, &format) :
1138 findFileFormat(filename, &format);
1141 if (r != 0 || format == IFF_UNKNOWN) {
1146 std::ifstream t(filename);
1147 std::string u((std::istreambuf_iterator<char>(t)),
1148 std::istreambuf_iterator<char>());
1151 return ProcessPagesFileList(
nullptr, &s, retry_config,
1152 timeout_millisec, renderer,
1157 bool tiff = (format == IFF_TIFF || format == IFF_TIFF_PACKBITS ||
1158 format == IFF_TIFF_RLE || format == IFF_TIFF_G3 ||
1159 format == IFF_TIFF_G4 || format == IFF_TIFF_LZW ||
1160 #if LIBLEPT_MAJOR_VERSION > 1 || LIBLEPT_MINOR_VERSION > 76 1161 format == IFF_TIFF_JPEG ||
1163 format == IFF_TIFF_ZIP);
1168 pix = (stdInput) ? pixReadMem(data, buf.size()) : pixRead(filename);
1169 if (pix ==
nullptr) {
1182 ProcessPagesMultipageTiff(data, buf.size(), filename, retry_config,
1183 timeout_millisec, renderer,
1186 timeout_millisec, renderer);
1192 if (!r || (renderer && !renderer->EndDocument())) {
1199 const char* retry_config,
int timeout_millisec,
1203 bool failed =
false;
1209 if (it ==
nullptr) {
1216 }
else if (timeout_millisec > 0) {
1219 monitor.
cancel =
nullptr;
1231 #ifndef ANDROID_BUILD 1233 pixWrite(
"tessinput.tif", page_pix, IFF_TIFF_G4);
1234 #endif // ANDROID_BUILD 1237 if (failed && retry_config !=
nullptr && retry_config[0] !=
'\0') {
1239 FILE* fp = fopen(kOldVarsFile,
"wb");
1240 if (fp ==
nullptr) {
1241 tprintf(
"Error, failed to open file \"%s\"\n", kOldVarsFile);
1254 if (renderer && !failed) {
1255 failed = !renderer->
AddImage(
this);
1318 text += para_text.get();
1320 char* result =
new char[text.
length() + 1];
1328 int left, top, right, bottom;
1329 it->
BoundingBox(level, &left, &top, &right, &bottom);
1345 int lcnt = 1, bcnt = 1, pcnt = 1, wcnt = 1;
1346 int page_id = page_number + 1;
1350 int page_num = page_id;
1365 tsv_str +=
"\t-1\t\n";
1385 AddBoxToTSV(res_it,
RIL_BLOCK, &tsv_str);
1386 tsv_str +=
"\t-1\t\n";
1397 AddBoxToTSV(res_it,
RIL_PARA, &tsv_str);
1398 tsv_str +=
"\t-1\t\n";
1409 tsv_str +=
"\t-1\t\n";
1413 int left, top, right, bottom;
1442 char* ret =
new char[tsv_str.
length() + 1];
1443 strcpy(ret, tsv_str.
string());
1484 int total_length = blob_count * kBytesPerBoxFileLine + utf8_length +
1486 char* result =
new char[total_length];
1488 int output_length = 0;
1491 int left, top, right, bottom;
1493 const std::unique_ptr<
char[]> text(
1497 for (
int i = 0; text[i] !=
'\0'; ++i) {
1501 snprintf(result + output_length, total_length - output_length,
1502 "%s %d %d %d %d %d\n", text.get(), left,
image_height_ - bottom,
1504 output_length += strlen(result + output_length);
1506 if (output_length + kMaxBytesPerLine > total_length)
1520 0x20ac, 0x201c, 0x201d, 0x2018, 0x2019, 0x2022, 0x2014, 0
1524 0x00a2, 0x0022, 0x0022, 0x0027, 0x0027, 0x00b7, 0x002d, 0
1536 bool tilde_crunch_written =
false;
1537 bool last_char_was_newline =
true;
1538 bool last_char_was_tilde =
false;
1542 char* result =
new char[total_length];
1550 (!tilde_crunch_written ||
1561 last_char_was_tilde =
false;
1563 if (!last_char_was_tilde) {
1565 last_char_was_tilde =
true;
1567 tilde_crunch_written =
true;
1568 last_char_was_newline =
false;
1573 tilde_crunch_written =
false;
1577 int length = lengths.
length();
1581 if (last_char_was_tilde &&
1582 word->
word->
space() == 0 && wordstr[offset] ==
' ') {
1586 offset = lengths[i++];
1588 if (i < length && wordstr[offset] != 0) {
1589 if (!last_char_was_newline)
1592 last_char_was_newline =
false;
1593 for (; i < length; offset += lengths[i++]) {
1594 if (wordstr[offset] ==
' ' ||
1595 wordstr[offset] == kTesseractReject) {
1597 last_char_was_tilde =
true;
1600 *ptr++ = kUNLVSuspect;
1601 UNICHAR ch(wordstr + offset, lengths[i]);
1603 for (
int j = 0; kUniChs[j] != 0; ++j) {
1604 if (kUniChs[j] == uni_ch) {
1605 uni_ch = kLatinChs[j];
1609 if (uni_ch <= 0xff) {
1610 *ptr++ =
static_cast<char>(uni_ch);
1611 last_char_was_tilde =
false;
1614 last_char_was_tilde =
true;
1623 tilde_crunch_written =
false;
1624 last_char_was_newline =
true;
1625 last_char_was_tilde =
false;
1633 #ifndef DISABLED_LEGACY_ENGINE 1645 const char** script_name,
1646 float* script_conf) {
1657 if (orient_deg) *orient_deg = orient_id * 90;
1662 *script_name = script;
1678 const char* script_name;
1688 std::stringstream stream;
1690 stream.imbue(std::locale::classic());
1692 stream.precision(2);
1695 <<
"Page number: " << page_number <<
"\n" 1696 <<
"Orientation in degrees: " << orient_deg <<
"\n" 1697 <<
"Rotate: " << rotate <<
"\n" 1698 <<
"Orientation confidence: " << orient_conf <<
"\n" 1699 <<
"Script: " << script_name <<
"\n" 1700 <<
"Script confidence: " << script_conf <<
"\n";
1701 const std::string& text = stream.str();
1702 char* result =
new char[text.length() + 1];
1703 strcpy(result, text.c_str());
1707 #endif // ndef DISABLED_LEGACY_ENGINE 1712 if (!conf)
return 0;
1715 while (*pt >= 0) sum += *pt++;
1716 if (pt != conf) sum /= pt - conf;
1731 int* conf =
new int[n_word+1];
1736 int w_conf =
static_cast<int>(100 + 5 * choice->
certainty());
1738 if (w_conf < 0) w_conf = 0;
1739 if (w_conf > 100) w_conf = 100;
1740 conf[n_word++] = w_conf;
1746 #ifndef DISABLED_LEGACY_ENGINE 1760 bool success =
true;
1764 const std::unique_ptr<const char[]> text(
GetUTF8Text());
1766 tprintf(
"Trying to adapt \"%s\" to \"%s\"\n", text.get(), wordstr);
1768 if (text !=
nullptr) {
1771 if (word_res !=
nullptr) {
1776 for (t = 0; text[t] !=
'\0'; ++t) {
1777 if (text[t] ==
'\n' || text[t] ==
' ')
1779 while (wordstr[w] ==
' ') ++w;
1780 if (text[t] != wordstr[w])
1784 if (text[t] !=
'\0' || wordstr[w] !=
'\0') {
1792 if (pr_it.
word() ==
nullptr)
1795 word_res = pr_it.
word();
1812 #endif // ndef DISABLED_LEGACY_ENGINE 1889 if (it ==
nullptr) {
1895 if (x2 <= x1) x2 = x1 + 1;
1897 *out_slope =
static_cast<float>(y2 - y1) / (x2 - x1);
1898 *out_offset =
static_cast<int>(y1 - *out_slope * x1);
1901 int left, top, right, bottom;
1911 *out_offset += bottom - std::max(left_y, right_y);
1914 *out_slope = -*out_slope;
1941 for (
int i = 0; i < num_subs; ++i) {
1947 #ifndef DISABLED_LEGACY_ENGINE 1952 #endif // ndef DISABLED_LEGACY_ENGINE 1957 tprintf(
"Please call Init before attempting to set an image.\n");
1974 if (*pix !=
nullptr)
1982 tprintf(
"Warning: User defined image dpi is outside of expected range " 1991 tprintf(
"Warning: Invalid resolution %d dpi. Using %d instead.\n",
2017 tprintf(
"Estimated internal resolution %d out of range! " 2018 "Corrected to %d.\n",
2028 tprintf(
"Please call SetImage before attempting recognition.\n");
2038 #ifndef DISABLED_LEGACY_ENGINE 2049 #ifndef DISABLED_LEGACY_ENGINE 2055 tprintf(
"Warning: Could not set equation detector\n");
2060 #endif // ndef DISABLED_LEGACY_ENGINE 2065 osd_tess ==
nullptr) {
2072 tprintf(
"Warning: Auto orientation and script detection requested," 2073 " but data path is undefined\n");
2078 nullptr, 0,
nullptr,
nullptr,
2079 false, &mgr) == 0) {
2084 tprintf(
"Warning: Auto orientation and script detection requested," 2085 " but osd language failed to load\n");
2132 int total_length = 2;
2133 int total_blobs = 0;
2139 if (choice !=
nullptr) {
2140 total_blobs += choice->
length() + 2;
2148 if (blob_count !=
nullptr)
2149 *blob_count = total_blobs;
2150 return total_length;
2153 #ifndef DISABLED_LEGACY_ENGINE 2171 #endif // ndef DISABLED_LEGACY_ENGINE 2192 bool** vertical_writing) {
2193 delete[] *block_orientation;
2194 *block_orientation =
nullptr;
2195 delete[] *vertical_writing;
2196 *vertical_writing =
nullptr;
2199 block_it.move_to_first();
2201 for (block_it.mark_cycle_pt(); !block_it.cycled_list(); block_it.forward()) {
2202 if (!block_it.data()->pdblk.poly_block()->IsText()) {
2208 tprintf(
"WARNING: Found no blocks\n");
2211 *block_orientation =
new int[num_blocks];
2212 *vertical_writing =
new bool[num_blocks];
2213 block_it.move_to_first();
2215 for (block_it.mark_cycle_pt(); !block_it.cycled_list();
2216 block_it.forward()) {
2217 if (!block_it.data()->pdblk.poly_block()->IsText()) {
2220 FCOORD re_rotation = block_it.data()->re_rotation();
2221 float re_theta = re_rotation.
angle();
2222 FCOORD classify_rotation = block_it.data()->classify_rotation();
2223 float classify_theta = classify_rotation.
angle();
2224 double rot_theta = - (re_theta - classify_theta) * 2.0 / M_PI;
2225 if (rot_theta < 0) rot_theta += 4;
2226 int num_rotations =
static_cast<int>(rot_theta + 0.5);
2227 (*block_orientation)[i] = num_rotations;
2230 (*vertical_writing)[i] = classify_rotation.
y() != 0.0f;
2237 int debug_level = 0;
2245 result_it, &models);
2271 for (ptr = text; *ptr; ptr++) {
2273 case '<': ret +=
"<";
break;
2274 case '>': ret +=
">";
break;
2275 case '&': ret +=
"&";
break;
2276 case '"': ret +=
""";
break;
2277 case '\'': ret +=
"'";
break;
2278 default: ret += *ptr;
2285 #ifndef DISABLED_LEGACY_ENGINE 2313 int32_t xstarts[] = {-32000};
2314 double quad_coeffs[] = {0, 0, baseline};
2319 ascender - (baseline + xheight),
2320 descender - baseline,
2327 int width = pixGetWidth(pix);
2328 int height = pixGetHeight(pix);
2329 BLOCK block(
"a character",
true, 0, 0, 0, 0, width, height);
2336 C_BLOB_IT c_blob_it(list);
2337 if (c_blob_it.empty())
2340 C_OUTLINE_IT ol_it(c_blob_it.data()->out_list());
2341 for (c_blob_it.forward();
2342 !c_blob_it.at_first();
2343 c_blob_it.forward()) {
2344 C_BLOB *c_blob = c_blob_it.data();
2345 ol_it.add_list_after(c_blob->
out_list());
2358 float x_center = (box.
left() + box.
right()) / 2.0f;
2361 tblob->
Normalize(
nullptr,
nullptr,
nullptr, x_center, baseline, scale, scale,
2369 static TBLOB *make_tesseract_blob(
float baseline,
float xheight,
2370 float descender,
float ascender,
2371 bool numeric_mode, Pix* pix) {
2394 TBLOB *blob = make_tesseract_blob(baseline, xheight, descender, ascender,
2398 float best_rating = -100;
2402 BLOB_CHOICE_LIST choices;
2404 BLOB_CHOICE_IT choice_it;
2405 choice_it.set_to_list(&choices);
2406 for (choice_it.mark_cycle_pt(); !choice_it.cycled_list();
2407 choice_it.forward()) {
2408 if (choice_it.data()->rating() > best_rating) {
2409 best_rating = choice_it.data()->rating();
2423 auto *page_res =
new PAGE_RES(
false, block_list,
2432 pass1_result =
new PAGE_RES(
false, block_list,
2435 return pass1_result;
2444 TESS_CHAR(
float _cost,
const char *repr,
int len = -1) : cost(_cost) {
2445 length = (len == -1 ? strlen(repr) : len);
2446 unicode_repr =
new char[length + 1];
2447 strncpy(unicode_repr, repr, length);
2451 : unicode_repr(nullptr),
2457 delete [] unicode_repr;
2464 static void add_space(TESS_CHAR_IT* it) {
2466 it->add_after_then_move(t);
2470 static float rating_to_cost(
float rating) {
2471 rating = 100 + rating;
2475 if (rating < 0) rating = 0;
2483 static void extract_result(TESS_CHAR_IT* out,
2487 while (page_res_it.
word() !=
nullptr) {
2495 int n = strlen(len);
2496 for (
int i = 0; i < n; i++) {
2500 out->add_after_then_move(tc);
2521 TESS_CHAR_LIST tess_chars;
2522 TESS_CHAR_IT tess_chars_it(&tess_chars);
2523 extract_result(&tess_chars_it, page_res);
2524 tess_chars_it.move_to_first();
2525 int n = tess_chars.length();
2527 *lengths =
new int[n];
2528 *costs =
new float[n];
2534 for (tess_chars_it.mark_cycle_pt();
2535 !tess_chars_it.cycled_list();
2536 tess_chars_it.forward(), i++) {
2538 text_len += (*lengths)[i] = tc->
length;
2539 (*costs)[i] = tc->
cost;
2543 (*y1)[i] = tc->
box.
top();
2545 char *p = *text =
new char[text_len];
2547 tess_chars_it.move_to_first();
2548 for (tess_chars_it.mark_cycle_pt();
2549 !tess_chars_it.cycled_list();
2550 tess_chars_it.forward()) {
2568 int* feature_outline_index) {
2574 &cn_features, &fx_info, &outline_counts);
2579 *num_features = cn_features.
size();
2580 memcpy(int_features, &cn_features[0], *num_features *
sizeof(cn_features[0]));
2582 if (feature_outline_index !=
nullptr) {
2584 for (
int i = 0; i < outline_counts.
size(); ++i) {
2585 while (f < outline_counts[i])
2586 feature_outline_index[f++] = i;
2594 int left,
int top,
int right,
int bottom) {
2595 TBOX box(left, bottom, right, top);
2596 BLOCK_IT b_it(blocks);
2597 for (b_it.mark_cycle_pt(); !b_it.cycled_list(); b_it.forward()) {
2598 BLOCK* block = b_it.data();
2602 for (r_it.mark_cycle_pt(); !r_it.cycled_list(); r_it.forward()) {
2603 ROW* row = r_it.data();
2607 for (w_it.mark_cycle_pt(); !w_it.cycled_list(); w_it.forward()) {
2608 WERD* word = w_it.data();
2619 int num_max_matches,
2622 int* num_matches_returned) {
2623 auto* choices =
new BLOB_CHOICE_LIST;
2625 BLOB_CHOICE_IT choices_it(choices);
2626 int& index = *num_matches_returned;
2628 for (choices_it.mark_cycle_pt();
2629 !choices_it.cycled_list() && index < num_max_matches;
2630 choices_it.forward()) {
2633 ratings[index] = choice->
rating();
2636 *num_matches_returned = index;
2639 #endif // ndef DISABLED_LEGACY_ENGINE bool WriteTRFile(const STRING &filename)
int IntCastRounded(double x)
void ResetAdaptiveClassifier()
double(Dict::* probability_in_context_)(const char *lang, const char *context, int context_bytes, const char *character, int character_bytes)
Probability in context function used by the ngram permuter.
void SetSourceResolution(int ppi)
UNICHAR_ID unichar_id() const
static ROW * FindRowForBox(BLOCK_LIST *blocks, int left, int top, int right, int bottom)
MutableIterator * GetMutableIterator()
STRING HOcrEscape(const char *text)
bool IsAtBeginningOf(PageIteratorLevel level) const override
void set_text(const char *new_text)
bool ProcessPage(Pix *pix, int page_index, const char *filename, const char *retry_config, int timeout_millisec, TessResultRenderer *renderer)
void GetLoadedLanguagesAsVector(GenericVector< STRING > *langs) const
Tesseract * osd_tesseract_
For orientation & script detection.
void GetAvailableLanguagesAsVector(GenericVector< STRING > *langs) const
const Dawg * GetDawg(int i) const
virtual char * GetUTF8Text(PageIteratorLevel level) const
bool BoundingBoxInternal(PageIteratorLevel level, int *left, int *top, int *right, int *bottom) const
bool GetIntVariable(const char *name, int *value) const
C_OUTLINE_LIST * out_list()
WERD_RES * restart_page()
void delete_data_pointers()
void ReadDebugConfigFile(const char *filename)
TESS_LOCAL void AdaptToCharacter(const char *unichar_repr, int length, float baseline, float xheight, float descender, float ascender)
bool major_overlap(const TBOX &box) const
bool tessedit_make_boxes_from_boxes
int valid_word(const WERD_CHOICE &word, bool numbers_ok) const
STRING * input_file_
Name used by training code.
static bool GetParamAsString(const char *name, const ParamsVectors *member_params, STRING *value)
float angle() const
find angle
void SetInputName(const char *name)
int GetScaleFactor() const
const char * GetInitLanguagesAsString() const
virtual bool Next(PageIteratorLevel level)
PageSegMode GetPageSegMode() const
bool IsEmpty() const
Return true if no image has been set.
virtual void Clear()
Destroy the Pix if there is one, freeing memory.
const char * GetStringVariable(const char *name) const
OcrEngineMode last_oem_requested_
Last ocr language mode requested.
void(Wordrec::* fill_lattice_)(const MATRIX &ratings, const WERD_CHOICE_LIST &best_choices, const UNICHARSET &unicharset, BlamerBundle *blamer_bundle)
static void ExtractFeatures(const TBLOB &blob, bool nonlinear_norm, GenericVector< INT_FEATURE_STRUCT > *bl_features, GenericVector< INT_FEATURE_STRUCT > *cn_features, INT_FX_RESULT_STRUCT *results, GenericVector< int > *outline_cn_counts)
bool IsBinary() const
Returns true if the source image is binary.
void set_pix_grey(Pix *grey_pix)
char * TesseractRect(const unsigned char *imagedata, int bytes_per_pixel, int bytes_per_line, int left, int top, int width, int height)
static void DeleteBlockList(BLOCK_LIST *block_list)
void SetRectangle(int left, int top, int width, int height)
Orientation and script detection only.
Tesseract * get_sub_lang(int index) const
TESS_LOCAL int TextLength(int *blob_count)
void AdaptiveClassifier(TBLOB *Blob, BLOB_CHOICE_LIST *Choices)
WERD_CHOICE * prev_word_best_choice_
bool PTIsTextType(PolyBlockType type)
Pix ** mutable_pix_binary()
bool Baseline(PageIteratorLevel level, int *x1, int *y1, int *x2, int *y2) const
STRING * datapath_
Current location of tessdata.
void PrepareForTessOCR(BLOCK_LIST *block_list, Tesseract *osd_tess, OSResults *osr)
GenericVector< IntParam * > int_params
tesseract::ParamsVectors * GlobalParams()
void SetImage(const unsigned char *imagedata, int width, int height, int bytes_per_pixel, int bytes_per_line)
ResultIterator * GetIterator()
bool tessedit_resegment_from_boxes
Pix * GetBinaryImage(PageIteratorLevel level) const
const int kMaxBytesPerLine
bool recog_all_words(PAGE_RES *page_res, ETEXT_DESC *monitor, const TBOX *target_word_box, const char *word_config, int dopasses)
Boxa * GetWords(Pixa **pixa)
static void PrintParams(FILE *fp, const ParamsVectors *member_params)
void AdaptToChar(TBLOB *Blob, CLASS_ID ClassId, int FontinfoId, float Threshold, ADAPT_TEMPLATES adaptive_templates)
ADAPT_TEMPLATES AdaptedTemplates
TBOX bounding_box() const
void set_min_orientation_margin(double margin)
void add_str_int(const char *str, int number)
const STRING & unichar_string() const
Pix * GetThresholdedImage()
TESS_LOCAL LTRResultIterator * GetLTRIterator()
void SetDictFunc(DictFunc f)
STRING * language_
Last initialized language.
void extract_edges(Pix *pix, BLOCK *block)
int init_tesseract_lm(const char *arg0, const char *textbase, const char *language, TessdataManager *mgr)
const char * get_script_from_script_id(int id) const
static ResultIterator * StartOfParagraph(const LTRResultIterator &resit)
BLOCK_RES * block() const
int IsValidWord(const char *word)
void ExtractFontName(const STRING &filename, STRING *fontname)
bool GetVariableAsString(const char *name, STRING *val)
bool IsValidCharacter(const char *utf8_character)
void ClearAdaptiveClassifier()
void DetectParagraphs(int debug_level, GenericVector< RowInfo > *row_infos, GenericVector< PARA * > *row_owners, PARA_LIST *paragraphs, GenericVector< ParagraphModel * > *models)
bool PSM_OSD_ENABLED(int pageseg_mode)
int GetScaledEstimatedResolution() const
void SetEquationDetect(EquationDetect *detector)
int GetSourceYResolution() const
void set_pix_thresholds(Pix *thresholds)
void ReadConfigFile(const char *filename)
static void NormalizeTBLOB(TBLOB *tblob, ROW *row, bool numeric_mode)
TBOX intersection(const TBOX &box) const
int SegmentPage(const STRING *input_file, BLOCK_LIST *blocks, Tesseract *osd_tess, OSResults *osr)
bool BoundingBox(PageIteratorLevel level, int *left, int *top, int *right, int *bottom) const
void ApplyBoxTraining(const STRING &fontname, PAGE_RES *page_res)
const TBOX & BlobBox(int index) const
const char * id_to_unichar(UNICHAR_ID id) const
void InitForAnalysePage()
const int kBytesPer64BitNumber
BLOCK_LIST * FindLinesCreateBlockList()
void SetBlackAndWhitelist()
bool GetBoolVariable(const char *name, bool *value) const
bool interactive_display_mode
virtual void Run(A1, A2, A3, A4)=0
void SetImage(const unsigned char *imagedata, int width, int height, int bytes_per_pixel, int bytes_per_line)
bool ProcessPagesInternal(const char *filename, const char *retry_config, int timeout_millisec, TessResultRenderer *renderer)
PolyBlockType BlockType() const
double matcher_good_threshold
const char * GetDatapath()
void set_pix_original(Pix *original_pix)
bool AdaptToWordStr(PageSegMode mode, const char *wordstr)
bool GetDoubleVariable(const char *name, double *value) const
Automatic page segmentation, but no OSD, or OCR.
TESS_LOCAL PAGE_RES * RecognitionPass2(BLOCK_LIST *block_list, PAGE_RES *pass1_result)
virtual TESS_LOCAL bool Threshold(Pix **pix)
bool LoadMemBuffer(const char *name, const char *data, int size)
static void ResetToDefaults(ParamsVectors *member_params)
int(Dict::*)(void *, const UNICHARSET &, UNICHAR_ID, bool) const DictFunc
const Dawg * GetDawg(int index) const
Return i-th dawg pointer recorded in the dawgs_ vector.
#define MAX_NUM_INT_FEATURES
static TESS_LOCAL int TesseractExtractResult(char **text, int **lengths, float **costs, int **x0, int **y0, int **x1, int **y1, PAGE_RES *page_res)
GenericVector< BoolParam * > bool_params
void bounding_box(ICOORD &bottom_left, ICOORD &top_right) const
get box
FileReader reader_
Reads files from any filesystem.
Pix * pix_original() const
bool SetDebugVariable(const char *name, const char *value)
Boxa * GetTextlines(bool raw_image, int raw_padding, Pixa **pixa, int **blockids, int **paraids)
static size_t getOpenCLDevice(void **device)
static const char * Version()
TESS_LOCAL PAGE_RES * RecognitionPass1(BLOCK_LIST *block_list)
const int kBlnBaselineOffset
#define ELISTIZE(CLASSNAME)
void SetPageSegMode(PageSegMode mode)
void chomp_string(char *str)
TESS_LOCAL void DetectParagraphs(bool after_text_recognition)
Boxa * GetConnectedComponents(Pixa **cc)
constexpr int kMaxCredibleResolution
TruthCallback * truth_cb_
char * GetBoxText(int page_number)
const char kTesseractReject
Pix * GetImage(PageIteratorLevel level, int padding, Pix *original_img, int *left, int *top) const
bool tessedit_train_from_boxes
void MaximallyChopWord(const GenericVector< TBOX > &boxes, BLOCK *block, ROW *row, WERD_RES *word_res)
CRUNCH_MODE unlv_crunch_mode
void SetSourceYResolution(int ppi)
void * cancel_this
monitor-aware progress callback
void SetInputImage(Pix *pix)
bool IsAtFinalElement(PageIteratorLevel level, PageIteratorLevel element) const override
char * GetOsdText(int page_number)
int RecognizeForChopTest(ETEXT_DESC *monitor)
Boxa * GetStrips(Pixa **pixa, int **blockids)
static ROW * MakeTessOCRRow(float baseline, float xheight, float descender, float ascender)
static void ClearPersistentCache()
UNICHAR_ID unichar_to_id(const char *const unichar_repr) const
void ReSegmentByClassification(PAGE_RES *page_res)
int num_sub_langs() const
bool tessedit_write_images
int NumDawgs() const
Return the number of dawgs in the dawgs_ vector.
void PrintVariables(FILE *fp) const
int orientation_and_script_detection(STRING &filename, OSResults *osr, tesseract::Tesseract *tess)
const char * string() const
PAGE_RES * SetupApplyBoxes(const GenericVector< TBOX > &boxes, BLOCK_LIST *block_list)
void TidyUp(PAGE_RES *page_res)
DLLSYM void tprintf(const char *format,...)
char * GetTSVText(int page_number)
void recog_training_segmented(const STRING &fname, PAGE_RES *page_res, volatile ETEXT_DESC *monitor, FILE *output_file)
bool(*)(const STRING &, GenericVector< char > *) FileReader
void(Wordrec::*)(const MATRIX &, const WERD_CHOICE_LIST &, const UNICHARSET &, BlamerBundle *) FillLatticeFunc
void assign(const char *cstr, int len)
bool AddImage(TessBaseAPI *api)
bool GetTextDirection(int *out_offset, float *out_slope)
tesseract::BoxWord * box_word
void SetProbabilityInContextFunc(ProbabilityInContextFunc f)
Dict & getDict() override
virtual Pix * GetPixRectGrey()
const int kBytesPerNumber
bool BeginDocument(const char *title)
int(Dict::* letter_is_okay_)(void *void_dawg_args, const UNICHARSET &unicharset, UNICHAR_ID unichar_id, bool word_end) const
PDBLK pdblk
Page Description Block.
bool recognition_done_
page_res_ contains recognition data.
int GetScaledYResolution() const
void set_deadline_msecs(int32_t deadline_msecs)
void SetRectangle(int left, int top, int width, int height)
#define ELISTIZEH(CLASSNAME)
TESS_API int get_best_script(int orientation_id) const
void GetFeaturesForBlob(TBLOB *blob, INT_FEATURE_STRUCT *int_features, int *num_features, int *feature_outline_index)
bool contains_unichar(const char *const unichar_repr) const
int InitLangMod(const char *datapath, const char *language)
Tesseract * tesseract() const
void TrainLineRecognizer(const STRING &input_imagename, const STRING &output_basename, BLOCK_LIST *block_list)
void RunAdaptiveClassifier(TBLOB *blob, int num_max_matches, int *unichar_ids, float *ratings, int *num_matches_returned)
TBOX bounding_box() const
static bool SetParam(const char *name, const char *value, SetParamConstraint constraint, ParamsVectors *member_params)
void BestChoiceToCorrectText()
OcrEngineMode oem() const
void set_unlv_suspects(WERD_RES *word)
TESS_LOCAL int FindLines()
bool Empty(PageIteratorLevel level) const
bool tessedit_train_line_recognizer
bool tessedit_resegment_from_line_boxes
virtual bool ThresholdToPix(PageSegMode pageseg_mode, Pix **pix)
Returns false on error.
TESS_LOCAL bool InternalSetImage()
T ClipToRange(const T &x, const T &lower_bound, const T &upper_bound)
double min_orientation_margin
WERD_CHOICE * best_choice
int GetSourceYResolution()
GenericVector< ParagraphModel * > * paragraph_models_
virtual void GetImageSizes(int *left, int *top, int *width, int *height, int *imagewidth, int *imageheight)
PAGE_RES * page_res_
The page-level data.
static void CatchSignals()
void ResetDocumentDictionary()
void InitAdaptiveClassifier(TessdataManager *mgr)
float base_line(float xpos) const
bool ProcessPages(const char *filename, const char *retry_config, int timeout_millisec, TessResultRenderer *renderer)
Boxa * GetComponentImages(PageIteratorLevel level, bool text_only, bool raw_image, int raw_padding, Pixa **pixa, int **blockids, int **paraids)
constexpr int kMinCredibleResolution
const UNICHARSET & getUnicharset() const
int init_tesseract(const char *arg0, const char *textbase, const char *language, OcrEngineMode oem, char **configs, int configs_size, const GenericVector< STRING > *vars_vec, const GenericVector< STRING > *vars_values, bool set_only_init_params, TessdataManager *mgr)
void set_source_resolution(int ppi)
Boxa * GetRegions(Pixa **pixa)
bool tessedit_ambigs_training
bool flag(WERD_FLAGS mask) const
ImageThresholder * thresholder_
Image thresholding module.
char * GetUTF8Text(PageIteratorLevel level) const
TBOX bounding_box() const
#define BOOL_VAR(name, val, comment)
static TESS_API DawgCache * GlobalDawgCache()
bool Next(PageIteratorLevel level) override
_ConstTessMemberResultCallback_5_0< false, R, T1, P1, P2, P3, P4, P5 >::base * NewPermanentTessCallback(const T1 *obj, R(T2::*member)(P1, P2, P3, P4, P5) const, typename Identity< P1 >::type p1, typename Identity< P2 >::type p2, typename Identity< P3 >::type p3, typename Identity< P4 >::type p4, typename Identity< P5 >::type p5)
int OrientationIdToValue(const int &id)
void split(char c, GenericVector< STRING > *splited)
void LearnWord(const char *fontname, WERD_RES *word)
void SetFillLatticeFunc(FillLatticeFunc f)
STRING * output_file_
Name used by debug code.
GenericVector< StringParam * > string_params
virtual Pix * GetPixRectThresholds()
virtual bool IsAtFinalElement(PageIteratorLevel level, PageIteratorLevel element) const
static TBLOB * MakeTBLOB(Pix *pix)
TESS_CHAR(float _cost, const char *repr, int len=-1)
Tesseract * tesseract_
The underlying data object.
const STRING & unichar_lengths() const
double(Dict::*)(const char *, const char *, int, const char *, int) ProbabilityInContextFunc
GenericVector< DoubleParam * > double_params
ROW_LIST * row_list()
get rows
int tessedit_pageseg_mode
int Recognize(ETEXT_DESC *monitor)
bool SetVariable(const char *name, const char *value)
Assume a single uniform block of text. (Default.)
C_BLOB_LIST * blob_list()
get blobs
const int kBytesPerBoxFileLine
PageIterator * AnalyseLayout()
float Confidence(PageIteratorLevel level) const
void pgeditor_main(int width, int height, PAGE_RES *page_res)
bool textord_equation_detect
void GetBlockTextOrientations(int **block_orientation, bool **vertical_writing)
PAGE_RES * ApplyBoxes(const STRING &fname, bool find_segmentation, BLOCK_LIST *block_list)
void CorrectClassifyWords(PAGE_RES *page_res)
const char * GetUnichar(int unichar_id)
const int kNumbersPerBlob
const char * GetInputName()
static TBLOB * PolygonalCopy(bool allow_detailed_fx, C_BLOB *src)
bool DetectOS(OSResults *)
int Init(const char *datapath, const char *language, OcrEngineMode mode, char **configs, int configs_size, const GenericVector< STRING > *vars_vec, const GenericVector< STRING > *vars_values, bool set_only_non_debug_params)
EquationDetect * equ_detect_
The equation detector.
int GetThresholdedImageScaleFactor() const
bool classify_bln_numeric_mode
BLOCK_LIST * block_list_
The page layout.
void read_config_file(const char *filename, SetParamConstraint constraint)
void SetOutputName(const char *name)
const char * c_str() const
void Normalize(const BLOCK *block, const FCOORD *rotation, const DENORM *predecessor, float x_origin, float y_origin, float x_scale, float y_scale, float final_xshift, float final_yshift, bool inverse, Pix *pix)
FILE * init_recog_training(const STRING &fname)
CANCEL_FUNC cancel
for errcode use
int * AllWordConfidences()
bool DetectOrientationScript(int *orient_deg, float *orient_conf, const char **script_name, float *script_conf)