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

📄 common_gfx.cpp

📁 《Visual C++数字图像识别技术典型案例》之光学字符识别技术源码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
/****************************************************************************** * 光学字符识别程序 * 文件名:common_gfx.cpp * 功能  :共用文件实现 * modified by PRTsinghua@hotmail.com******************************************************************************/#include <iostream>#include <qpainter.h>#include <qapplication.h>#include "common_gfx.h"using std::max;using std::cout;using std::endl;/****************************************************************************** * 判断是否边界点 * 参数:x  x坐标 *       y  y坐标 * 返回:返回bool值******************************************************************************/bool AbstractImage::is_border_pixel( int x, int y ) const{	return	!is_background( x, y ) &&		( is_background( x-1, y ) || is_background( x+1, y ) ||		  is_background( x, y-1 ) || is_background( x, y+1 ) ) ;}/****************************************************************************** * 判断是否邻接点 * 参数:x  x坐标 *       y  y坐标 * 返回:返回bool值******************************************************************************/bool AbstractImage::is_near_pixel( int x, int y ) const{	if ( !is_background( x,   y-1 ) ||	     !is_background( x-1, y   ) ||	     !is_background( x+1, y   ) ||	     !is_background( x,   y+1 ) )		return true;	return false;}/****************************************************************************** * 二值化 * 参数:auto_threshold  是否自动检测阈值 * 返回:无******************************************************************************/CharImage CharImage::convert_bw( bool auto_threshold ) const{	int threshold = -1;		if ( auto_threshold ) 		threshold = Histogram( *this ).get_bw_threshold();	CharImage img( width(), height(), 32 );	img.clear();		for( int y = 0; y < height(); y++ )		for( int x = 0; x < width(); x++ )			if ( !is_background( x, y, threshold ) )				img.set_pixel( x, y, black );				return img;}/****************************************************************************** * 构造函数******************************************************************************/Histogram::Histogram( QWidget *parent, const char *name ) : 	QDialog( parent, name ), 	parent( parent ){ 	setCaption("histogram"); 	clear(); }/****************************************************************************** * 构造函数******************************************************************************/Histogram::Histogram( const QImage &img, QWidget *parent, const char *name ) : 	QDialog( parent, name ), 	parent( parent ){ 	setCaption("histogram"); 	load( img );}/****************************************************************************** * 清空直方图******************************************************************************/void Histogram::clear(){	frequency = vector<int>( 256, 0 );	log_frequency = vector<float>( 256, 0 );	pix_count = 0;	min_value = max_value = mean_value = 0;	most_value = least_value = 0;	std_deviation = 0;	entropy = 0;	white_maximum = black_maximum = 0;	bw_threshold = 127;	draw_flags = 0;}/****************************************************************************** * 加载图像******************************************************************************/void Histogram::load( const QImage &img ){	clear();	pix_count = img.width()*img.height();		min_value = INT_MAX;		// 计算灰度值的频率	for( int y = 0; y < img.height(); y++ )		for( int x = 0; x < img.width(); x++ )		{				int value = qGray( img.pixel( x, y ) ); 			min_value = min( min_value, value );			max_value = max( max_value, value );			mean_value += value;						frequency[ value ]++;		}	if ( img.height()*img.width() > 0 )		mean_value = mean_value / pix_count;	// 计算标准分割值	unsigned long dev_count = 0;	for( int y = 0; y < img.height(); y++ )		for( int x = 0; x < img.width(); x++ )		{				int value = qGray( img.pixel( x, y ) );			dev_count += ( value - mean_value ) * ( value - mean_value );		}	if ( img.height()*img.width() > 1 )		std_deviation = qRound( sqrt( dev_count / ( pix_count - 1 ) ) );	int most = 0, least = INT_MAX;		// 寻找最频繁和最少出现的灰度值	for( int value = min_value; value <= max_value; value++ )	{		if ( frequency[ value ] > most )		{			most = frequency[ value ];			most_value = value;		}				if ( frequency[ value ] < least )		{			least = frequency[ value ];			least_value = value;		}				if ( frequency[ value ] != 0 )		{			log_frequency[ value ] = log( frequency[ value ] );			float relative_frequency = frequency[ value ] / static_cast<float>( pix_count );			entropy += relative_frequency * log( relative_frequency ) / log( 2 );		}	}	entropy = - entropy;			// 寻找局部最大的白色值	for( int value = min_value; value <= ( min_value + max_value ) / 2; value++ )		if ( frequency[ value ] != 0 && log_frequency[ white_maximum ] < log_frequency[ value ] )			white_maximum = value;		// 寻找局部最大的黑色值	for( int value = ( min_value + max_value ) / 2; value <= max_value; value++ )		if ( frequency[ value ] != 0 && log_frequency[ black_maximum ] < log_frequency[ value ] )			// 避免假值			if ( log_frequency[ value-1 ] != 0 )				black_maximum = value;			// 寻找最大值之间的最小值	bw_threshold = min( white_maximum, black_maximum );	int second_threshold = 0;	for( int value = white_maximum+1; value <  black_maximum; value++ )	{		if ( frequency[ value ] > 0 && log_frequency[ bw_threshold ] > log_frequency[ value ] )		{			bw_threshold = value;			second_threshold = 0;		}		else if ( log_frequency[ bw_threshold ] == log_frequency[ value ] )		{			second_threshold = value;		}	}			if ( second_threshold != 0 )		bw_threshold = ( bw_threshold + second_threshold ) / 2;		else if( bw_threshold == min( white_maximum, black_maximum ) )	{		if ( white_maximum != black_maximum ) 				bw_threshold = ( white_maximum + black_maximum ) / 2;		else			bw_threshold = 127;		}		repaint();}/****************************************************************************** * 保存******************************************************************************/void Histogram::save(){	QPixmap pixmap( size().width(), size().height() );	drawHistogram( pixmap );	if ( !pixmap.save( "./histogram.png", "PNG" ) )		QApplication::beep();}/****************************************************************************** * 打印图像信息******************************************************************************/void Histogram::print(){	cout << "pixel count: 		" << pix_count << endl;	cout << "minimum gray value:	" << min_value << endl;	cout << "maximum gray value: 	" << max_value << endl;	cout << "mean gray value: 	" << mean_value << endl;	cout << "standard deviation: 	" << std_deviation << endl;	cout << "entropy: 		" << entropy<< endl;	cout << "white minimum in histogram: 	" << white_maximum << endl;	cout << "black minimum in histogram: 	" << black_maximum << endl;	cout << "b/w threshold:			" << bw_threshold << endl;}void Histogram::paintEvent( QPaintEvent * ){	QPixmap pixmap( size().width(), size().height() );	drawHistogram( pixmap );		// 画图	bitBlt( this, 0, 0, &pixmap );}/****************************************************************************** * 画直方图******************************************************************************/void Histogram::drawHistogram( QPixmap &pixmap ){	float x_scale = static_cast<float>( pixmap.width() ) / frequency.size();	float y_scale = static_cast<float>( pixmap.height() ) / log_frequency[ most_value ];		// 画背景	pixmap.fill( "white" );		QPainter painter( &pixmap );	painter.setPen( QPen( "black", static_cast<int>( ceil( x_scale ) ) ) );		for( int value = min_value; value <= max_value; value++ )	{		painter.moveTo( qRound( value * x_scale ), size().height() );		painter.lineTo( qRound( value * x_scale ), 			qRound( ( log_frequency[ most_value ] - log_frequency[ value ] ) * y_scale ) );		if ( draw_flags != 0 )		{			painter.save();			int x_position = qRound( value * x_scale );			if ( qRound( ( log_frequency[ most_value ] - log_frequency[ value ] ) * y_scale ) <= 0 )				painter.moveTo( qRound( value * x_scale ), size().height() );			// 画标注信息			if ( value == white_maximum && ( draw_flags & draw_max_white ) )			{				painter.setPen( QPen( "blue", static_cast<int>( ceil( x_scale ) ) ) );				painter.lineTo( x_position, 0 );							}			else if ( value == black_maximum && ( draw_flags & draw_max_black ) )			{				painter.setPen( QPen( "blue", static_cast<int>( ceil( x_scale ) ) ) );				painter.lineTo( x_position, 0 );			}			else if ( value == bw_threshold && ( draw_flags & draw_threshold ) )			{				painter.setPen( QPen( "red", static_cast<int>( ceil( x_scale ) ) ) );				painter.lineTo( x_position, 0 );			}			else if ( value == 127 && ( draw_flags & draw_middle ) )			{				painter.setPen( QPen( "cyan", static_cast<int>( ceil( x_scale ) ) ) );				painter.lineTo( x_position, 0 );			}			else if ( value == mean_value && ( draw_flags & draw_mean_value ) )			{				painter.setPen( QPen( "green", static_cast<int>( ceil( x_scale ) ) ) );				painter.lineTo( x_position, 0 );			}					painter.restore();

⌨️ 快捷键说明

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