?? training.cpp
字號:
/* training.cpp : code for training vars and training-related GUI * Author: Maxie D. Schmidt (created 5/26/2006) */#include "training.h"// default values if no config file to load:bool new_scan_set = false;int scan_ignore_edges_top = 40;int scan_ignore_edges_bottom = 40;int scan_ignore_edges_left = 40;int scan_ignore_edges_right = 40;int space_int_padding = 10; // pxint line_height_int_padding = 10; // pxint trcfg_grid_size_x = 108;int trcfg_grid_size_y = 96;int trcfg_gridcell_size_x = 12;int trcfg_gridcell_size_y = 12;int trcfg_intersect_px = 10; // 1 is same as scan whole lineint_interval_t trcfg_space_int = create_interval(10, 20);int_interval_t trcfg_line_height_int = create_interval(70, 120);parse_list *tr_parse_list = NULL;profile *tr_profile = NULL;/////// related functions:void init_training(bool train_with_scan) { if(train_with_scan && pf->parsed) { tr_parse_list = new parse_list(*(pf->plist)); tr_parse_list->letters_parsed = true; pf->plist->clear(); pf->parsed = false; } else tr_parse_list = new parse_list();}void cleanup_training() { delete tr_parse_list; tr_parse_list = NULL; delete tr_profile; tr_profile = NULL;}bool parse_training(string img_text, vector<int> lines, vector<int> spint_lines) { if((lines.size() % 2) != 0) { log_error(ERROR_PARSE_ERROR, "tr. # lines is odd", NULL); return false; } else if((spint_lines.size() % 2) != 0) { log_error(ERROR_PARSE_ERROR, "spint # lines is odd", NULL); return false; } // get line intervals: int cur_interval_size; lines = sort_lower_to_upper(lines); spint_lines = sort_lower_to_upper(spint_lines); bool line_int_setup = true, spint_line_int_setup = true; if(new_scan_set && ((lines.size() == 0) || (spint_lines.size() == 0))) { log_error(ERROR_PARSE_ERROR, "Need intervals for new scan set.",NULL); return false; } else if(new_scan_set) { line_int_setup = false; spint_line_int_setup = false; } for(int i = 0; i < lines.size(); i += 2) { cur_interval_size = lines[i + 1] - lines[i] + 1; if(!line_int_setup) { trcfg_line_height_int.lower = max(cur_interval_size - line_height_int_padding, 0); trcfg_line_height_int.upper = cur_interval_size + line_height_int_padding; line_int_setup = true; } else { if(max(cur_interval_size - line_height_int_padding, 0) < trcfg_line_height_int.lower) trcfg_line_height_int.lower = max(cur_interval_size - line_height_int_padding, 0); else if((cur_interval_size + line_height_int_padding) > trcfg_line_height_int.upper) trcfg_line_height_int.upper = cur_interval_size + line_height_int_padding; } } // for i for(int j = 0; j < spint_lines.size(); j += 2) { cur_interval_size = spint_lines[j + 1] - spint_lines[j] + 1; if(!spint_line_int_setup) { trcfg_space_int.lower = max(cur_interval_size - space_int_padding, 0); trcfg_space_int.upper = cur_interval_size + space_int_padding; spint_line_int_setup = true; } else { if(max(cur_interval_size - space_int_padding, 0) < trcfg_space_int.lower) trcfg_space_int.lower = max(cur_interval_size - space_int_padding, 0); else if((cur_interval_size + space_int_padding) > trcfg_space_int.upper) trcfg_space_int.upper = cur_interval_size + space_int_padding; } } // for j // fill in the parse list (less character defs): if(!fill_parse_list(trcfg_line_height_int, pf, tr_parse_list)) return false; // add characters to the parse_list: int cur_text_pos = 0; //img_text = strip_newlines(img_text); img_text = strip_unused_chars(img_text); if(img_text.size() == 0) { log_error(ERROR_PARSE_ERROR, "no text to train with", NULL); return false; } parsed_line *cur_pl = tr_parse_list->pl_begin; if(cur_pl == NULL) { log_error(ERROR_PARSE_ERROR, "parse_list has no lines", NULL); return false; } // space interval: bool space_int_setup = true; if(new_scan_set) space_int_setup = false; while(cur_pl != NULL) { parsed_char *cur_pc = cur_pl->pc_begin; if(cur_pc == NULL) { log_error(ERROR_PARSE_ERROR, "line has no chars", NULL); return false; } while(cur_pc != NULL) { if(img_text[cur_text_pos] == ' ') { if(cur_pc != cur_pl->pc_begin) { // modify space interval: int cur_interval = cur_pc->self_node.self_box.xy.x - (cur_pc->prev->self_node.self_box.xy.x + cur_pc->prev->self_node.self_box.horiz_len); if(!space_int_setup) { trcfg_space_int.lower = max(cur_interval - space_int_padding, 0); trcfg_space_int.upper = cur_interval + space_int_padding; space_int_setup = true; } else { if(max(cur_interval - space_int_padding, 0) < trcfg_space_int.lower) trcfg_space_int.lower = max(cur_interval - space_int_padding, 0); else if((cur_interval + space_int_padding) > trcfg_space_int.upper) trcfg_space_int.upper = cur_interval + space_int_padding; } } cur_text_pos++; } cur_pc->self_node.character = img_text[cur_text_pos]; cur_pc = cur_pc->next; cur_text_pos++; if((cur_text_pos >= img_text.length()) && (cur_pc != NULL)) { log_error(ERROR_PARSE_ERROR, "insufficient # letters",NULL); return false; } } // while cur_pc cur_pl = cur_pl->next; } // while cur_pl new_scan_set = false; tr_parse_list->letters_parsed = true; signals.do_tr_clear_int_lines(); signals.do_tr_refresh(); return true;}bool remap_characters(parse_list *plist, string text) { if((plist == NULL) || (plist->pl_begin == NULL) || (plist->pl_begin->pc_begin == NULL)) { log_error(ERROR_PARSE_ERROR, "in remap_characters: NULL before map", NULL); return false; } text = trim_whitespace(text); text = strip_unused_chars(text); if(text.length() == 0) { log_error(ERROR_PARSE_ERROR, "in remap: no text to remap", NULL); return false; } int text_pos = 0; parsed_line *pl = plist->pl_begin; parsed_char *pc; while(pl != NULL) { pc = pl->pc_begin; while(pc != NULL) { if(text_pos == text.length()) { log_error(ERROR_PARSE_ERROR, "in remap: insuff. # chars", NULL); return false; } pc->self_node.character = text[text_pos]; text_pos++; pc = pc->next; } pl = pl->next; } return true;}bool tr_train_with_scan_replace_text() { parsed_line *cur_pl = tr_parse_list->pl_begin; parsed_char *cur_pc; translated_line t_line; t_line.line_num = 0; while(cur_pl != NULL) { t_line.line_num++; t_line.text = ""; cur_pc = cur_pl->pc_begin; while(cur_pc != NULL) { // spaces: if(cur_pc != cur_pl->pc_begin) { int char_spacing = cur_pc->self_node.self_box.xy.x - (cur_pc->prev->self_node.self_box.xy.x + cur_pc->prev->self_node.self_box.horiz_len); if((char_spacing >= trcfg_space_int.lower) && (char_spacing <= trcfg_space_int.upper)) t_line.text = t_line.text + ' '; } t_line.text = t_line.text + cur_pc->self_node.character; cur_pc = cur_pc->next; } // while cur_pc != NULL cur_pl = cur_pl->next; text_lines.push_back(t_line); signals.do_new_line(t_line); } // while cur_pl != NULL return true;}/////// drawing area:tr_drawing_area::tr_drawing_area(int size_x, int size_y) : drawing_area(size_x, size_y) { swin_vis_x = 0; swin_vis_y = 0; swin_vis_width = pf->width; swin_vis_height = pf->height; need_valid_vis = true; selected_line_index = -1; selected_spint_line_index = -1; selected_line_index0 = -1; selected_line_index1 = -1; split_chars_line_index = -1; dragging = false; selecting_lines = false; selected_chars = NULL; tool_split_chars_divider_pos = NULL; tool_join_letters = NULL; tool_rm_spots = NULL; tool_split_chars = NULL; tools_search_alternate = NULL; // setup X events: Gdk::EventMask mask = Gdk::BUTTON_PRESS_MASK | Gdk::BUTTON_RELEASE_MASK | Gdk::POINTER_MOTION_MASK; add_events(mask); // refresh after parsing: signals.signal_tr_refresh().connect(sigc::mem_fun(*this, &tr_drawing_area::on_signal_tr_refresh)); signals.signal_tr_clear_int_lines().connect(sigc::mem_fun(*this, &tr_drawing_area::on_signal_tr_clear_int_lines));}void tr_drawing_area::refresh() { if((pf != NULL) && (pf->is_valid)) draw_image(); draw_spint_lines(); draw_lines(); if(tr_parse_list->letters_parsed) draw_parse_list(tr_parse_list); draw_parse_boundary(); if(*tool_split_chars) draw_split_chars_lines(); if(*tool_join_letters || *tool_rm_spots || *tool_split_chars) draw_selected_chars();}void tr_drawing_area::add_line(int line) { lines.push_back(line); selected_line_index = lines.size() - 1; refresh();}void tr_drawing_area::delete_line() { if(lines.size() > 0) { lines.pop_back(); refresh(); }}vector<int> tr_drawing_area::get_lines() { return lines;}bool tr_drawing_area::add_spint_line(int line) { if((selected_line_index0 != -1) && (selected_line_index1 != -1)) { spint_lines.push_back(line); selected_spint_line_index = spint_lines.size() - 1; refresh(); return true; } log_error(ERROR_PARSE_ERROR, "Need to setup selected lines before adding a spint line.", NULL); return false;}bool tr_drawing_area::delete_spint_line() { if(spint_lines.size() > 0) { spint_lines.pop_back(); refresh(); return true; } else { log_error(ERROR_PARSE_ERROR, "Spint lines size is zero (cannot delete)", NULL); return false; }}vector<int> tr_drawing_area::get_spint_lines() { return spint_lines;}void tr_drawing_area::select_lines() { if((selected_line_index0 != -1) && (selected_line_index1 != -1)) { log_error(ERROR_PARSE_ERROR, "Need to clear the existing lines before selecting new ones.", NULL); return; } selecting_lines = true;}void tr_drawing_area::clear_select_lines() { selected_line_index0 = selected_line_index1 = -1; selecting_lines = false; selected_spint_line_index = -1; spint_lines.clear(); refresh();}void tr_drawing_area::set_swin_vis_props(int x, int y, int width, int height) { swin_vis_x = x; swin_vis_y = y; swin_vis_width = width;
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -