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

📄 abstract_character.cpp

📁 《Visual C++数字图像识别技术典型案例》之光学字符识别技术源码
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/****************************************************************************** * 光学字符识别程序 * 文件名:abstract_aharacter.cpp * 功能  :抽象字符类实现文件 * modified by PRTsinghua@hotmail.com******************************************************************************/#include <stdlib.h>#include <ostream>#include "common.h"#include "abstract_character.h"using std::cout;using std::endl;/****************************************************************************** * 未匹配区域******************************************************************************/float abstract_connection::unmatched_area(const vector<abstract_singular_point> &aspv){	if( is_matched )		return 0;	float length=0;	point<float> p=aspv[singular_point_1];	list< point<float> >::iterator i=polyline.begin();	while( i!=polyline.end() )	{		length+=euklidian_distance(p.x,p.y, i->x,i->y);		p=*i;		++i;	}	length+=euklidian_distance(p.x,p.y, aspv[singular_point_2].x,aspv[singular_point_2].y);	return weight*length*length;}/****************************************************************************** * <<操作******************************************************************************/ostream& operator<< (ostream& o, point<float> &p){	o << '(' << p.x << ',' << p.y << ')';	return o;}/****************************************************************************** * <<操作******************************************************************************/ostream& operator<< (ostream& o, abstract_character &c){	int nr=0;	o << "--- singular points ---" << endl;	for(vector<abstract_singular_point>::iterator i=c.aspv.begin(); i!=c.aspv.end(); ++i)	{		o << nr++ << ": (" << i->x << ',' << i->y << ") is " << i->type << " with connections: ";		for(list<int>::iterator j=i->acl.begin(); j!=i->acl.end(); ++j)		{			if( j!=i->acl.begin() )				o << ", ";			o << *j;		}		o << endl;	}		nr=0;	o << "--- connections ---" << endl;	for(vector<abstract_connection>::iterator i=c.acv.begin(); i!=c.acv.end(); ++i)	{		o << nr++ << ": " << i->singular_point_1 << "->" << i->singular_point_2 << " is " << i->type <<		     " with polygon points: ";		for(list< point<float> >::iterator j=i->polyline.begin(); j!=i->polyline.end(); ++j)			o << '(' << j->x << ',' << j->y << ") ";		o << endl;	}	return o;}/****************************************************************************** * <<操作******************************************************************************/ostream& operator<< (ostream& o, const path& p){	o << p.singular_point_1 << "-[";	for(list<int>::const_iterator i=p.connections.begin(); i!=p.connections.end(); ++i)	{		if( i!=p.connections.begin() )			o << ", ";		cout << *i;	}	o << "]->" << p.singular_point_2;	return o;}/****************************************************************************** * 变换操作 * 参数:angle    旋转角度 *       scale    变化比例 *       x        x 坐标 *       y        y 坐标 * 返回:无******************************************************************************/transformation::transformation(float angle, float scale, float x, float y) :	min_x(FLT_MAX),	max_x(-FLT_MAX),	min_y(FLT_MAX),	max_y(-FLT_MAX),	scale_factor(scale),	x_0(x),	y_0(y),	a(cos(angle)),	b(-sin(angle)),	c(sin(angle)),	d(cos(angle)){}/****************************************************************************** * 平移变换 * 参数:x        x坐标 *       y        y坐标 *       t_x      x方向平移坐标 *       t_y      y方向平移坐标 * 返回:无******************************************************************************/void transformation::transform(float x, float y, float &t_x, float &t_y){	x=scale_factor*(x-x_0);	y=scale_factor*(-y-y_0);	t_x=a*x+b*y;	t_y=c*x+d*y;	if( t_x<min_x )		min_x=t_x;	if( t_x>max_x )		max_x=t_x;	if( t_y<min_y )		min_y=t_y;	if( t_y>max_y )		max_y=t_y;}/****************************************************************************** * 开始跟踪路径******************************************************************************/path::const_iterator path::begin() const{	const_iterator it;	it.base_char=base_char;	it.cached_point=&(base_char->aspv[singular_point_1]);	it.end_state=false;	it.end_point=singular_point_1;	it.con_iter=connections.begin();	it.con_last=--connections.end();	it.setup_polyline_iterators();	return it;}/****************************************************************************** * 重新开始跟踪路径******************************************************************************/path::const_reverse_iterator path::rbegin() const{	const_reverse_iterator it;	it.base_char=base_char;	it.cached_point=&(base_char->aspv[singular_point_2]);	it.end_state=false;	it.end_point=singular_point_2;	it.con_iter=--connections.end();	it.con_last=connections.begin();	it.setup_polyline_iterators();	return it;}/****************************************************************************** * 获得未匹配的分歧点******************************************************************************/float path::get_unmatched_divergence(){	float divergence=0;	float x=0,y=0;	for(const_iterator i=begin(); i!=end(); ++i)	{		if( i!=begin() && !i.is_matched() )		{			float segment_area=euklidian_distance(x,y, i->x,i->y);			divergence+=i.get_weight()*segment_area*segment_area;		}		x=i->x;		y=i->y;	}	return divergence;}/****************************************************************************** * 标记未匹配的部分******************************************************************************/void path::mark_unmatched(){	for(list<int>::iterator i=connections.begin(); i!=connections.end(); ++i)		base_char->acv[*i].is_matched=true;}/****************************************************************************** * 标记******************************************************************************/void path::mark(){	for(list<int>::iterator i=connections.begin(); i!=connections.end(); ++i)	{		base_char->acv[*i].is_matched=true;		base_char->acv[*i].weight+=1.0;	}}/****************************************************************************** * 内部路径******************************************************************************/inner_path::inner_path(abstract_character &ac, int start_point, int end_point) : path(&ac){	singular_point_1=start_point;	singular_point_2=end_point;}/****************************************************************************** * 附加连接******************************************************************************/bool inner_path::append_connection(int con){	if( contains_connection(con) )		return false;	connections.push_back(con);	return true;}/****************************************************************************** * 路径树构造函数******************************************************************************/tree_path::tree_path(abstract_character &ac, int start_point) : path(&ac){	singular_point_1=start_point;	singular_point_2=start_point;}/****************************************************************************** * 附加连接******************************************************************************/bool tree_path::append_connection(int con){	assert( singular_point_1!=-1 );	if( contains_connection(con) )		return false;	connections.push_back(con);	singular_point_2=base_char->acv[con].walk(end_point());	return true;}/****************************************************************************** * 移除最后一个连接******************************************************************************/void tree_path::remove_last_connection(){	singular_point_2=base_char->acv[connections.back()].walk(end_point());	connections.pop_back();}/****************************************************************************** * hash表******************************************************************************/namespace __gnu_cxx {template<> struct hash< const singular_point* >{	size_t operator()( const singular_point* const&  key ) const	{		return reinterpret_cast<size_t>(key);	// hash value is the pointer itself	}};/****************************************************************************** * hash表******************************************************************************/template<> struct hash< const connection* >{	size_t operator()( const connection* const& key ) const	{		return reinterpret_cast<size_t>(key);	}};}/****************************************************************************** * 移除连接******************************************************************************/int abstract_character::resolve_con(	const connection *con,	hash_map<const singular_point*, int, hash<const singular_point*> > &spmap,	hash_map<const connection*, int, hash<const connection*> > &conmap,	transformation &T){	hash_map<const connection*, int, hash<const connection*> >::iterator coni = conmap.find(con);	if( coni!=conmap.end() )		return coni->second;	acv.push_back( abstract_connection() );	abstract_connection &acon=acv.back();	int aconnr=acv.size()-1;	conmap[con]=aconnr;	acon.type=con->type;	acon.singular_point_1=resolve_sp(con->point1,spmap,conmap,T);	acon.singular_point_2=resolve_sp(con->point2,spmap,conmap,T);	bool first=true;	for(list<skeleton_sequence>::const_iterator i=con->sseql.begin(); i!=con->sseql.end(); ++i)	{		float x,y;				if( first )		{			T.transform(i->first->aligned_x,i->first->aligned_y,x,y);			acon.polyline.push_back( point<float>(x,y) );			first=false;		}		T.transform(i->last->aligned_x,i->last->aligned_y,x,y);		acon.polyline.push_back( point<float>(x,y) );	}	return aconnr;}/****************************************************************************** * 去除孤立点******************************************************************************/int abstract_character::resolve_sp(	const singular_point *sp,	hash_map<const singular_point*, int, hash<const singular_point*> > &spmap,	hash_map<const connection*, int, hash<const connection*> > &conmap,	transformation &T){	hash_map<const singular_point*, int, hash<const singular_point*> >::iterator spi = spmap.find(sp);	if( spi!=spmap.end() )		return spi->second;	aspv.push_back( abstract_singular_point() );	abstract_singular_point &asp=aspv.back();	int aspnr=aspv.size()-1;	spmap[sp]=aspnr;	T.transform(sp->x,sp->y,asp.x,asp.y);	asp.type=sp->type;	for(list< inner_sequence_start >::const_iterator j=sp->sequences.begin(); j!=sp->sequences.end(); ++j)		asp.add_connection( resolve_con(j->connect,spmap,conmap,T) );	return aspnr;}/****************************************************************************** * 笔划 * 参数:thickness  粗细 *       x1         点1的x坐标 *       y1         点1的y坐标 *       x2         点2的x坐标 *       y2         点2的y坐标******************************************************************************/void abstract_character::stroke(transformation &T,				float thickness,				float x1,				float y1,				float x2,				float y2){	float x=x2-x1,y=y2-y1;	if( is_equal(x*x+y*y,0) )	// 线是一个点	{		T.transform(x1,y1,x,y);		return;	}	thickness/=2;	float angle=atan2(y,x);	float dx=cos(angle-M_PI_2)*thickness;	float dy=sin(angle-M_PI_2)*thickness;	T.transform(x1+dx,y1+dy,x,y);	T.transform(x2+dx,y2+dy,x,y);	dx=cos(angle+M_PI_2)*thickness;	dy=sin(angle+M_PI_2)*thickness;	T.transform(x1+dx,y1+dy,x,y);	T.transform(x2+dx,y2+dy,x,y);}/******************************************************************************

⌨️ 快捷键说明

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