tesseract v5.3.3.20231005
pgedit.cpp
Go to the documentation of this file.
1/**********************************************************************
2 * File: pgedit.cpp (Formerly pgeditor.c)
3 * Description: Page structure file editor
4 * Author: Phil Cheatle
5 *
6 *(C) Copyright 1991, Hewlett-Packard Ltd.
7 ** Licensed under the Apache License, Version 2.0(the "License");
8 ** you may not use this file except in compliance with the License.
9 ** You may obtain a copy of the License at
10 ** http:// www.apache.org/licenses/LICENSE-2.0
11 ** Unless required by applicable law or agreed to in writing, software
12 ** distributed under the License is distributed on an "AS IS" BASIS,
13 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 ** See the License for the specific language governing permissions and
15 ** limitations under the License.
16 *
17 **********************************************************************/
18
19// Include automatically generated configuration file if running autoconf.
20#ifdef HAVE_CONFIG_H
21# include "config_auto.h"
22#endif
23
24#include "pgedit.h"
25
26#include "blread.h"
27#include "control.h"
28#include "pageres.h"
29#include "paramsd.h"
30#include "scrollview.h"
31#include "statistc.h"
32#include "svmnode.h"
33#include "tesseractclass.h"
34#include "tordmain.h"
35#include "werdit.h"
36
37#include <cctype>
38#include <cmath>
39#include <iomanip> // for std::setprecision
40#include <locale> // for std::locale::classic
41#include <sstream> // for std::stringstream
42
43#ifndef GRAPHICS_DISABLED
44namespace tesseract {
45# define ASC_HEIGHT (2 * kBlnBaselineOffset + kBlnXHeight)
46# define X_HEIGHT (kBlnBaselineOffset + kBlnXHeight)
47# define BL_HEIGHT kBlnBaselineOffset
48# define DESC_HEIGHT 0
49
81};
82
94};
95
96/*
97 *
98 * Some global data
99 *
100 */
101
102static ScrollView *image_win;
103static ParamsEditor *pe;
104static bool stillRunning = false;
105
106static ScrollView *bln_word_window = nullptr; // baseline norm words
107
108static CMD_EVENTS mode = CHANGE_DISP_CMD_EVENT; // selected words op
109
110static bool recog_done = false; // recog_all_words was called
111
112// These variables should remain global, since they are only used for the
113// debug mode (in which only a single Tesseract thread/instance will exist).
114static std::bitset<16> word_display_mode;
115static ColorationMode color_mode = CM_RAINBOW;
116static bool display_image = false;
117static bool display_blocks = false;
118static bool display_baselines = false;
119
120static PAGE_RES *current_page_res = nullptr;
121
122STRING_VAR(editor_image_win_name, "EditorImage", "Editor image window name");
123INT_VAR(editor_image_xpos, 590, "Editor image X Pos");
124INT_VAR(editor_image_ypos, 10, "Editor image Y Pos");
125static INT_VAR(editor_image_menuheight, 50, "Add to image height for menu bar");
128
129STRING_VAR(editor_word_name, "BlnWords", "BL normalized word window");
130INT_VAR(editor_word_xpos, 60, "Word window X Pos");
131INT_VAR(editor_word_ypos, 510, "Word window Y Pos");
132INT_VAR(editor_word_height, 240, "Word window height");
133INT_VAR(editor_word_width, 655, "Word window width");
134
142static void show_point(PAGE_RES *page_res, float x, float y) {
143 FCOORD pt(x, y);
144 PAGE_RES_IT pr_it(page_res);
145
146 std::stringstream msg;
147 msg.imbue(std::locale::classic());
148 msg << std::fixed << std::setprecision(3) << "Pt:(" << x << ", " << y << ") ";
149
150 for (WERD_RES *word = pr_it.word(); word != nullptr; word = pr_it.forward()) {
151 if (pr_it.row() != pr_it.prev_row() && pr_it.row()->row->bounding_box().contains(pt)) {
152 msg << "BL(x)=" << pr_it.row()->row->base_line(x) << ' ';
153 }
154 if (word->word->bounding_box().contains(pt)) {
155 TBOX box = word->word->bounding_box();
156 msg << "Wd(" << box.left() << ", " << box.bottom() << ")/("
157 << box.right() << ", " << box.top() << ") ";
158 C_BLOB_IT cblob_it(word->word->cblob_list());
159 for (cblob_it.mark_cycle_pt(); !cblob_it.cycled_list(); cblob_it.forward()) {
160 C_BLOB *cblob = cblob_it.data();
161 box = cblob->bounding_box();
162 if (box.contains(pt)) {
163 msg << "CBlb(" << box.left() << ", " << box.bottom() << ")/("
164 << box.right() << ", " << box.top() << ") ";
165 }
166 }
167 }
168 }
169 image_win->AddMessage(msg.str().c_str());
170}
171
178static void pgeditor_msg( // message display
179 const char *msg) {
180 image_win->AddMessage(msg);
181}
182
184public:
185 void Notify(const SVEvent *sv_event) override {
186 if (sv_event->type == SVET_DESTROY) {
187 bln_word_window = nullptr;
188 } else if (sv_event->type == SVET_CLICK) {
189 show_point(current_page_res, sv_event->x, sv_event->y);
190 }
191 }
192};
193
199static ScrollView *bln_word_window_handle() { // return handle
200 // not opened yet
201 if (bln_word_window == nullptr) {
202 pgeditor_msg("Creating BLN word window...");
203 bln_word_window = new ScrollView(editor_word_name.c_str(), editor_word_xpos, editor_word_ypos,
204 editor_word_width, editor_word_height, 4000, 4000, true);
205 auto *a = new BlnEventHandler();
206 bln_word_window->AddEventHandler(a);
207 pgeditor_msg("Creating BLN word window...Done");
208 }
209 return bln_word_window;
210}
211
219static void build_image_window(int width, int height) {
220 delete image_win;
221 image_win = new ScrollView(editor_image_win_name.c_str(), editor_image_xpos, editor_image_ypos,
222 width + 1, height + editor_image_menuheight + 1, width, height, true);
223}
224
231static void display_bln_lines(ScrollView *window, ScrollView::Color colour, float scale_factor,
232 float y_offset, float minx, float maxx) {
233 window->Pen(colour);
234 window->Line(minx, y_offset + scale_factor * DESC_HEIGHT, maxx,
235 y_offset + scale_factor * DESC_HEIGHT);
236 window->Line(minx, y_offset + scale_factor * BL_HEIGHT, maxx,
237 y_offset + scale_factor * BL_HEIGHT);
238 window->Line(minx, y_offset + scale_factor * X_HEIGHT, maxx, y_offset + scale_factor * X_HEIGHT);
239 window->Line(minx, y_offset + scale_factor * ASC_HEIGHT, maxx,
240 y_offset + scale_factor * ASC_HEIGHT);
241}
242
251void PGEventHandler::Notify(const SVEvent *event) {
252 char myval = '0';
253 if (event->type == SVET_POPUP) {
254 pe->Notify(event);
255 } // These are handled by ParamsEditor
256 else if (event->type == SVET_EXIT) {
257 stillRunning = false;
258 } else if (event->type == SVET_MENU) {
259 if (strcmp(event->parameter, "true") == 0) {
260 myval = 'T';
261 } else if (strcmp(event->parameter, "false") == 0) {
262 myval = 'F';
263 }
264 tess_->process_cmd_win_event(event->command_id, &myval);
265 } else {
266 tess_->process_image_event(*event);
267 }
268}
269
276 SVMenuNode *parent_menu;
277 auto *root_menu_item = new SVMenuNode();
278
279 SVMenuNode *modes_menu_item = root_menu_item->AddChild("MODES");
280
281 modes_menu_item->AddChild("Change Display", CHANGE_DISP_CMD_EVENT);
282 modes_menu_item->AddChild("Dump Word", DUMP_WERD_CMD_EVENT);
283 modes_menu_item->AddChild("Show Point", SHOW_POINT_CMD_EVENT);
284 modes_menu_item->AddChild("Show BL Norm Word", SHOW_BLN_WERD_CMD_EVENT);
285 modes_menu_item->AddChild("Config Words", DEBUG_WERD_CMD_EVENT);
286 modes_menu_item->AddChild("Recog Words", RECOG_WERDS);
287 modes_menu_item->AddChild("Recog Blobs", RECOG_PSEUDO);
288 modes_menu_item->AddChild("Show Blob Features", SHOW_BLOB_FEATURES);
289
290 parent_menu = root_menu_item->AddChild("DISPLAY");
291
292 parent_menu->AddChild("Blamer", BLAMER_CMD_EVENT, false);
293 parent_menu->AddChild("Bounding Boxes", BOUNDING_BOX_CMD_EVENT, false);
294 parent_menu->AddChild("Correct Text", CORRECT_TEXT_CMD_EVENT, false);
295 parent_menu->AddChild("Polygonal Approx", POLYGONAL_CMD_EVENT, false);
296 parent_menu->AddChild("Baseline Normalized", BL_NORM_CMD_EVENT, false);
297 parent_menu->AddChild("Edge Steps", BITMAP_CMD_EVENT, true);
298 parent_menu->AddChild("Subscripts", SHOW_SUBSCRIPT_CMD_EVENT);
299 parent_menu->AddChild("Superscripts", SHOW_SUPERSCRIPT_CMD_EVENT);
300 parent_menu->AddChild("Italics", SHOW_ITALIC_CMD_EVENT);
301 parent_menu->AddChild("Bold", SHOW_BOLD_CMD_EVENT);
302 parent_menu->AddChild("Underline", SHOW_UNDERLINE_CMD_EVENT);
303 parent_menu->AddChild("FixedPitch", SHOW_FIXEDPITCH_CMD_EVENT);
304 parent_menu->AddChild("Serifs", SHOW_SERIF_CMD_EVENT);
305 parent_menu->AddChild("SmallCaps", SHOW_SMALLCAPS_CMD_EVENT);
306 parent_menu->AddChild("DropCaps", SHOW_DROPCAPS_CMD_EVENT);
307
308 parent_menu = root_menu_item->AddChild("OTHER");
309
310 parent_menu->AddChild("Quit", QUIT_CMD_EVENT);
311 parent_menu->AddChild("Show Image", IMAGE_CMD_EVENT, false);
312 parent_menu->AddChild("ShowBlock Outlines", BLOCKS_CMD_EVENT, false);
313 parent_menu->AddChild("Show Baselines", BASELINES_CMD_EVENT, false);
314 parent_menu->AddChild("Uniform Display", UNIFORM_DISP_CMD_EVENT);
315 parent_menu->AddChild("Refresh Display", REFRESH_CMD_EVENT);
316
317 return root_menu_item;
318}
319
325void Tesseract::do_re_display(bool (tesseract::Tesseract::*word_painter)(PAGE_RES_IT *pr_it)) {
326 int block_count = 1;
327
328 image_win->Clear();
329 if (display_image) {
330 image_win->Draw(pix_binary_, 0, 0);
331 }
332
333 image_win->Brush(ScrollView::NONE);
334 PAGE_RES_IT pr_it(current_page_res);
335 for (WERD_RES *word = pr_it.word(); word != nullptr; word = pr_it.forward()) {
336 (this->*word_painter)(&pr_it);
337 if (display_baselines && pr_it.row() != pr_it.prev_row()) {
338 pr_it.row()->row->plot_baseline(image_win, ScrollView::GREEN);
339 }
340 if (display_blocks && pr_it.block() != pr_it.prev_block()) {
341 pr_it.block()->block->pdblk.plot(image_win, block_count++, ScrollView::RED);
342 }
343 }
344 image_win->Update();
345}
346
355void Tesseract::pgeditor_main(int width, int height, PAGE_RES *page_res) {
356 current_page_res = page_res;
357 if (current_page_res->block_res_list.empty()) {
358 return;
359 }
360
361 recog_done = false;
362 stillRunning = true;
363
364 build_image_window(width, height);
365 word_display_mode.set(DF_EDGE_STEP);
367# ifndef GRAPHICS_DISABLED
368 pe = new ParamsEditor(this, image_win);
369# endif
370 PGEventHandler pgEventHandler(this);
371
372 image_win->AddEventHandler(&pgEventHandler);
373 image_win->AddMessageBox();
374
375 SVMenuNode *svMenuRoot = build_menu_new();
376
377 svMenuRoot->BuildMenu(image_win);
378 image_win->SetVisible(true);
379
380 image_win->AwaitEvent(SVET_DESTROY);
381 image_win->AddEventHandler(nullptr);
382}
383
391bool Tesseract::process_cmd_win_event( // UI command semantics
392 int32_t cmd_event, // which menu item?
393 char *new_value // any prompt data
394) {
395 char msg[160];
396 bool exit = false;
397
398 color_mode = CM_RAINBOW;
399
400 // Run recognition on the full page if needed.
401 switch (cmd_event) {
402 case BLAMER_CMD_EVENT:
412 if (!recog_done) {
413 recog_all_words(current_page_res, nullptr, nullptr, nullptr, 0);
414 recog_done = true;
415 }
416 break;
417 default:
418 break;
419 }
420
421 char *parameter;
422
423 switch (cmd_event) {
424 case NULL_CMD_EVENT:
425 break;
426
431 case RECOG_WERDS:
432 case RECOG_PSEUDO:
434 mode = static_cast<CMD_EVENTS>(cmd_event);
435 break;
438 parameter = image_win->ShowInputDialog("Config File Name");
439 word_config_ = parameter;
440 delete[] parameter;
441 break;
443 if (new_value[0] == 'T') {
444 word_display_mode.set(DF_BOX);
445 } else {
446 word_display_mode.reset(DF_BOX);
447 }
449 break;
450 case BLAMER_CMD_EVENT:
451 if (new_value[0] == 'T') {
452 word_display_mode.set(DF_BLAMER);
453 } else {
454 word_display_mode.reset(DF_BLAMER);
455 }
458 break;
460 if (new_value[0] == 'T') {
461 word_display_mode.set(DF_TEXT);
462 } else {
463 word_display_mode.reset(DF_TEXT);
464 }
466 break;
468 if (new_value[0] == 'T') {
469 word_display_mode.set(DF_POLYGONAL);
470 } else {
471 word_display_mode.reset(DF_POLYGONAL);
472 }
474 break;
476 if (new_value[0] == 'T') {
477 word_display_mode.set(DF_BN_POLYGONAL);
478 } else {
479 word_display_mode.reset(DF_BN_POLYGONAL);
480 }
482 break;
483 case BITMAP_CMD_EVENT:
484 if (new_value[0] == 'T') {
485 word_display_mode.set(DF_EDGE_STEP);
486 } else {
487 word_display_mode.reset(DF_EDGE_STEP);
488 }
490 break;
493 break;
494 case IMAGE_CMD_EVENT:
495 display_image = (new_value[0] == 'T');
497 break;
498 case BLOCKS_CMD_EVENT:
499 display_blocks = (new_value[0] == 'T');
501 break;
503 display_baselines = (new_value[0] == 'T');
505 break;
507 color_mode = CM_SUBSCRIPT;
509 break;
511 color_mode = CM_SUPERSCRIPT;
513 break;
515 color_mode = CM_ITALIC;
517 break;
519 color_mode = CM_BOLD;
521 break;
523 color_mode = CM_UNDERLINE;
525 break;
527 color_mode = CM_FIXEDPITCH;
529 break;
531 color_mode = CM_SERIF;
533 break;
535 color_mode = CM_SMALLCAPS;
537 break;
539 color_mode = CM_DROPCAPS;
541 break;
544 break;
545 case QUIT_CMD_EVENT:
546 exit = true;
548 break;
549
550 default:
551 snprintf(msg, sizeof(msg), "Unrecognised event %" PRId32 "(%s)", cmd_event, new_value);
552 image_win->AddMessage(msg);
553 break;
554 }
555 return exit;
556}
557
567void Tesseract::process_image_event( // action in image win
568 const SVEvent &event) {
569 // The following variable should remain static, since it is used by
570 // debug editor, which uses a single Tesseract instance.
571 static ICOORD down;
572 ICOORD up;
573 TBOX selection_box;
574 char msg[80];
575
576 switch (event.type) {
577 case SVET_SELECTION:
578 if (event.type == SVET_SELECTION) {
579 down.set_x(event.x + event.x_size);
580 down.set_y(event.y + event.y_size);
581 if (mode == SHOW_POINT_CMD_EVENT) {
582 show_point(current_page_res, event.x, event.y);
583 }
584 }
585
586 up.set_x(event.x);
587 up.set_y(event.y);
588
589 selection_box = TBOX(down, up);
590
591 switch (mode) {
593 process_selected_words(current_page_res, selection_box,
595 break;
597 process_selected_words(current_page_res, selection_box,
599 break;
601 process_selected_words(current_page_res, selection_box,
603 break;
605 debug_word(current_page_res, selection_box);
606 break;
608 break; // ignore up event
609
610 case RECOG_WERDS:
611# ifndef DISABLED_LEGACY_ENGINE
612 image_win->AddMessage("Recogging selected words");
613 this->process_selected_words(current_page_res, selection_box,
615# endif // ndef DISABLED_LEGACY_ENGINE
616 break;
617 case RECOG_PSEUDO:
618 image_win->AddMessage("Recogging selected blobs");
619 recog_pseudo_word(current_page_res, selection_box);
620 break;
622 blob_feature_display(current_page_res, selection_box);
623 break;
624
625 default:
626 snprintf(msg, sizeof(msg), "Mode %d not yet implemented", mode);
627 image_win->AddMessage(msg);
628 break;
629 }
630 default:
631 break;
632 }
633}
634
640void Tesseract::debug_word(PAGE_RES *page_res, const TBOX &selection_box) {
641# ifndef DISABLED_LEGACY_ENGINE
643# endif
644 recog_all_words(page_res, nullptr, &selection_box, word_config_.c_str(), 0);
645}
646
647/**********************************************************************
648 * WERD PROCESSOR FUNCTIONS
649 * ========================
650 *
651 * These routines are invoked by one or more of:
652 * process_all_words()
653 * process_selected_words()
654 * or
655 * process_all_words_it()
656 * process_selected_words_it()
657 * for each word to be processed
658 **********************************************************************/
659
669 return word_set_display(pr_it);
670}
671
678 WERD_RES *word_res = pr_it->word();
679 if (word_res->chopped_word == nullptr) {
680 // Setup word normalization parameters.
681 word_res->SetupForRecognition(unicharset, this, BestPix(), tessedit_ocr_engine_mode, nullptr,
682 classify_bln_numeric_mode, textord_use_cjk_fp_model,
683 poly_allow_detailed_fx, pr_it->row()->row, pr_it->block()->block);
684 }
685 bln_word_window_handle()->Clear();
686 display_bln_lines(bln_word_window_handle(), ScrollView::CYAN, 1.0, 0.0f, -1000.0f, 1000.0f);
687 C_BLOB_IT it(word_res->word->cblob_list());
689 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
690 it.data()->plot_normed(word_res->denorm, color, ScrollView::BROWN, bln_word_window_handle());
691 color = WERD::NextColor(color);
692 }
693 bln_word_window_handle()->Update();
694 return true;
695}
696
703 WERD_RES *word_res = pr_it->word();
704 WERD *word = word_res->word;
705 TBOX word_bb; // word bounding box
706 int word_height; // ht of word BB
707 bool displayed_something = false;
708 float shift; // from bot left
709
710 if (color_mode != CM_RAINBOW && word_res->box_word != nullptr) {
711# ifndef DISABLED_LEGACY_ENGINE
712 BoxWord *box_word = word_res->box_word;
713 WERD_CHOICE *best_choice = word_res->best_choice;
714 int length = box_word->length();
715 if (word_res->fontinfo == nullptr) {
716 return false;
717 }
718 const FontInfo &font_info = *word_res->fontinfo;
719 for (int i = 0; i < length; ++i) {
721 switch (color_mode) {
722 case CM_SUBSCRIPT:
723 if (best_choice->BlobPosition(i) == SP_SUBSCRIPT) {
724 color = ScrollView::RED;
725 }
726 break;
727 case CM_SUPERSCRIPT:
728 if (best_choice->BlobPosition(i) == SP_SUPERSCRIPT) {
729 color = ScrollView::RED;
730 }
731 break;
732 case CM_ITALIC:
733 if (font_info.is_italic()) {
734 color = ScrollView::RED;
735 }
736 break;
737 case CM_BOLD:
738 if (font_info.is_bold()) {
739 color = ScrollView::RED;
740 }
741 break;
742 case CM_FIXEDPITCH:
743 if (font_info.is_fixed_pitch()) {
744 color = ScrollView::RED;
745 }
746 break;
747 case CM_SERIF:
748 if (font_info.is_serif()) {
749 color = ScrollView::RED;
750 }
751 break;
752 case CM_SMALLCAPS:
753 if (word_res->small_caps) {
754 color = ScrollView::RED;
755 }
756 break;
757 case CM_DROPCAPS:
758 if (best_choice->BlobPosition(i) == SP_DROPCAP) {
759 color = ScrollView::RED;
760 }
761 break;
762 // TODO(rays) underline is currently completely unsupported.
763 case CM_UNDERLINE:
764 default:
765 break;
766 }
767 image_win->Pen(color);
768 TBOX box = box_word->BlobBox(i);
769 image_win->Rectangle(box.left(), box.bottom(), box.right(), box.top());
770 }
771 return true;
772# else
773 return false;
774# endif // ndef DISABLED_LEGACY_ENGINE
775 }
776 /*
777 Note the double coercions of(COLOUR)((int32_t)editor_image_word_bb_color)
778 etc. are to keep the compiler happy.
779*/
780 // display bounding box
781 if (word->display_flag(DF_BOX)) {
782 word->bounding_box().plot(image_win,
783 static_cast<ScrollView::Color>((int32_t)editor_image_word_bb_color),
784 static_cast<ScrollView::Color>((int32_t)editor_image_word_bb_color));
785
786 auto c = static_cast<ScrollView::Color>((int32_t)editor_image_blob_bb_color);
787 image_win->Pen(c);
788 // cblob iterator
789 C_BLOB_IT c_it(word->cblob_list());
790 for (c_it.mark_cycle_pt(); !c_it.cycled_list(); c_it.forward()) {
791 c_it.data()->bounding_box().plot(image_win);
792 }
793 displayed_something = true;
794 }
795
796 // display edge steps
797 if (word->display_flag(DF_EDGE_STEP)) { // edgesteps available
798 word->plot(image_win); // rainbow colors
799 displayed_something = true;
800 }
801
802 // display poly approx
803 if (word->display_flag(DF_POLYGONAL)) {
804 // need to convert
805 TWERD *tword = TWERD::PolygonalCopy(poly_allow_detailed_fx, word);
806 tword->plot(image_win);
807 delete tword;
808 displayed_something = true;
809 }
810
811 // Display correct text and blamer information.
812 std::string text;
813 std::string blame;
814 if (word->display_flag(DF_TEXT) && word->text() != nullptr) {
815 text = word->text();
816 }
817 if (word->display_flag(DF_BLAMER) &&
818 !(word_res->blamer_bundle != nullptr &&
820 text = "";
821 const BlamerBundle *blamer_bundle = word_res->blamer_bundle;
822 if (blamer_bundle == nullptr) {
823 text += "NULL";
824 } else {
825 text = blamer_bundle->TruthString();
826 }
827 text += " -> ";
828 std::string best_choice_str;
829 if (word_res->best_choice == nullptr) {
830 best_choice_str = "NULL";
831 } else {
832 word_res->best_choice->string_and_lengths(&best_choice_str, nullptr);
833 }
834 text += best_choice_str;
835 IncorrectResultReason reason =
836 (blamer_bundle == nullptr) ? IRR_PAGE_LAYOUT : blamer_bundle->incorrect_result_reason();
838 blame += " [";
839 blame += BlamerBundle::IncorrectReasonName(reason);
840 blame += "]";
841 }
842 if (text.length() > 0) {
843 word_bb = word->bounding_box();
844 image_win->Pen(ScrollView::RED);
845 word_height = word_bb.height();
846 int text_height = 0.50 * word_height;
847 if (text_height > 20) {
848 text_height = 20;
849 }
850 image_win->TextAttributes("Arial", text_height, false, false, false);
851 shift = (word_height < word_bb.width()) ? 0.25 * word_height : 0.0f;
852 image_win->Text(word_bb.left() + shift, word_bb.bottom() + 0.25 * word_height, text.c_str());
853 if (blame.length() > 0) {
854 image_win->Text(word_bb.left() + shift, word_bb.bottom() + 0.25 * word_height - text_height,
855 blame.c_str());
856 }
857
858 displayed_something = true;
859 }
860
861 if (!displayed_something) { // display BBox anyway
862 word->bounding_box().plot(image_win,
863 static_cast<ScrollView::Color>((int32_t)editor_image_word_bb_color),
864 static_cast<ScrollView::Color>((int32_t)editor_image_word_bb_color));
865 }
866 return true;
867}
868} // namespace tesseract
869#endif // !GRAPHICS_DISABLED
870
871namespace tesseract {
878 if (pr_it->block()->block != nullptr) {
879 tprintf("\nBlock data...\n");
880 pr_it->block()->block->print(nullptr, false);
881 }
882 tprintf("\nRow data...\n");
883 pr_it->row()->row->print(nullptr);
884 tprintf("\nWord data...\n");
885 WERD_RES *word_res = pr_it->word();
886 word_res->word->print();
887 if (word_res->blamer_bundle != nullptr && wordrec_debug_blamer &&
889 tprintf("Current blamer debug: %s\n", word_res->blamer_bundle->debug().c_str());
890 }
891 return true;
892}
893
894#ifndef GRAPHICS_DISABLED
901 WERD *word = pr_it->word()->word;
902 word->set_display_flag(DF_BOX, word_display_mode[DF_BOX]);
903 word->set_display_flag(DF_TEXT, word_display_mode[DF_TEXT]);
904 word->set_display_flag(DF_POLYGONAL, word_display_mode[DF_POLYGONAL]);
905 word->set_display_flag(DF_EDGE_STEP, word_display_mode[DF_EDGE_STEP]);
906 word->set_display_flag(DF_BN_POLYGONAL, word_display_mode[DF_BN_POLYGONAL]);
907 word->set_display_flag(DF_BLAMER, word_display_mode[DF_BLAMER]);
908 return word_display(pr_it);
909}
910
911// page_res is non-const because the iterator doesn't know if you are going
912// to change the items it points to! Really a const here though.
913void Tesseract::blob_feature_display(PAGE_RES *page_res, const TBOX &selection_box) {
914# ifndef DISABLED_LEGACY_ENGINE
915 PAGE_RES_IT *it = make_pseudo_word(page_res, selection_box);
916 if (it != nullptr) {
917 WERD_RES *word_res = it->word();
918 word_res->x_height = it->row()->row->x_height();
919 word_res->SetupForRecognition(unicharset, this, BestPix(), tessedit_ocr_engine_mode, nullptr,
920 classify_bln_numeric_mode, textord_use_cjk_fp_model,
921 poly_allow_detailed_fx, it->row()->row, it->block()->block);
922 TWERD *bln_word = word_res->chopped_word;
923 TBLOB *bln_blob = bln_word->blobs[0];
924 INT_FX_RESULT_STRUCT fx_info;
925 std::vector<INT_FEATURE_STRUCT> bl_features;
926 std::vector<INT_FEATURE_STRUCT> cn_features;
927 Classify::ExtractFeatures(*bln_blob, classify_nonlinear_norm, &bl_features, &cn_features,
928 &fx_info, nullptr);
929 // Display baseline features.
930 ScrollView *bl_win = CreateFeatureSpaceWindow("BL Features", 512, 0);
932 for (auto &bl_feature : bl_features) {
933 RenderIntFeature(bl_win, &bl_feature, ScrollView::GREEN);
934 }
935 bl_win->Update();
936 // Display cn features.
937 ScrollView *cn_win = CreateFeatureSpaceWindow("CN Features", 512, 0);
939 for (auto &cn_feature : cn_features) {
940 RenderIntFeature(cn_win, &cn_feature, ScrollView::GREEN);
941 }
942 cn_win->Update();
943
944 it->DeleteCurrentWord();
945 delete it;
946 }
947# endif // ndef DISABLED_LEGACY_ENGINE
948}
949
950#endif // !GRAPHICS_DISABLED
951
952} // namespace tesseract
#define DESC_HEIGHT
Definition: pgedit.cpp:48
#define ASC_HEIGHT
Definition: pgedit.cpp:45
#define BL_HEIGHT
Definition: pgedit.cpp:47
#define X_HEIGHT
Definition: pgedit.cpp:46
#define INT_VAR(name, val, comment)
Definition: params.h:357
#define STRING_VAR(name, val, comment)
Definition: params.h:363
#define ASSERT_HOST(x)
Definition: errcode.h:54
@ TBOX
const double y
@ SHOW_SUBSCRIPT_CMD_EVENT
Definition: pgedit.cpp:72
@ DEBUG_WERD_CMD_EVENT
Definition: pgedit.cpp:56
@ SHOW_UNDERLINE_CMD_EVENT
Definition: pgedit.cpp:76
@ SHOW_SERIF_CMD_EVENT
Definition: pgedit.cpp:78
@ BASELINES_CMD_EVENT
Definition: pgedit.cpp:65
@ SHOW_BOLD_CMD_EVENT
Definition: pgedit.cpp:75
@ BLAMER_CMD_EVENT
Definition: pgedit.cpp:57
@ SHOW_BLN_WERD_CMD_EVENT
Definition: pgedit.cpp:55
@ RECOG_PSEUDO
Definition: pgedit.cpp:70
@ SHOW_SUPERSCRIPT_CMD_EVENT
Definition: pgedit.cpp:73
@ BL_NORM_CMD_EVENT
Definition: pgedit.cpp:61
@ REFRESH_CMD_EVENT
Definition: pgedit.cpp:67
@ BITMAP_CMD_EVENT
Definition: pgedit.cpp:62
@ DUMP_WERD_CMD_EVENT
Definition: pgedit.cpp:53
@ SHOW_BLOB_FEATURES
Definition: pgedit.cpp:71
@ SHOW_POINT_CMD_EVENT
Definition: pgedit.cpp:54
@ IMAGE_CMD_EVENT
Definition: pgedit.cpp:63
@ RECOG_WERDS
Definition: pgedit.cpp:69
@ NULL_CMD_EVENT
Definition: pgedit.cpp:51
@ SHOW_DROPCAPS_CMD_EVENT
Definition: pgedit.cpp:80
@ SHOW_FIXEDPITCH_CMD_EVENT
Definition: pgedit.cpp:77
@ CHANGE_DISP_CMD_EVENT
Definition: pgedit.cpp:52
@ CORRECT_TEXT_CMD_EVENT
Definition: pgedit.cpp:59
@ BOUNDING_BOX_CMD_EVENT
Definition: pgedit.cpp:58
@ BLOCKS_CMD_EVENT
Definition: pgedit.cpp:64
@ POLYGONAL_CMD_EVENT
Definition: pgedit.cpp:60
@ UNIFORM_DISP_CMD_EVENT
Definition: pgedit.cpp:66
@ QUIT_CMD_EVENT
Definition: pgedit.cpp:68
@ SHOW_SMALLCAPS_CMD_EVENT
Definition: pgedit.cpp:79
@ SHOW_ITALIC_CMD_EVENT
Definition: pgedit.cpp:74
ColorationMode
Definition: pgedit.cpp:83
@ CM_ITALIC
Definition: pgedit.cpp:87
@ CM_SUBSCRIPT
Definition: pgedit.cpp:85
@ CM_RAINBOW
Definition: pgedit.cpp:84
@ CM_FIXEDPITCH
Definition: pgedit.cpp:90
@ CM_BOLD
Definition: pgedit.cpp:88
@ CM_SMALLCAPS
Definition: pgedit.cpp:92
@ CM_SUPERSCRIPT
Definition: pgedit.cpp:86
@ CM_SERIF
Definition: pgedit.cpp:91
@ CM_DROPCAPS
Definition: pgedit.cpp:93
@ CM_UNDERLINE
Definition: pgedit.cpp:89
PAGE_RES_IT * make_pseudo_word(PAGE_RES *page_res, const TBOX &selection_box)
Definition: werdit.cpp:38
int editor_image_ypos
Definition: pgedit.cpp:124
int editor_word_height
Definition: pgedit.cpp:132
void tprintf(const char *format,...)
Definition: tprintf.cpp:41
@ SP_SUBSCRIPT
Definition: ratngs.h:254
@ SP_DROPCAP
Definition: ratngs.h:254
@ SP_SUPERSCRIPT
Definition: ratngs.h:254
int editor_image_xpos
Definition: pgedit.cpp:123
@ SVET_SELECTION
Definition: scrollview.h:57
@ SVET_DESTROY
Definition: scrollview.h:54
@ SVET_POPUP
Definition: scrollview.h:62
@ SVET_CLICK
Definition: scrollview.h:56
@ character
Definition: mfoutline.h:53
@ baseline
Definition: mfoutline.h:53
ScrollView * CreateFeatureSpaceWindow(const char *name, int xpos, int ypos)
Definition: intproto.cpp:1622
void RenderIntFeature(ScrollView *window, const INT_FEATURE_STRUCT *Feature, ScrollView::Color color)
Definition: intproto.cpp:1500
int editor_word_ypos
Definition: pgedit.cpp:131
int editor_word_width
Definition: pgedit.cpp:133
@ DF_POLYGONAL
Polyg approx.
Definition: werd.h:50
@ DF_BLAMER
Blamer information.
Definition: werd.h:53
@ DF_BOX
Bounding box.
Definition: werd.h:48
@ DF_BN_POLYGONAL
BL normalisd polyapx.
Definition: werd.h:52
@ DF_EDGE_STEP
Edge steps.
Definition: werd.h:51
@ DF_TEXT
Correct ascii.
Definition: werd.h:49
IncorrectResultReason
Definition: blamer.h:56
@ IRR_CORRECT
Definition: blamer.h:58
@ IRR_PAGE_LAYOUT
Definition: blamer.h:77
@ IRR_NUM_REASONS
Definition: blamer.h:103
int editor_image_word_bb_color
Definition: pgedit.cpp:126
int editor_image_blob_bb_color
Definition: pgedit.cpp:127
void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView *window)
Definition: intproto.cpp:889
int editor_word_xpos
Definition: pgedit.cpp:130
char * editor_image_win_name
Definition: pgedit.cpp:122
char * editor_word_name
Definition: pgedit.cpp:129
void Notify(const SVEvent *sve) override
Definition: paramsd.cpp:271
void Notify(const SVEvent *sv_event) override
Definition: pgedit.cpp:185
void Notify(const SVEvent *sve) override
Definition: pgedit.cpp:251
bool recog_interactive(PAGE_RES_IT *pr_it)
Definition: control.cpp:76
void process_image_event(const SVEvent &event)
Definition: pgedit.cpp:567
bool process_cmd_win_event(int32_t cmd_event, char *new_value)
Definition: pgedit.cpp:391
SVMenuNode * build_menu_new()
Definition: pgedit.cpp:275
void recog_pseudo_word(PAGE_RES *page_res, TBOX &selection_box)
Definition: control.cpp:62
bool word_display(PAGE_RES_IT *pr_it)
Definition: pgedit.cpp:702
bool word_bln_display(PAGE_RES_IT *pr_it)
Definition: pgedit.cpp:677
Image BestPix() const
void process_selected_words(PAGE_RES *page_res, TBOX &selection_box, bool(tesseract::Tesseract::*word_processor)(PAGE_RES_IT *pr_it))
Definition: pagewalk.cpp:30
bool word_set_display(PAGE_RES_IT *pr_it)
Definition: pgedit.cpp:900
bool word_dumper(PAGE_RES_IT *pr_it)
Definition: pgedit.cpp:877
bool word_blank_and_set_display(PAGE_RES_IT *pr_its)
Definition: pgedit.cpp:667
void debug_word(PAGE_RES *page_res, const TBOX &selection_box)
Definition: pgedit.cpp:640
void pgeditor_main(int width, int height, PAGE_RES *page_res)
Definition: pgedit.cpp:355
void blob_feature_display(PAGE_RES *page_res, const TBOX &selection_box)
Definition: pgedit.cpp:913
void do_re_display(bool(tesseract::Tesseract::*word_painter)(PAGE_RES_IT *pr_it))
Definition: pgedit.cpp:325
bool recog_all_words(PAGE_RES *page_res, ETEXT_DESC *monitor, const TBOX *target_word_box, const char *word_config, int dopasses)
Definition: control.cpp:287
static const char * IncorrectReasonName(IncorrectResultReason irr)
Definition: blamer.cpp:56
std::string TruthString() const
Definition: blamer.h:124
const std::string & debug() const
Definition: blamer.h:140
IncorrectResultReason incorrect_result_reason() const
Definition: blamer.h:131
static TWERD * PolygonalCopy(bool allow_detailed_fx, WERD *src)
Definition: blobs.cpp:778
std::vector< TBLOB * > blobs
Definition: blobs.h:462
void plot(ScrollView *window)
Definition: blobs.cpp:907
unsigned length() const
Definition: boxword.h:81
const TBOX & BlobBox(unsigned index) const
Definition: boxword.h:84
bool is_italic() const
Definition: fontinfo.h:118
bool is_fixed_pitch() const
Definition: fontinfo.h:124
bool is_bold() const
Definition: fontinfo.h:121
bool is_serif() const
Definition: fontinfo.h:127
void print(FILE *fp, bool dump)
dump whole table
Definition: ocrblock.cpp:188
PDBLK pdblk
Page Description Block.
Definition: ocrblock.h:185
void plot_baseline(ScrollView *window, ScrollView::Color colour)
Definition: ocrrow.h:139
void print(FILE *fp) const
Definition: ocrrow.cpp:167
float x_height() const
Definition: ocrrow.h:66
BLOCK_RES_LIST block_res_list
Definition: pageres.h:81
WERD_CHOICE * best_choice
Definition: pageres.h:239
TWERD * chopped_word
Definition: pageres.h:210
bool SetupForRecognition(const UNICHARSET &unicharset_in, tesseract::Tesseract *tesseract, Image pix, int norm_mode, const TBOX *norm_box, bool numeric_mode, bool use_body_size, bool allow_detailed_fx, ROW *row, const BLOCK *block)
Definition: pageres.cpp:304
BlamerBundle * blamer_bundle
Definition: pageres.h:250
const FontInfo * fontinfo
Definition: pageres.h:307
tesseract::BoxWord * box_word
Definition: pageres.h:270
BLOCK_RES * block() const
Definition: pageres.h:769
WERD_RES * forward()
Definition: pageres.h:743
BLOCK_RES * prev_block() const
Definition: pageres.h:760
WERD_RES * word() const
Definition: pageres.h:763
ROW_RES * prev_row() const
Definition: pageres.h:757
ROW_RES * row() const
Definition: pageres.h:766
void plot(ScrollView *window, int32_t serial, ScrollView::Color colour)
Definition: pdblock.cpp:185
integer coordinate
Definition: points.h:36
void set_x(TDimension xin)
rewrite function
Definition: points.h:67
void set_y(TDimension yin)
rewrite function
Definition: points.h:71
void string_and_lengths(std::string *word_str, std::string *word_lengths_str) const
Definition: ratngs.cpp:427
ScriptPos BlobPosition(unsigned index) const
Definition: ratngs.h:306
TDimension left() const
Definition: rect.h:82
TDimension height() const
Definition: rect.h:118
TDimension width() const
Definition: rect.h:126
TDimension top() const
Definition: rect.h:68
TDimension right() const
Definition: rect.h:89
TDimension bottom() const
Definition: rect.h:75
void plot(ScrollView *fd) const
Definition: rect.h:296
const char * text() const
Definition: werd.h:121
void set_display_flag(uint8_t flag, bool value)
Definition: werd.h:138
bool display_flag(uint8_t flag) const
Definition: werd.h:135
static ScrollView::Color NextColor(ScrollView::Color colour)
Definition: werd.cpp:298
TBOX bounding_box() const
Definition: werd.cpp:155
void print() const
Definition: werd.cpp:262
void plot(ScrollView *window, ScrollView::Color colour)
Definition: werd.cpp:289
C_BLOB_LIST * cblob_list()
Definition: werd.h:96
UNICHARSET unicharset
Definition: ccutil.h:61
static void ExtractFeatures(const TBLOB &blob, bool nonlinear_norm, std::vector< INT_FEATURE_STRUCT > *bl_features, std::vector< INT_FEATURE_STRUCT > *cn_features, INT_FX_RESULT_STRUCT *results, std::vector< int > *outline_cn_counts)
Definition: intfx.cpp:436
SVEventType type
Definition: scrollview.h:74
char * ShowInputDialog(const char *msg)
Definition: scrollview.cpp:722
void AddMessage(const char *message)
Definition: scrollview.cpp:533
std::unique_ptr< SVEvent > AwaitEvent(SVEventType type)
Definition: scrollview.cpp:432
void TextAttributes(const char *font, int pixel_size, bool bold, bool italic, bool underlined)
Definition: scrollview.cpp:610
void Text(int x, int y, const char *mystring)
Definition: scrollview.cpp:635
void Draw(Image image, int x_pos, int y_pos)
Definition: scrollview.cpp:750
void SetVisible(bool visible)
Definition: scrollview.cpp:515
void Pen(Color color)
Definition: scrollview.cpp:710
static void Update()
Definition: scrollview.cpp:700
void AddEventHandler(SVEventHandler *listener)
Add an Event Listener to this ScrollView Window.
Definition: scrollview.cpp:408
void Brush(Color color)
Definition: scrollview.cpp:716
static void Exit()
Definition: scrollview.cpp:559
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:576
SVMenuNode * AddChild(const char *txt)
Definition: svmnode.cpp:59
void BuildMenu(ScrollView *sv, bool menu_bar=true)
Definition: svmnode.cpp:120