This program reads in a text file consisting of feature samples from a training page in the following format:
The result of this program is a binary inttemp file used by the OCR engine.
422 if (FLAGS_list_available_fonts) {
423 const vector<string>& all_fonts = FontUtils::ListAvailableFonts();
424 for (
int i = 0; i < all_fonts.size(); ++i) {
425 printf(
"%3d: %s\n", i, all_fonts[i].c_str());
427 "Font %s is unrecognized.\n", all_fonts[i].c_str());
433 if (FLAGS_text.empty()) {
434 tprintf(
"'--text' option is missing!\n");
437 if (FLAGS_outputbase.empty()) {
438 tprintf(
"'--outputbase' option is missing!\n");
441 if (!FLAGS_unicharset_file.empty() && FLAGS_render_ngrams) {
442 tprintf(
"Use '--unicharset_file' only if '--render_ngrams' is set.\n");
446 if (!FLAGS_find_fonts && !FontUtils::IsAvailableFont(FLAGS_font.c_str())) {
448 if (!FontUtils::IsAvailableFont(FLAGS_font.c_str(), &pango_name)) {
449 tprintf(
"Could not find font named %s.\n", FLAGS_font.c_str());
450 if (!pango_name.empty()) {
451 tprintf(
"Pango suggested font %s.\n", pango_name.c_str());
453 tprintf(
"Please correct --font arg.\n");
458 if (FLAGS_render_ngrams)
459 FLAGS_output_word_boxes =
true;
461 char font_desc_name[1024];
462 snprintf(font_desc_name, 1024,
"%s %d", FLAGS_font.c_str(),
463 static_cast<int>(FLAGS_ptsize));
465 render.set_add_ligatures(FLAGS_ligatures);
466 render.set_leading(FLAGS_leading);
467 render.set_resolution(FLAGS_resolution);
468 render.set_char_spacing(FLAGS_char_spacing * FLAGS_ptsize);
469 render.set_h_margin(FLAGS_margin);
470 render.set_v_margin(FLAGS_margin);
471 render.set_output_word_boxes(FLAGS_output_word_boxes);
472 render.set_box_padding(FLAGS_box_padding);
473 render.set_strip_unrenderable_words(FLAGS_strip_unrenderable_words);
474 render.set_underline_start_prob(FLAGS_underline_start_prob);
475 render.set_underline_continuation_prob(FLAGS_underline_continuation_prob);
478 if (FLAGS_writing_mode ==
"horizontal") {
480 render.set_vertical_text(
false);
481 render.set_gravity_hint_strong(
false);
482 render.set_render_fullwidth_latin(
false);
483 }
else if (FLAGS_writing_mode ==
"vertical") {
485 render.set_vertical_text(
true);
486 render.set_gravity_hint_strong(
false);
487 render.set_render_fullwidth_latin(
false);
488 }
else if (FLAGS_writing_mode ==
"vertical-upright") {
494 render.set_vertical_text(
true);
495 render.set_gravity_hint_strong(
true);
496 render.set_render_fullwidth_latin(
true);
498 tprintf(
"Invalid writing mode: %s\n", FLAGS_writing_mode.c_str());
504 if (!File::ReadFileToString(FLAGS_text.c_str(), &src_utf8)) {
505 tprintf(
"Failed to read file: %s\n", FLAGS_text.c_str());
510 if (strncmp(src_utf8.c_str(),
"\xef\xbb\xbf", 3) == 0) {
511 src_utf8.erase(0, 3);
513 tlog(1,
"Render string of size %d\n", src_utf8.length());
515 if (FLAGS_render_ngrams || FLAGS_only_extract_font_properties) {
518 const string kSeparator = FLAGS_render_ngrams ?
" " :
" ";
522 const int kCharsPerLine = (FLAGS_ptsize > 20) ? 50 : 100;
525 if (FLAGS_render_ngrams && !FLAGS_unicharset_file.empty() &&
527 tprintf(
"Failed to load unicharset from file %s\n",
528 FLAGS_unicharset_file.c_str());
535 const char *str8 = src_utf8.c_str();
536 int len = src_utf8.length();
538 vector<pair<int, int> > offsets;
540 while (offset < len) {
542 offsets.push_back(make_pair(offset, step));
546 if (FLAGS_render_ngrams)
547 std::random_shuffle(offsets.begin(), offsets.end());
549 for (
int i = 0, line = 1; i < offsets.size(); ++i) {
550 const char *curr_pos = str8 + offsets[i].first;
551 int ngram_len = offsets[i].second;
553 if (!FLAGS_unicharset_file.empty() &&
557 rand_utf8.append(curr_pos, ngram_len);
558 if (rand_utf8.length() > line * kCharsPerLine) {
559 rand_utf8.append(
" \n");
561 if (line & 0x1) rand_utf8.append(kSeparator);
563 rand_utf8.append(kSeparator);
566 tlog(1,
"Rendered ngram string of size %d\n", rand_utf8.length());
567 src_utf8.swap(rand_utf8);
569 if (FLAGS_only_extract_font_properties) {
570 tprintf(
"Extracting font properties only\n");
577 vector<float> page_rotation;
578 const char* to_render_utf8 = src_utf8.c_str();
582 vector<string> font_names;
586 int num_pass = FLAGS_bidirectional_rotation ? 2 : 1;
587 for (
int pass = 0; pass < num_pass; ++pass) {
590 for (
int offset = 0; offset < strlen(to_render_utf8); ++im, ++page_num) {
591 tlog(1,
"Starting page %d\n", im);
593 if (FLAGS_find_fonts) {
594 offset += render.RenderAllFontsToImage(FLAGS_min_coverage,
595 to_render_utf8 + offset,
596 strlen(to_render_utf8 + offset),
599 offset += render.RenderToImage(to_render_utf8 + offset,
600 strlen(to_render_utf8 + offset), &pix);
606 rotation = -1 * page_rotation[page_num];
608 if (FLAGS_degrade_image) {
610 FLAGS_rotate_image ? &rotation : NULL);
612 render.RotatePageBoxes(rotation);
616 page_rotation.push_back(rotation);
619 Pix* gray_pix = pixConvertTo8(pix,
false);
621 Pix* binary = pixThresholdToBinary(gray_pix, 128);
622 pixDestroy(&gray_pix);
623 char tiff_name[1024];
624 if (FLAGS_find_fonts) {
625 if (FLAGS_render_per_font) {
626 string fontname_for_file = tesseract::StringReplace(
627 font_used,
" ",
"_");
628 snprintf(tiff_name, 1024,
"%s.%s.tif", FLAGS_outputbase.c_str(),
629 fontname_for_file.c_str());
630 pixWriteTiff(tiff_name, binary, IFF_TIFF_G4,
"w");
631 tprintf(
"Rendered page %d to file %s\n", im, tiff_name);
633 font_names.push_back(font_used);
636 snprintf(tiff_name, 1024,
"%s.tif", FLAGS_outputbase.c_str());
637 pixWriteTiff(tiff_name, binary, IFF_TIFF_G4, im == 0 ?
"w" :
"a");
638 tprintf(
"Rendered page %d to file %s\n", im, tiff_name);
641 if (FLAGS_output_individual_glyph_images) {
643 tprintf(
"ERROR: Individual glyphs not saved\n");
648 if (FLAGS_find_fonts && offset != 0) {
655 if (!FLAGS_find_fonts) {
656 string box_name = FLAGS_outputbase.c_str();
658 render.WriteAllBoxes(box_name);
659 }
else if (!FLAGS_render_per_font && !font_names.empty()) {
660 string filename = FLAGS_outputbase.c_str();
662 FILE* fp = fopen(
filename.c_str(),
"wb");
666 for (
int i = 0; i < font_names.size(); ++i) {
667 fprintf(fp,
"%s\n", font_names[i].c_str());
Pix * DegradeImage(Pix *input, int exposure, TRand *randomizer, float *rotation)
bool encodable_string(const char *str, int *first_bad_position) const
int SpanUTF8NotWhitespace(const char *text)
void set_seed(uinT64 seed)
#define ASSERT_HOST_MSG(x,...)
bool load_from_file(const char *const filename, bool skip_fragments)
int SpanUTF8Whitespace(const char *text)
void ParseCommandLineFlags(const char *usage, int *argc, char ***argv, const bool remove_flags)
void ExtractFontProperties(const string &utf8_text, StringRenderer *render, const string &output_base)
bool MakeIndividualGlyphs(Pix *pix, const vector< BoxChar *> &vbox, const int input_tiff_page)