📄 page.h
字号:
/****************************************************************************** * 光学字符识别程序 * 文件名:page.h * 功能 :页面定义文件 * modified by PRTsinghua@hotmail.com******************************************************************************/#ifndef PAGE_H#define PAGE_H#include <iostream>#include <limits.h>#include <list>#include <vector>#include <qwidget.h>#include "kognition.h"#include "common.h"#include "common_gfx.h"#include "image.h"class BoundingBox {public: BoundingBox(): min_x( INT_MAX ), min_y( INT_MAX ), max_x( 0 ), max_y( 0 ), area( 0 ) {} BoundingBox( const BoundingBox &bb ) : min_x( bb.min_x ), min_y( bb.min_y ), max_x( bb.max_x ), max_y( bb.max_y ), area( bb.area ), part( bb.part ) {} ~BoundingBox() {} int width() const { return max_x - min_x + 1; } int height() const { return max_y - min_y + 1; } bool overhangs( const BoundingBox &bb ) const; // 检验包围盒是否悬挂于另一个之上 bool operator<( const BoundingBox& bb ) const { return (min_x < bb.min_x); } // 需要排序 int min_x; // 左边界 int min_y; // 上边界 int max_x; // 右边界 int max_y; // 底边 int area; // 包围盒中的面积 guarded_ptr<CharImage> part; // 图像包含字符的一部分 static const float overhang_ratio; // 容许的悬挂比率(根据字符宽度)};class MetaBox : public BoundingBox {public: void add_part( const BoundingBox &bb ); float get_x() const { return ( min_x + max_x )/2.0; } // 需要相关性 float get_y() const { return max_y; } // 同上 list< BoundingBox > parts;};class base_line; // 前向声明class char_line : public slist<MetaBox> {public: char_line() : sum_heights( 0 ), max_width( 0 ), max_height( 0 ), next_line_pos( 0 ), last_x_pos( 0 ), done( false ) {} void add_char( const BoundingBox &bb ); // 在字符行中增加新的字符 void add_char( const MetaBox &mb ); // 在字符行中添加metabox的一部分 iterator remove_char( char_line::iterator mb ); // 在字符行中移去字符 bool merge_line( char_line *line2 ); // 合并两行 bool same_line( int x, int y, bool store = false ); // 判断一个字符是否在某个字符行中 float distance( float x, float y ) const; // 计算某个点到基线的距离 bool intersects( const char_line &cl ) const; bool is_done() const { return done; } void set_done() { done = true; } void clear(); int get_avg_height() const { return base.num_points == 0 ? 0 : sum_heights/base.num_points; } // 字符平均高度 int get_max_width() const { return max_width; } int get_max_height() const { return max_height; } int get_next_line() const { return next_line_pos; } int get_last_x() const { return last_x_pos; } const BoundingBox* get_max_part( const base_line *baseline = NULL ) const; // 返回最高的字符 static const int min_correlation_chars; private: void extend_char( char_line::iterator mb, const BoundingBox &bb, bool correlate=true ); // 伴随包围盒的扩展metabox void extend_char( char_line::iterator mb, const MetaBox &bb ); int sum_heights; // 字符的高度和 int max_width; // 最长的包围盒的宽度 int max_height; // 最高的包围盒的高度 int next_line_pos; // 下一行的位置 int last_x_pos; // 上一个添加的字符的x坐标 bool done; // 标识符:该行是否已经识别 iterator marker; // 标识:上一个水平位置 correlation<MetaBox> base; // 相关基线 static const float vert_line_dist_ratio; // 线间距离};class base_line : public list< point<float> >{public: base_line( const char_line &chars ); float get_base_y( const MetaBox &mb ) const; float distance( int x, int y ) const; float get_angle() const { return angle; } const correlation< point<float> >* get_line() const { return &corr; } static const float y_variance_ratio; // 允许的与理想直线的偏移 static const float diaresis_ratio; // 悬挂点的高度private: correlation< point<float> > corr; float angle;};class SizeWalker: public CharImageWalker{public: SizeWalker( CharImage &image, BoundingBox &bbox ) : CharImageWalker( image ), bb( bbox ) {} virtual ~SizeWalker() {} private: virtual void walker_process2( int x, int y ); BoundingBox &bb;};class CopyWalker: public CharImageWalker{public: CopyWalker( CharImage &image, BoundingBox &bbox ) : CharImageWalker( image ), bb( bbox ) {}; virtual ~CopyWalker() {};private: virtual void walker_process( int x, int y ); virtual void walker_process2( int x, int y ); BoundingBox &bb;};class Page : public QWidget{ Q_OBJECTpublic: Page( KognitionApp *parent = 0, const char *name = 0 ); ~Page(); enum drawing_flags { draw_boundingboxes = 0x00000001, draw_metaboxes = 0x00000002, draw_baseline = 0x00000004, draw_basepoints = 0x00000008, draw_maxpart = 0x00000010, draw_bw = 0x00000020 }; bool load( const QString &filename ); // 加载图像 void recognize(const char *data_base_def=NULL); // 识别扫描图像 void clear(); // 清空数据和窗口 void drawRectangle( QPainter &p, float scale, int min_x, int min_y, int max_x, int max_y ); // 绘制矩形 void paintEvent(QPaintEvent *); // 重绘窗口 void mouseMoveEvent(QMouseEvent *e); // 跟踪鼠标移动 void change_line_thickness( bool bigger ); // 改变输出线条的粗细 void set_draw_flag( drawing_flags flag, bool state ); // 设置绘制输出的标识 void drawRecognitionState( QPixmap &pixmap, float scale, int pix_xpos, int pix_ypos); // 绘制信息 void makeSnapshot(); // 保存带有信息的页面到文件 void setScale( float scale ); // 输出的比例变换 float getScale( bool realScale = true ); float getDpiScale( float dpi, float target_size_cm, bool is_height ); // 输出到文件的比例变换 void setXPos( int xpos ); // 输出pixmap的x坐标 int getXPos() { return pix_xpos; } void setYPos( int ypos ); // 输出pixmap的y坐标 int getYPos() { return pix_ypos; } Image* img; // image类,用来识别 Histogram* hist; // histogram类 private: void extract_part( int x, int y, CharImage &source, BoundingBox &bb ); // 提取字符的一部分,用来建立包围盒 CharImage scan; // 扫描的图像 list<char_line> lines; // 字符行缓冲 static const float min_area_divisor; static const int very_long_character_ratio; static const int num_bufferlines; // 输出的窗口变量 QPixmap pix; // 带有调试信息的pixmap QPixmap pix_bw; // 黑白 pixmap,调试信息之用 int pix_xpos; // 输出 pixmap 的x坐标 int pix_ypos; // 输出 pixmap 的y坐标 float pix_scale; // 输出 pixmap 的比例(automatic scaling: -1 width & height, -2 width, -3 height) int pen_size; // 画笔大小 unsigned int draw_flags; // 绘制标识 KognitionApp *app;signals: void setStatusMsg(const QString &str);};inline float Page::getDpiScale( float dpi, float target_size_cm, bool is_height ){ float dots = target_size_cm*dpi / 2.54; if( is_height ) return dots / scan.height(); else return dots / scan.width();}inline ostream& operator<< ( ostream& o, BoundingBox bb ) { o << "min: (" << bb.min_x << "," << bb.min_y << ") - " "max: (" << bb.max_x << "," << bb.max_y << ") / " "character area: " << bb.area; return o;}#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -