tesseract 5.2.0
Loading...
Searching...
No Matches
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
40#ifndef GRAPHICS_DISABLED
41namespace tesseract {
42# define ASC_HEIGHT (2 * kBlnBaselineOffset + kBlnXHeight)
43# define X_HEIGHT (kBlnBaselineOffset + kBlnXHeight)
44# define BL_HEIGHT kBlnBaselineOffset
45# define DESC_HEIGHT 0
46
78};
79
91};
92
93/*
94 *
95 * Some global data
96 *
97 */
98
99static ScrollView *image_win;
100static ParamsEditor *pe;
101static bool stillRunning = false;
102
103static ScrollView *bln_word_window = nullptr; // baseline norm words
104
105static CMD_EVENTS mode = CHANGE_DISP_CMD_EVENT; // selected words op
106
107static bool recog_done = false; // recog_all_words was called
108
109// These variables should remain global, since they are only used for the
110// debug mode (in which only a single Tesseract thread/instance will exist).
111static std::bitset<16> word_display_mode;
112static ColorationMode color_mode = CM_RAINBOW;
113static bool display_image = false;
114static bool display_blocks = false;
115static bool display_baselines = false;
116
117static PAGE_RES *current_page_res = nullptr;
118
119STRING_VAR(editor_image_win_name, "EditorImage", "Editor image window name");
120INT_VAR(editor_image_xpos, 590, "Editor image X Pos");
121INT_VAR(editor_image_ypos, 10, "Editor image Y Pos");
122static INT_VAR(editor_image_menuheight, 50, "Add to image height for menu bar");
125
126STRING_VAR(editor_word_name, "BlnWords", "BL normalized word window");
127INT_VAR(editor_word_xpos, 60, "Word window X Pos");
128INT_VAR(editor_word_ypos, 510, "Word window Y Pos");
129INT_VAR(editor_word_height, 240, "Word window height");
130INT_VAR(editor_word_width, 655, "Word window width");
131
139static void show_point(PAGE_RES *page_res, float x, float y) {
140 FCOORD pt(x, y);
141 PAGE_RES_IT pr_it(page_res);
142
143 const int kBufsize = 512;
144 char msg[kBufsize];
145 char *msg_ptr = msg;
146
147 msg_ptr += sprintf(msg_ptr, "Pt:(%0.3f, %0.3f) ", x, y);
148
149 for (WERD_RES *word = pr_it.word(); word != nullptr; word = pr_it.forward()) {
150 if (pr_it.row() != pr_it.prev_row() && pr_it.row()->row->bounding_box().contains(pt)) {
151 msg_ptr += sprintf(msg_ptr, "BL(x)=%0.3f ", pr_it.row()->row->base_line(x));
152 }
153 if (word->word->bounding_box().contains(pt)) {
154 TBOX box = word->word->bounding_box();
155 msg_ptr += sprintf(msg_ptr, "Wd(%d, %d)/(%d, %d) ", box.left(), box.bottom(), box.right(),
156 box.top());
157 C_BLOB_IT cblob_it(word->word->cblob_list());
158 for (cblob_it.mark_cycle_pt(); !cblob_it.cycled_list(); cblob_it.forward()) {
159 C_BLOB *cblob = cblob_it.data();
160 box = cblob->bounding_box();
161 if (box.contains(pt)) {
162 msg_ptr += sprintf(msg_ptr, "CBlb(%d, %d)/(%d, %d) ", box.left(), box.bottom(),
163 box.right(), box.top());
164 }
165 }
166 }
167 }
168 image_win->AddMessage(msg);
169}
170
177static void pgeditor_msg( // message display
178 const char *msg) {
179 image_win->AddMessage(msg);
180}
181
183public:
184 void Notify(const SVEvent *sv_event) override {
185 if (sv_event->type == SVET_DESTROY) {
186 bln_word_window = nullptr;
187 } else if (sv_event->type == SVET_CLICK) {
188 show_point(current_page_res, sv_event->x, sv_event->y);
189 }
190 }
191};
192
198static ScrollView *bln_word_window_handle() { // return handle
199 // not opened yet
200 if (bln_word_window == nullptr) {
201 pgeditor_msg("Creating BLN word window...");
202 bln_word_window = new ScrollView(editor_word_name.c_str(), editor_word_xpos, editor_word_ypos,
203 editor_word_width, editor_word_height, 4000, 4000, true);
204 auto *a = new BlnEventHandler();
205 bln_word_window->AddEventHandler(a);
206 pgeditor_msg("Creating BLN word window...Done");
207 }
208 return bln_word_window;
209}
210
218static void build_image_window(int width, int height) {
219 delete image_win;
220 image_win = new ScrollView(editor_image_win_name.c_str(), editor_image_xpos, editor_image_ypos,
221 width + 1, height + editor_image_menuheight + 1, width, height, true);
222}
223
230static void display_bln_lines(ScrollView *window, ScrollView::Color colour, float scale_factor,
231 float y_offset, float minx, float maxx) {
232 window->Pen(colour);
233 window->Line(minx, y_offset + scale_factor * DESC_HEIGHT, maxx,
234 y_offset + scale_factor * DESC_HEIGHT);
235 window->Line(minx, y_offset + scale_factor * BL_HEIGHT, maxx,
236 y_offset + scale_factor * BL_HEIGHT);
237 window->Line(minx, y_offset + scale_factor * X_HEIGHT, maxx, y_offset + scale_factor * X_HEIGHT);
238 window->Line(minx, y_offset + scale_factor * ASC_HEIGHT, maxx,
239 y_offset + scale_factor * ASC_HEIGHT);
240}
241
250void PGEventHandler::Notify(const SVEvent *event) {
251 char myval = '0';
252 if (event->type == SVET_POPUP) {
253 pe->Notify(event);
254 } // These are handled by ParamsEditor
255 else if (event->type == SVET_EXIT) {
256 stillRunning = false;
257 } else if (event->type == SVET_MENU) {
258 if (strcmp(event->parameter, "true") == 0) {
259 myval = 'T';
260 } else if (strcmp(event->parameter, "false") == 0) {
261 myval = 'F';
262 }
263 tess_->process_cmd_win_event(event->command_id, &myval);
264 } else {
265 tess_->process_image_event(*event);
266 }
267}
268
275 SVMenuNode *parent_menu;
276 auto *root_menu_item = new SVMenuNode();
277
278 SVMenuNode *modes_menu_item = root_menu_item->AddChild("MODES");
279
280 modes_menu_item->AddChild("Change Display", CHANGE_DISP_CMD_EVENT);
281 modes_menu_item->AddChild("Dump Word", DUMP_WERD_CMD_EVENT);
282 modes_menu_item->AddChild("Show Point", SHOW_POINT_CMD_EVENT);
283 modes_menu_item->AddChild("Show BL Norm Word", SHOW_BLN_WERD_CMD_EVENT);
284 modes_menu_item->AddChild("Config Words", DEBUG_WERD_CMD_EVENT);
285 modes_menu_item->AddChild("Recog Words", RECOG_WERDS);
286 modes_menu_item->AddChild("Recog Blobs", RECOG_PSEUDO);
287 modes_menu_item->AddChild("Show Blob Features", SHOW_BLOB_FEATURES);
288
289 parent_menu = root_menu_item->AddChild("DISPLAY");
290
291 parent_menu->AddChild("Blamer", BLAMER_CMD_EVENT, false);
292 parent_menu->AddChild("Bounding Boxes", BOUNDING_BOX_CMD_EVENT, false);
293 parent_menu->AddChild("Correct Text", CORRECT_TEXT_CMD_EVENT, false);
294 parent_menu->AddChild("Polygonal Approx", POLYGONAL_CMD_EVENT, false);
295 parent_menu->AddChild("Baseline Normalized", BL_NORM_CMD_EVENT, false);
296 parent_menu->AddChild("Edge Steps", BITMAP_CMD_EVENT, true);
297 parent_menu->AddChild("Subscripts", SHOW_SUBSCRIPT_CMD_EVENT);
298 parent_menu->AddChild("Superscripts", SHOW_SUPERSCRIPT_CMD_EVENT);
299 parent_menu->AddChild("Italics", SHOW_ITALIC_CMD_EVENT);
300 parent_menu->AddChild("Bold", SHOW_BOLD_CMD_EVENT);
301 parent_menu->AddChild("Underline", SHOW_UNDERLINE_CMD_EVENT);
302 parent_menu->AddChild("FixedPitch", SHOW_FIXEDPITCH_CMD_EVENT);
303 parent_menu->AddChild("Serifs", SHOW_SERIF_CMD_EVENT);
304 parent_menu->AddChild("SmallCaps", SHOW_SMALLCAPS_CMD_EVENT);
305 parent_menu->AddChild("DropCaps", SHOW_DROPCAPS_CMD_EVENT);
306
307 parent_menu = root_menu_item->AddChild("OTHER");
308
309 parent_menu->AddChild("Quit", QUIT_CMD_EVENT);
310 parent_menu->AddChild("Show Image", IMAGE_CMD_EVENT, false);
311 parent_menu->AddChild("ShowBlock Outlines", BLOCKS_CMD_EVENT, false);
312 parent_menu->AddChild("Show Baselines", BASELINES_CMD_EVENT, false);
313 parent_menu->AddChild("Uniform Display", UNIFORM_DISP_CMD_EVENT);
314 parent_menu->AddChild("Refresh Display", REFRESH_CMD_EVENT);
315
316 return root_menu_item;
317}
318
324void Tesseract::do_re_display(bool (tesseract::Tesseract::*word_painter)(PAGE_RES_IT *pr_it)) {
325 int block_count = 1;
326
327 image_win->Clear();
328 if (display_image) {
329 image_win->Draw(pix_binary_, 0, 0);
330 }
331
332 image_win->Brush(ScrollView::NONE);
333 PAGE_RES_IT pr_it(current_page_res);
334 for (WERD_RES *word = pr_it.word(); word != nullptr; word = pr_it.forward()) {
335 (this->*word_painter)(&pr_it);
336 if (display_baselines && pr_it.row() != pr_it.prev_row()) {
337 pr_it.row()->row->plot_baseline(image_win, ScrollView::GREEN);
338 }
339 if (display_blocks && pr_it.block() != pr_it.prev_block()) {
340 pr_it.block()->block->pdblk.plot(image_win, block_count++, ScrollView::RED);
341 }
342 }
343 image_win->Update();
344}
345
354void Tesseract::pgeditor_main(int width, int height, PAGE_RES *page_res) {
355 current_page_res = page_res;
356 if (current_page_res->block_res_list.empty()) {
357 return;
358 }
359
360 recog_done = false;
361 stillRunning = true;
362
363 build_image_window(width, height);
364 word_display_mode.set(DF_EDGE_STEP);
366# ifndef GRAPHICS_DISABLED
367 pe = new ParamsEditor(this, image_win);
368# endif
369 PGEventHandler pgEventHandler(this);
370
371 image_win->AddEventHandler(&pgEventHandler);
372 image_win->AddMessageBox();
373
374 SVMenuNode *svMenuRoot = build_menu_new();
375
376 svMenuRoot->BuildMenu(image_win);
377 image_win->SetVisible(true);
378
379 image_win->AwaitEvent(SVET_DESTROY);
380 image_win->AddEventHandler(nullptr);
381}
382
390bool Tesseract::process_cmd_win_event( // UI command semantics
391 int32_t cmd_event, // which menu item?
392 char *new_value // any prompt data
393) {
394 char msg[160];
395 bool exit = false;
396
397 color_mode = CM_RAINBOW;
398
399 // Run recognition on the full page if needed.
400 switch (cmd_event) {
401 case BLAMER_CMD_EVENT:
411 if (!recog_done) {
412 recog_all_words(current_page_res, nullptr, nullptr, nullptr, 0);
413 recog_done = true;
414 }
415 break;
416 default:
417 break;
418 }
419
420 char *parameter;
421
422 switch (cmd_event) {
423 case NULL_CMD_EVENT:
424 break;
425
430 case RECOG_WERDS:
431 case RECOG_PSEUDO:
433 mode = static_cast<CMD_EVENTS>(cmd_event);
434 break;
437 parameter = image_win->ShowInputDialog("Config File Name");
438 word_config_ = parameter;
439 delete[] parameter;
440 break;
442 if (new_value[0] == 'T') {
443 word_display_mode.set(DF_BOX);
444 } else {
445 word_display_mode.reset(DF_BOX);
446 }
448 break;
449 case BLAMER_CMD_EVENT:
450 if (new_value[0] == 'T') {
451 word_display_mode.set(DF_BLAMER);
452 } else {
453 word_display_mode.reset(DF_BLAMER);
454 }
457 break;
459 if (new_value[0] == 'T') {
460 word_display_mode.set(DF_TEXT);
461 } else {
462 word_display_mode.reset(DF_TEXT);
463 }
465 break;
467 if (new_value[0] == 'T') {
468 word_display_mode.set(DF_POLYGONAL);
469 } else {
470 word_display_mode.reset(DF_POLYGONAL);
471 }
473 break;
475 if (new_value[0] == 'T') {
476 word_display_mode.set(DF_BN_POLYGONAL);
477 } else {
478 word_display_mode.reset(DF_BN_POLYGONAL);
479 }
481 break;
482 case BITMAP_CMD_EVENT:
483 if (new_value[0] == 'T') {
484 word_display_mode.set(DF_EDGE_STEP);
485 } else {
486 word_display_mode.reset(DF_EDGE_STEP);
487 }
489 break;
492 break;
493 case IMAGE_CMD_EVENT:
494 display_image = (new_value[0] == 'T');
496 break;
497 case BLOCKS_CMD_EVENT:
498 display_blocks = (new_value[0] == 'T');
500 break;
502 display_baselines = (new_value[0] == 'T');
504 break;
506 color_mode = CM_SUBSCRIPT;
508 break;
510 color_mode = CM_SUPERSCRIPT;
512 break;
514 color_mode = CM_ITALIC;
516 break;
518 color_mode = CM_BOLD;
520 break;
522 color_mode = CM_UNDERLINE;
524 break;
526 color_mode = CM_FIXEDPITCH;
528 break;
530 color_mode = CM_SERIF;
532 break;
534 color_mode = CM_SMALLCAPS;
536 break;
538 color_mode = CM_DROPCAPS;
540 break;
543 break;
544 case QUIT_CMD_EVENT:
545 exit = true;
547 break;
548
549 default:
550 snprintf(msg, sizeof(msg), "Unrecognised event %" PRId32 "(%s)", cmd_event, new_value);
551 image_win->AddMessage(msg);
552 break;
553 }
554 return exit;
555}
556
566void Tesseract::process_image_event( // action in image win
567 const SVEvent &event) {
568 // The following variable should remain static, since it is used by
569 // debug editor, which uses a single Tesseract instance.
570 static ICOORD down;
571 ICOORD up;
572 TBOX selection_box;
573 char msg[80];
574
575 switch (event.type) {
576 case SVET_SELECTION:
577 if (event.type == SVET_SELECTION) {
578 down.set_x(event.x + event.x_size);
579 down.set_y(event.y + event.y_size);
580 if (mode == SHOW_POINT_CMD_EVENT) {
581 show_point(current_page_res, event.x, event.y);
582 }
583 }
584
585 up.set_x(event.x);
586 up.set_y(event.y);
587
588 selection_box = TBOX(down, up);
589
590 switch (mode) {
592 process_selected_words(current_page_res, selection_box,
594 break;
596 process_selected_words(current_page_res, selection_box,
598 break;
600 process_selected_words(current_page_res, selection_box,
602 break;
604 debug_word(current_page_res, selection_box);
605 break;
607 break; // ignore up event
608
609 case RECOG_WERDS:
610# ifndef DISABLED_LEGACY_ENGINE
611 image_win->AddMessage("Recogging selected words");
612 this->process_selected_words(current_page_res, selection_box,
614# endif // ndef DISABLED_LEGACY_ENGINE
615 break;
616 case RECOG_PSEUDO:
617 image_win->AddMessage("Recogging selected blobs");
618 recog_pseudo_word(current_page_res, selection_box);
619 break;
621 blob_feature_display(current_page_res, selection_box);
622 break;
623
624 default:
625 sprintf(msg, "Mode %d not yet implemented", mode);
626 image_win->AddMessage(msg);
627 break;
628 }
629 default:
630 break;
631 }
632}
633
639void Tesseract::debug_word(PAGE_RES *page_res, const TBOX &selection_box) {
640# ifndef DISABLED_LEGACY_ENGINE
642# endif
643 recog_all_words(page_res, nullptr, &selection_box, word_config_.c_str(), 0);
644}
645
646/**********************************************************************
647 * WERD PROCESSOR FUNCTIONS
648 * ========================
649 *
650 * These routines are invoked by one or more of:
651 * process_all_words()
652 * process_selected_words()
653 * or
654 * process_all_words_it()
655 * process_selected_words_it()
656 * for each word to be processed
657 **********************************************************************/
658
668 return word_set_display(pr_it);
669}
670
677 WERD_RES *word_res = pr_it->word();
678 if (word_res->chopped_word == nullptr) {
679 // Setup word normalization parameters.
680 word_res->SetupForRecognition(unicharset, this, BestPix(), tessedit_ocr_engine_mode, nullptr,
681 classify_bln_numeric_mode, textord_use_cjk_fp_model,
682 poly_allow_detailed_fx, pr_it->row()->row, pr_it->block()->block);
683 }
684 bln_word_window_handle()->Clear();
685 display_bln_lines(bln_word_window_handle(), ScrollView::CYAN, 1.0, 0.0f, -1000.0f, 1000.0f);
686 C_BLOB_IT it(word_res->word->cblob_list());
688 for (it.mark_cycle_pt(); !it.cycled_list(); it.forward()) {
689 it.data()->plot_normed(word_res->denorm, color, ScrollView::BROWN, bln_word_window_handle());
690 color = WERD::NextColor(color);
691 }
692 bln_word_window_handle()->Update();
693 return true;
694}
695
702 WERD_RES *word_res = pr_it->word();
703 WERD *word = word_res->word;
704 TBOX word_bb; // word bounding box
705 int word_height; // ht of word BB
706 bool displayed_something = false;
707 float shift; // from bot left
708
709 if (color_mode != CM_RAINBOW && word_res->box_word != nullptr) {
710# ifndef DISABLED_LEGACY_ENGINE
711 BoxWord *box_word = word_res->box_word;
712 WERD_CHOICE *best_choice = word_res->best_choice;
713 int length = box_word->length();
714 if (word_res->fontinfo == nullptr) {
715 return false;
716 }
717 const FontInfo &font_info = *word_res->fontinfo;
718 for (int i = 0; i < length; ++i) {
720 switch (color_mode) {
721 case CM_SUBSCRIPT:
722 if (best_choice->BlobPosition(i) == SP_SUBSCRIPT) {
723 color = ScrollView::RED;
724 }
725 break;
726 case CM_SUPERSCRIPT:
727 if (best_choice->BlobPosition(i) == SP_SUPERSCRIPT) {
728 color = ScrollView::RED;
729 }
730 break;
731 case CM_ITALIC:
732 if (font_info.is_italic()) {
733 color = ScrollView::RED;
734 }
735 break;
736 case CM_BOLD:
737 if (font_info.is_bold()) {
738 color = ScrollView::RED;
739 }
740 break;
741 case CM_FIXEDPITCH:
742 if (font_info.is_fixed_pitch()) {
743 color = ScrollView::RED;
744 }
745 break;
746 case CM_SERIF:
747 if (font_info.is_serif()) {
748 color = ScrollView::RED;
749 }
750 break;
751 case CM_SMALLCAPS:
752 if (word_res->small_caps) {
753 color = ScrollView::RED;
754 }
755 break;
756 case CM_DROPCAPS:
757 if (best_choice->BlobPosition(i) == SP_DROPCAP) {
758 color = ScrollView::RED;
759 }
760 break;
761 // TODO(rays) underline is currently completely unsupported.
762 case CM_UNDERLINE:
763 default:
764 break;
765 }
766 image_win->Pen(color);
767 TBOX box = box_word->BlobBox(i);
768 image_win->Rectangle(box.left(), box.bottom(), box.right(), box.top());
769 }
770 return true;
771# else
772 return false;
773# endif // ndef DISABLED_LEGACY_ENGINE
774 }
775 /*
776 Note the double coercions of(COLOUR)((int32_t)editor_image_word_bb_color)
777 etc. are to keep the compiler happy.
778*/
779 // display bounding box
780 if (word->display_flag(DF_BOX)) {
781 word->bounding_box().plot(image_win,
782 static_cast<ScrollView::Color>((int32_t)editor_image_word_bb_color),
783 static_cast<ScrollView::Color>((int32_t)editor_image_word_bb_color));
784
785 auto c = static_cast<ScrollView::Color>((int32_t)editor_image_blob_bb_color);
786 image_win->Pen(c);
787 // cblob iterator
788 C_BLOB_IT c_it(word->cblob_list());
789 for (c_it.mark_cycle_pt(); !c_it.cycled_list(); c_it.forward()) {
790 c_it.data()->bounding_box().plot(image_win);
791 }
792 displayed_something = true;
793 }
794
795 // display edge steps
796 if (word->display_flag(DF_EDGE_STEP)) { // edgesteps available
797 word->plot(image_win); // rainbow colors
798 displayed_something = true;
799 }
800
801 // display poly approx
802 if (word->display_flag(DF_POLYGONAL)) {
803 // need to convert
804 TWERD *tword = TWERD::PolygonalCopy(poly_allow_detailed_fx, word);
805 tword->plot(image_win);
806 delete tword;
807 displayed_something = true;
808 }
809
810 // Display correct text and blamer information.
811 std::string text;
812 std::string blame;
813 if (word->display_flag(DF_TEXT) && word->text() != nullptr) {
814 text = word->text();
815 }
816 if (word->display_flag(DF_BLAMER) &&
817 !(word_res->blamer_bundle != nullptr &&
819 text = "";
820 const BlamerBundle *blamer_bundle = word_res->blamer_bundle;
821 if (blamer_bundle == nullptr) {
822 text += "NULL";
823 } else {
824 text = blamer_bundle->TruthString();
825 }
826 text += " -> ";
827 std::string best_choice_str;
828 if (word_res->best_choice == nullptr) {
829 best_choice_str = "NULL";
830 } else {
831 word_res->best_choice->string_and_lengths(&best_choice_str, nullptr);
832 }
833 text += best_choice_str;
834 IncorrectResultReason reason =
835 (blamer_bundle == nullptr) ? IRR_PAGE_LAYOUT : blamer_bundle->incorrect_result_reason();
837 blame += " [";
838 blame += BlamerBundle::IncorrectReasonName(reason);
839 blame += "]";
840 }
841 if (text.length() > 0) {
842 word_bb = word->bounding_box();
843 image_win->Pen(ScrollView::RED);
844 word_height = word_bb.height();
845 int text_height = 0.50 * word_height;
846 if (text_height > 20) {
847 text_height = 20;
848 }
849 image_win->TextAttributes("Arial", text_height, false, false, false);
850 shift = (word_height < word_bb.width()) ? 0.25 * word_height : 0.0f;
851 image_win->Text(word_bb.left() + shift, word_bb.bottom() + 0.25 * word_height, text.c_str());
852 if (blame.length() > 0) {
853 image_win->Text(word_bb.left() + shift, word_bb.bottom() + 0.25 * word_height - text_height,
854 blame.c_str());
855 }
856
857 displayed_something = true;
858 }
859
860 if (!displayed_something) { // display BBox anyway
861 word->bounding_box().plot(image_win,
862 static_cast<ScrollView::Color>((int32_t)editor_image_word_bb_color),
863 static_cast<ScrollView::Color>((int32_t)editor_image_word_bb_color));
864 }
865 return true;
866}
867} // namespace tesseract
868#endif // !GRAPHICS_DISABLED
869
870namespace tesseract {
877 if (pr_it->block()->block != nullptr) {
878 tprintf("\nBlock data...\n");
879 pr_it->block()->block->print(nullptr, false);
880 }
881 tprintf("\nRow data...\n");
882 pr_it->row()->row->print(nullptr);
883 tprintf("\nWord data...\n");
884 WERD_RES *word_res = pr_it->word();
885 word_res->word->print();
886 if (word_res->blamer_bundle != nullptr && wordrec_debug_blamer &&
888 tprintf("Current blamer debug: %s\n", word_res->blamer_bundle->debug().c_str());
889 }
890 return true;
891}
892
893#ifndef GRAPHICS_DISABLED
900 WERD *word = pr_it->word()->word;
901 word->set_display_flag(DF_BOX, word_display_mode[DF_BOX]);
902 word->set_display_flag(DF_TEXT, word_display_mode[DF_TEXT]);
903 word->set_display_flag(DF_POLYGONAL, word_display_mode[DF_POLYGONAL]);
904 word->set_display_flag(DF_EDGE_STEP, word_display_mode[DF_EDGE_STEP]);
905 word->set_display_flag(DF_BN_POLYGONAL, word_display_mode[DF_BN_POLYGONAL]);
906 word->set_display_flag(DF_BLAMER, word_display_mode[DF_BLAMER]);
907 return word_display(pr_it);
908}
909
910// page_res is non-const because the iterator doesn't know if you are going
911// to change the items it points to! Really a const here though.
912void Tesseract::blob_feature_display(PAGE_RES *page_res, const TBOX &selection_box) {
913# ifndef DISABLED_LEGACY_ENGINE
914 PAGE_RES_IT *it = make_pseudo_word(page_res, selection_box);
915 if (it != nullptr) {
916 WERD_RES *word_res = it->word();
917 word_res->x_height = it->row()->row->x_height();
918 word_res->SetupForRecognition(unicharset, this, BestPix(), tessedit_ocr_engine_mode, nullptr,
919 classify_bln_numeric_mode, textord_use_cjk_fp_model,
920 poly_allow_detailed_fx, it->row()->row, it->block()->block);
921 TWERD *bln_word = word_res->chopped_word;
922 TBLOB *bln_blob = bln_word->blobs[0];
923 INT_FX_RESULT_STRUCT fx_info;
924 std::vector<INT_FEATURE_STRUCT> bl_features;
925 std::vector<INT_FEATURE_STRUCT> cn_features;
926 Classify::ExtractFeatures(*bln_blob, classify_nonlinear_norm, &bl_features, &cn_features,
927 &fx_info, nullptr);
928 // Display baseline features.
929 ScrollView *bl_win = CreateFeatureSpaceWindow("BL Features", 512, 0);
931 for (auto &bl_feature : bl_features) {
932 RenderIntFeature(bl_win, &bl_feature, ScrollView::GREEN);
933 }
934 bl_win->Update();
935 // Display cn features.
936 ScrollView *cn_win = CreateFeatureSpaceWindow("CN Features", 512, 0);
938 for (auto &cn_feature : cn_features) {
939 RenderIntFeature(cn_win, &cn_feature, ScrollView::GREEN);
940 }
941 cn_win->Update();
942
943 it->DeleteCurrentWord();
944 delete it;
945 }
946# endif // ndef DISABLED_LEGACY_ENGINE
947}
948
949#endif // !GRAPHICS_DISABLED
950
951} // namespace tesseract
#define INT_VAR(name, val, comment)
Definition: params.h:356
#define STRING_VAR(name, val, comment)
Definition: params.h:362
#define ASSERT_HOST(x)
Definition: errcode.h:54
#define DESC_HEIGHT
Definition: pgedit.cpp:45
#define ASC_HEIGHT
Definition: pgedit.cpp:42
#define BL_HEIGHT
Definition: pgedit.cpp:44
#define X_HEIGHT
Definition: pgedit.cpp:43
@ TBOX
@ SHOW_SUBSCRIPT_CMD_EVENT
Definition: pgedit.cpp:69
@ DEBUG_WERD_CMD_EVENT
Definition: pgedit.cpp:53
@ SHOW_UNDERLINE_CMD_EVENT
Definition: pgedit.cpp:73
@ SHOW_SERIF_CMD_EVENT
Definition: pgedit.cpp:75
@ BASELINES_CMD_EVENT
Definition: pgedit.cpp:62
@ SHOW_BOLD_CMD_EVENT
Definition: pgedit.cpp:72
@ BLAMER_CMD_EVENT
Definition: pgedit.cpp:54
@ SHOW_BLN_WERD_CMD_EVENT
Definition: pgedit.cpp:52
@ RECOG_PSEUDO
Definition: pgedit.cpp:67
@ SHOW_SUPERSCRIPT_CMD_EVENT
Definition: pgedit.cpp:70
@ BL_NORM_CMD_EVENT
Definition: pgedit.cpp:58
@ REFRESH_CMD_EVENT
Definition: pgedit.cpp:64
@ BITMAP_CMD_EVENT
Definition: pgedit.cpp:59
@ DUMP_WERD_CMD_EVENT
Definition: pgedit.cpp:50
@ SHOW_BLOB_FEATURES
Definition: pgedit.cpp:68
@ SHOW_POINT_CMD_EVENT
Definition: pgedit.cpp:51
@ IMAGE_CMD_EVENT
Definition: pgedit.cpp:60
@ RECOG_WERDS
Definition: pgedit.cpp:66
@ NULL_CMD_EVENT
Definition: pgedit.cpp:48
@ SHOW_DROPCAPS_CMD_EVENT
Definition: pgedit.cpp:77
@ SHOW_FIXEDPITCH_CMD_EVENT
Definition: pgedit.cpp:74
@ CHANGE_DISP_CMD_EVENT
Definition: pgedit.cpp:49
@ CORRECT_TEXT_CMD_EVENT
Definition: pgedit.cpp:56
@ BOUNDING_BOX_CMD_EVENT
Definition: pgedit.cpp:55
@ BLOCKS_CMD_EVENT
Definition: pgedit.cpp:61
@ POLYGONAL_CMD_EVENT
Definition: pgedit.cpp:57
@ UNIFORM_DISP_CMD_EVENT
Definition: pgedit.cpp:63
@ QUIT_CMD_EVENT
Definition: pgedit.cpp:65
@ SHOW_SMALLCAPS_CMD_EVENT
Definition: pgedit.cpp:76
@ SHOW_ITALIC_CMD_EVENT
Definition: pgedit.cpp:71
ColorationMode
Definition: pgedit.cpp:80
@ CM_ITALIC
Definition: pgedit.cpp:84
@ CM_SUBSCRIPT
Definition: pgedit.cpp:82
@ CM_RAINBOW
Definition: pgedit.cpp:81
@ CM_FIXEDPITCH
Definition: pgedit.cpp:87
@ CM_BOLD
Definition: pgedit.cpp:85
@ CM_SMALLCAPS
Definition: pgedit.cpp:89
@ CM_SUPERSCRIPT
Definition: pgedit.cpp:83
@ CM_SERIF
Definition: pgedit.cpp:88
@ CM_DROPCAPS
Definition: pgedit.cpp:90
@ CM_UNDERLINE
Definition: pgedit.cpp:86
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:121
int editor_word_height
Definition: pgedit.cpp:129
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:120
@ SVET_SELECTION
Definition: scrollview.h:56
@ SVET_DESTROY
Definition: scrollview.h:53
@ SVET_POPUP
Definition: scrollview.h:61
@ SVET_CLICK
Definition: scrollview.h:55
@ 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:128
int editor_word_width
Definition: pgedit.cpp:130
@ 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:123
int editor_image_blob_bb_color
Definition: pgedit.cpp:124
void ClearFeatureSpaceWindow(NORM_METHOD norm_method, ScrollView *window)
Definition: intproto.cpp:887
int editor_word_xpos
Definition: pgedit.cpp:127
char * editor_image_win_name
Definition: pgedit.cpp:119
char * editor_word_name
Definition: pgedit.cpp:126
void Notify(const SVEvent *sve) override
Definition: paramsd.cpp:271
void Notify(const SVEvent *sv_event) override
Definition: pgedit.cpp:184
void Notify(const SVEvent *sve) override
Definition: pgedit.cpp:250
bool recog_interactive(PAGE_RES_IT *pr_it)
Definition: control.cpp:76
void process_image_event(const SVEvent &event)
Definition: pgedit.cpp:566
bool process_cmd_win_event(int32_t cmd_event, char *new_value)
Definition: pgedit.cpp:390
SVMenuNode * build_menu_new()
Definition: pgedit.cpp:274
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:701
bool word_bln_display(PAGE_RES_IT *pr_it)
Definition: pgedit.cpp:676
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:899
bool word_dumper(PAGE_RES_IT *pr_it)
Definition: pgedit.cpp:876
bool word_blank_and_set_display(PAGE_RES_IT *pr_its)
Definition: pgedit.cpp:666
void debug_word(PAGE_RES *page_res, const TBOX &selection_box)
Definition: pgedit.cpp:639
void pgeditor_main(int width, int height, PAGE_RES *page_res)
Definition: pgedit.cpp:354
void blob_feature_display(PAGE_RES *page_res, const TBOX &selection_box)
Definition: pgedit.cpp:912
void do_re_display(bool(tesseract::Tesseract::*word_painter)(PAGE_RES_IT *pr_it))
Definition: pgedit.cpp:324
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:73
char * ShowInputDialog(const char *msg)
Definition: scrollview.cpp:735
void AddMessage(const char *message)
Definition: scrollview.cpp:546
void TextAttributes(const char *font, int pixel_size, bool bold, bool italic, bool underlined)
Definition: scrollview.cpp:623
void Text(int x, int y, const char *mystring)
Definition: scrollview.cpp:648
void Draw(Image image, int x_pos, int y_pos)
Definition: scrollview.cpp:767
void SetVisible(bool visible)
Definition: scrollview.cpp:528
void Pen(Color color)
Definition: scrollview.cpp:723
static void Update()
Definition: scrollview.cpp:713
void AddEventHandler(SVEventHandler *listener)
Add an Event Listener to this ScrollView Window.
Definition: scrollview.cpp:418
void Brush(Color color)
Definition: scrollview.cpp:729
static void Exit()
Definition: scrollview.cpp:572
void Rectangle(int x1, int y1, int x2, int y2)
Definition: scrollview.cpp:589
SVEvent * AwaitEvent(SVEventType type)
Definition: scrollview.cpp:445
SVMenuNode * AddChild(const char *txt)
Definition: svmnode.cpp:59
void BuildMenu(ScrollView *sv, bool menu_bar=true)
Definition: svmnode.cpp:120