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

📄 character.h

📁 vc++数字图像识别技术典型案例
💻 H
字号:
/****************************************************************************** * 光学字符识别程序 * 文件名:character.h * 功能  :字符类定义文件 * modified by PRTsinghua@hotmail.com******************************************************************************/#ifndef CHARACTER_H#define CHARACTER_H#include <list>#include <complex>#include "common_gfx.h"#include "common_math.h"#include "segimage.h"using std::ostream;using std::polar;typedef	enum { left_curved=-1, straight=0, right_curved=1 } curvature_type;typedef	enum { end_point, branching_point, turning_point } point_type;inline curvature_type operator-(curvature_type t){	return static_cast<curvature_type>( -static_cast<int>(t) );};struct inner_point : public point<float>{	float direction;	// 方向	float thickness;	// 粗细	float aligned_x;	// 多边形终点: 交叉点x坐标	float aligned_y;	// 多边形终点: 交叉点y坐标	float angle;		// 夹角	inline void set_angle(const inner_point &prev, const inner_point &next);	};typedef list<inner_point> inner_sequence;struct correlation_info : public correlation<inner_point>{	void align_connection_point(const correlation_info &prev_ci);	inline void set_angle();};typedef correlation_info skeleton_sequence;struct singular_point;struct connection{	curvature_type type;				// 曲线类型	singular_point *point1;				// 起点	singular_point *point2;				// 终点	float length;						// 曲线长度	float mean_dist;					// 点线平均距离	list< skeleton_sequence > sseql;	// 多边形曲线近似	float distance_to_start( point<float> *p );	float distance_to_end( point<float> *p );};inline float connection::distance_to_start( point<float> *p ){	return euklidian_distance(p->x, p->y, sseql.front().first->aligned_x, sseql.front().first->aligned_y);}inline float connection::distance_to_end( point<float> *p ){	return euklidian_distance(p->x, p->y, sseql.back().last->aligned_x, sseql.back().last->aligned_y);}struct subconnection{	int curvature_signum;				// +/-1 凸/凹; 0 直线	int num_sequences;					// 序列数目	float length;						// 总的曲线长度	list<skeleton_sequence>::iterator start;	// 起点	list<skeleton_sequence>::iterator end;		// 终点	subconnection() : curvature_signum(0), num_sequences(0), length(0) {}	inline void add_sequence_at_front(list<skeleton_sequence>::iterator n);	inline void add_sequence(list<skeleton_sequence>::iterator n);	inline void remove_last_sequence();};struct  inner_sequence_start {	bool 		is_start;	inner_sequence*	sequence;	connection*	connect;	void get_connection_info(const subconnection &sc);	inner_sequence_start() : is_start(false) {}	~inner_sequence_start();};struct singular_point : public point<float>{	point_type type;	int area;	list< inner_sequence_start > sequences;		void set_type();	void delete_connection(connection *con);};class character{	public: 		list<singular_point> spl;		int min_x, min_y, max_x, max_y;			// 字符包围边界		float line_thickness;					// 截面平均粗细				character(const Segimage &segimage, list<Segimage::singularpoint> &spl_old);		// 缺省的析构函数释放了所有的变量	private:		static const float threshold;			// 如果方向的平均变化超过阈值,则停止		static const float lower_factor;		// 合并后更大的序列的百分比		static const float smooth_iterations_factor;	// 方向平滑次数		static const int lower_boundary;		// 骨架序列的上限点数		static const int sufficient_number;		// 骨架序列的下限点数		static const float md_threshold;		// 用来决定直线判断的经验相关系数阈值		static const float md_compound_threshold;				// 复合直线的距离均值阈值		static const float angle_treshold;						// 角度阈值		static const float acute_angle_threshold;				// 锐角阈值		static const float straight_line_threshold_for_merge;	// 直线合并阈值		static const float straight_line_lower_threshold_for_intersect;	// 两条线夹角的下阈值		static const float straight_line_upper_threshold_for_intersect;	// 两条线夹角的上阈值		static const float straight_line_threshold;				// 直线合并阈值		static const float curve_to_line_ratio;					// 曲线直线转换比		float long_line;						// 字符中长线的长度		float short_line;						// 字符中短线的长度		int char_size;							// 水平/垂直 大小中的相对大者		int min_sequence;						// 可能的直线最短距离		static void merge_segments(const skeleton_sequence &prev, 			const skeleton_sequence &curr, skeleton_sequence &result);		static void add_direction(complex<float> &c, float angle);		static bool is_bigger(list<skeleton_sequence>::iterator curr, 			list<skeleton_sequence>::iterator other, list< skeleton_sequence > &sseql);		bool is_good_line(const connection &conn);		float choose_direction(float dir, float last);		bool average_angle(const float a[], int num_elements, float &result);		void collect_curve_segments(list< skeleton_sequence > &sseql);		void detect_curves();		void identify_curves();		void strip_extra_line();		void find_dots();		void beautify();		void delete_connection(connection *con);};//// 内联函数定义///****************************************************************************** * 设置角度 * 参数:prev    前一个点 *       next    后一个点 * 返回:无******************************************************************************/inline void inner_point::set_angle(const inner_point &prev, const inner_point &next){	angle=angle_between(prev.aligned_x, prev.aligned_y, aligned_x, 		aligned_y, next.aligned_x, next.aligned_y);}/****************************************************************************** * 设置角度 * 参数:无 * 返回:无******************************************************************************/inline void correlation_info::set_angle(){	angle=atan2(last->y-first->y, last->x-first->x);}/****************************************************************************** * 序列前添加 * 参数:n    迭代器 * 返回:无******************************************************************************/inline void subconnection::add_sequence_at_front(list<skeleton_sequence>::iterator n){	if( num_sequences==0 )		end=n;	num_sequences++;	length+=euklidian_distance(n->first->aligned_x,n->first->aligned_y,		n->last->aligned_x,n->last->aligned_y);	start=n;}/****************************************************************************** * 增加序列一个 * 参数:n    迭代器 * 返回:无******************************************************************************/inline void subconnection::add_sequence(list<skeleton_sequence>::iterator n){	if( num_sequences==0 )		start=n;	num_sequences++;	length+=euklidian_distance(n->first->aligned_x,n->first->aligned_y,		n->last->aligned_x,n->last->aligned_y);	end=n;}/****************************************************************************** * 移去最后序列 * 参数:无 * 返回:无******************************************************************************/inline void subconnection::remove_last_sequence(){	assert( num_sequences>0 );	length-=euklidian_distance(end->first->aligned_x,end->first->aligned_y,		end->last->aligned_x,end->last->aligned_y);	num_sequences--;	if( num_sequences>0 )		end--;	if( num_sequences<=1 )		curvature_signum=0;}/****************************************************************************** * 添加方向 * 参数:c      复数 *       angle  角度 * 返回:无******************************************************************************/inline void character::add_direction(complex<float> &c, float angle){	c+=polar(1.0F,angle);}/****************************************************************************** * 选择方向 * 参数:dir    方向 *       last   最后一个 * 返回:方向******************************************************************************/inline float character::choose_direction(float dir, float last){	float d1=fabs(normalize_angle_pi(dir-last));	float d2=fabs(normalize_angle_pi(normalize_angle_pi(dir+M_PI)-last));	return d1<d2?dir:normalize_angle_pi(dir+M_PI);}/****************************************************************************** * 判断字符是否更大 * 参数:curr    当前迭代器 *       other   另一个迭代器 * 返回:是,则返回true,否则返回false******************************************************************************/inline bool character::is_bigger(list<skeleton_sequence>::iterator curr, 	list<skeleton_sequence>::iterator other, list< skeleton_sequence > &sseql){	return	other!=sseql.end() &&		other->num_points>=sufficient_number &&		(curr->num_points<=lower_boundary 		|| (curr->num_points<other->num_points*lower_factor));}/****************************************************************************** * 评价线的好坏 * 参数:conn   连接 * 返回:是好线,返回true,否则返回false******************************************************************************/inline bool character::is_good_line(const connection &conn){	return conn.type==straight && (conn.length>short_line 		|| (2*conn.length>line_thickness && conn.mean_dist<md_threshold));}#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -