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

📄 common_gfx.cpp

📁 《Visual C++数字图像识别技术典型案例》之光学字符识别技术源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
		}	}}/****************************************************************************** * 画图标识******************************************************************************/void Histogram::toggle_draw_flag( unsigned int flag ){	if ( draw_flags & flag )		draw_flags &= ~flag;	// 清除标识	else		draw_flags |= flag;		// 设置标识}/****************************************************************************** * 键盘事件******************************************************************************/void Histogram::keyPressEvent( QKeyEvent *e ){	switch (e->key())	{	case Key_W:	toggle_draw_flag( draw_max_white );			break;	case Key_B:	toggle_draw_flag( draw_max_black );			break;	case Key_T:	toggle_draw_flag( draw_threshold );			break;	case Key_I:	toggle_draw_flag( draw_middle );			break;	case Key_M:	toggle_draw_flag( draw_mean_value );			break;	case Key_Print:	save();			break;	default:	if ( parent )			{				QKeyEvent accel_event(QEvent::Accel, e->key(), e->ascii(), 0);				QApplication::sendEvent( parent, &accel_event );				QApplication::sendEvent( parent, e );			}	}	repaint();}/****************************************************************************** * 边缘跟踪 * 参数:start_x  x起点坐标 *       start_y  y起点坐标 * 返回:无******************************************************************************/void Walker::walk_border( int start_x, int start_y ){	const int x_offset[] = { /* down */ 0, /* right */ 1, /* up */  0, /* left */ -1 };	const int y_offset[] = { /* down */ 1, /* right */ 0, /* up */ -1, /* left */  0 };	direction d = left, t;	int x = start_x, y = start_y;	int walker_x, walker_y;	int count = 0;	// 搜寻邻近的自由点	while ( !is_good_walker_start( walker_x = x + x_offset[d], walker_y = y + y_offset[d] ) && count++ < 4 )		++d;	if ( count >= 4 ) // 没有发现合适的起点		return;		walker_process2( walker_x, walker_y );	int first_walker_x = walker_x, first_walker_y = walker_y;		// 正确的方向	while( t = leftof(d), walker_x + x_offset[t] != x || walker_y + y_offset[t] != y )		++d;	int last_x = -1, last_y = -1;	int same_pixel_count = 0;	bool stopit = false;	do {		if ( !stopit && ( x != last_x || y != last_y ) )			{			walker_process( x, y );				last_x = x;			last_y = y;			same_pixel_count = 0;		}		else				same_pixel_count++;			if ( is_border_pixel( x = walker_x + x_offset[d], y = walker_y + y_offset[d] ) )			--d;		else		{			walker_process2( walker_x, walker_y );								walker_x = x;			walker_y = y;			t = leftof(d);			if ( !is_border_pixel( x = walker_x + x_offset[t], y = walker_y+y_offset[t] ) )		// 角点			{				walker_x = x;				walker_y = y;				++d; // 逆时针旋转				t = leftof(d);				x = walker_x + x_offset[t];				y = walker_y + y_offset[t];			}		}		if ( !( x != start_x || y != start_y || ( last_x == start_x && last_y == start_y && same_pixel_count < 3 ) ) )			stopit = true;	} while ( !stopit || walker_x != first_walker_x || walker_y != first_walker_y );}/****************************************************************************** * 判断是否好的起点 * 参数:x  x坐标 *       y  y坐标 * 返回:返回bool值******************************************************************************/bool CharImageWalker::is_good_walker_start( int x, int y ) const{	return	img.is_background( x, y ) &&		( !img.is_background( x-1, y ) || !img.is_background( x+1, y ) ||		  !img.is_background( x, y-1 ) || !img.is_background( x, y+1 ) );}float straight_line::function( float xval ) const{	// y = gradient * x + y_axis_intercept 	float gradient = tan( angle );	float y_axis_intercept = y - gradient * x;	return xval * gradient + y_axis_intercept;}/****************************************************************************** * 计算交叉点 * 参数:line2                  *       x_intersect     保存交叉点的x坐标 *       y_intersect     保存交叉点的y坐标 * 返回:返回bool值******************************************************************************/bool straight_line::intersect(const straight_line &line2, float &x_intersect, float &y_intersect) const{	float angle1 = normalize_line_angle( angle + M_PI_2 );	float angle2 = normalize_line_angle( line2.angle + M_PI_2 );	float tan_phi1 = tan( angle1 );	float sin_phi2 = sin( angle2 );	float cos_phi2 = cos( angle2 );	float divisor = cos_phi2*tan_phi1 - sin_phi2;	if( is_null( divisor ) )		return false;		x_intersect = -( sin_phi2 * ( x + tan_phi1 * (y - line2.y) ) - tan_phi1 * cos_phi2 * line2.x )/divisor;	y_intersect = ( cos_phi2 * ( x + tan_phi1 * y - line2.x ) - sin_phi2 * line2.y )/divisor;	return true;}/****************************************************************************** * 归一化 * 参数:x  x坐标 *       y  y坐标 * 返回:无******************************************************************************/straight_line straight_line::normal(float x, float y) const{	return straight_line(x,y,normalize_line_angle(angle + M_PI_2));}/****************************************************************************** * 计算垂线 * 参数:px                     x坐标 *       py                     y坐标 *       x_perpendicular        垂足的x坐标 *       y_perpendicular        垂足的y坐标 * 返回:无******************************************************************************/void straight_line::construct_perpendicular(float px, float py, float &x_perpendicular, float &y_perpendicular) const{	assert( intersect( normal(px,py), x_perpendicular, y_perpendicular ) );}/****************************************************************************** * 判断点序列是否和线段相交******************************************************************************/bool line_segment::intersect( const line_segment &seg2, bool touch_is_intersect, point<float> *pi ){	point<float> A = p1;	point<float> B = p2;	point<float> C = seg2.p1;	point<float> D = seg2.p2;	float nominator1 = ( A.y - C.y ) * ( D.x - C.x ) - ( A.x - C.x ) * ( D.y - C.y );	float nominator2 = ( A.y - C.y ) * ( B.x - A.x ) - ( A.x - C.x ) * ( B.y - A.y );	float denominator = ( B.x - A.x ) * ( D.y - C.y ) - ( B.y - A.y ) * ( D.x - C.x );		if ( is_null( denominator ) )	{		if ( is_null( nominator1 ) )			return true; 	// 共线的情况		else			return false;	// 平行的情况	}	float r = nominator1 / denominator;	float s = nominator2 / denominator;	if ( pi ) // 如有必要,计算交叉点	{		pi->x = A.x + ( r * (B.x - A.x) );		pi->y = A.y + ( r * (B.y - A.y) );	}		if ( !touch_is_intersect ) // 如果起点和终点相同,则无交叉点	{		// 考虑机器精度		if ( !specify( r, 0 ) )			specify( r, 1 );			if ( !specify( s, 0 ) )			specify( s, 1 );					return ( r > 0 && r < 1 && s > 0 && s < 1 );	}	else		return ( r >= 0 && r <= 1 && s >= 0 && s <= 1 );}/****************************************************************************** * 3×3滤波器******************************************************************************/int filter( int x, int y, CharImage src, float H[3][3] ){	int Se[3][3] = { { src.get_pixel( x-1, y-1 ), src.get_pixel( x, y-1 ), src.get_pixel( x+1, y-1 ) },			 { src.get_pixel( x-1, y   ), src.get_pixel( x, y   ), src.get_pixel( x+1, y   ) },			 { src.get_pixel( x-1, y+1 ), src.get_pixel( x, y+1 ), src.get_pixel( x+1, y+1 ) } };	int k = 1, Sa = 0; 	for ( int u=0; u<3; u++ )		for ( int v=0; v<3; v++ ) 			Sa += qRound( Se[1+k-v][1+k-u] * H[v][u] );			return qRound( Sa/9.0 );}/****************************************************************************** * 3×3滤波器******************************************************************************/CharImage filter( CharImage src, float H[3][3] ){	CharImage filtered( src.width(), src.height(), 32 );	for ( int y = 0; y < src.height(); y++ )		for ( int x = 0; x < src.width(); x++ )			filtered.set_pixel( x, y, filter( x, y, src, H ) );	return filtered;}/****************************************************************************** * 3×3滤波器******************************************************************************/CharImage filter( CharImage src, float Hx[3][3], float Hy[3][3], int mode ){	// 模式含义 	// 0 = magnitude of gradient (default)		// 1 = angle of gradient (see below)	// 2 = border (b/w)	CharImage filtered( src.width(), src.height(), 32 );	for ( int y = 0; y < src.height(); y++ )		for ( int x = 0; x < src.width(); x++ )		{			int Gx = filter( x, y, src, Hx );			int Gy = -filter( x, y, src, Hy );						if ( mode == 0 || mode == 2 )				filtered.set_pixel( x, y, static_cast<int>( sqrt( Gx*Gx + Gy*Gy ) + 0.5 ) );			else			{				if ( Gx == 0 && Gy == 0 )					filtered.set_pixel( x, y, 0 );				else				{					float angle = atan2( Gy, Gx );					filtered.set_pixel( x, y, 					  static_cast<int>( normalize_angle_2pi(angle)/(2*M_PI) * 255 + 0.5 ) );				}			}		}	if ( mode == 2 )	{		filtered.set_bw_threshold( 16 );		filtered = filtered.convert_bw();	}	return filtered;}

⌨️ 快捷键说明

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