⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 page.h

📁 《Visual C++数字图像识别技术典型案例》之光学字符识别技术源码
💻 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 + -