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

📄 image.cpp

📁 vc++数字图像识别技术典型案例
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	#ifdef SPEED_MEASURE		struct timeval curtime;		seconds_passed( curtime );	#endif	Segimage &simage = ( *segimage );	#ifdef SPEED_MEASURE		cout << "setup Segimage ( in s ): " << seconds_passed( curtime ) << endl;	#endif			simage.get_border_lists( bl );	#ifdef SPEED_MEASURE		cout << "get_border_list() ( in s ): " << seconds_passed( curtime ) << endl;	#endif		for ( Segimage::border_lists::iterator i = bl.begin(); i != bl.end(); ++i )	{		for ( vector< qlist< Segimage::point > >::iterator n = i->begin(); n != i->end(); ++n )		{			float old_ang = 0;			ringlist_iterator< Segimage::point > m( *n );						for ( int o = n->size(); o >= 0; ++m, o-- ) // 第一个元素被访问了两次			{				Segimage::point &p = *m;				p.ang = direction( p ); // 角度逆时针测量				p.dang = calc_dang( old_ang, p.ang );				old_ang = p.ang;			}		}	}	#ifdef SPEED_MEASURE		cout << "param setup ( in s ): " << seconds_passed( curtime ) << endl;	#endif		// 在需要的地方平滑角度	for ( Segimage::border_lists::iterator i = bl.begin(); i != bl.end(); i++ )	{		for ( vector< qlist< Segimage::point > >::iterator n = i->begin(); n != i->end(); n++ )		{			int num_elems = n->size();			ringlist_iterator< Segimage::point > start( *n );					if ( need_no_smoothing( start ) )				while( num_elems-- > 0 && need_no_smoothing( start ) )					++start;			else			{				while( num_elems-- > 0 && !need_no_smoothing( start ) )					--start;				++start;			}					// 完全不必平滑			if ( need_no_smoothing( start ) )				break;			ringlist_iterator< Segimage::point > first = start;			ringlist_iterator< Segimage::point > curr = start;			num_elems = n->size();			bool collecting_smoothing_points = true;			int num_smoothing_points = 1;						while( num_elems-- > 0 )			{				if ( collecting_smoothing_points )				{					if ( need_no_smoothing( curr ) ) 					{						smooth_points( first, --curr, --num_smoothing_points );						++curr;						collecting_smoothing_points = false;					}					else						++num_smoothing_points;				}				else				{					if ( !need_no_smoothing( curr ) )					{						first = curr;						collecting_smoothing_points = true;						num_smoothing_points = 2;					}				}				++curr;			}						// 所有点需要平滑			if ( collecting_smoothing_points )				smooth_points( first, --curr, --num_smoothing_points );		}	}		#ifdef SPEED_MEASURE		cout << "smoothing ( in s ): " << seconds_passed( curtime ) << endl;	#endif		//寻找相反的点,删除相交区域	for ( Segimage::border_lists::iterator i = bl.begin(); i != bl.end(); ++i )	{		for ( vector< qlist< Segimage::point > >::iterator n = i->begin(); n != i->end(); ++n )		{			ringlist_iterator< Segimage::point > m( *n );			for ( int o = n->size(); o > 0; ++m, o-- )			{				ringlist_iterator< Segimage::point > opposite = simage.find_opposite( *m );								// 线另一侧的曲率近似相等				if ( min_angle_between( m->ang, normalize_angle_pi( opposite->ang + M_PI ), 2*M_PI ) < cs_angle_treshold &&				    m != opposite )				{					m->set_opposite( opposite );					simage.intersect_cs( *m );										if ( m->length != -1 )						opposite->num_ending++;				}			}		}	}	#ifdef SPEED_MEASURE		cout << "find opposite & del intersections ( in s ): " << seconds_passed( curtime ) << endl;	#endif		list<Segimage::singularpoint> tmp_spl;	// 通过遍历边界列表寻找交叉段序列	for ( Segimage::border_lists::iterator i = bl.begin(); i != bl.end(); ++i )	{		for ( vector< qlist< Segimage::point > >::iterator n = i->begin(); n != i->end(); ++n )		{			int num_cs = 0;			ringlist_iterator< Segimage::point > m( *n );			for ( int o = n->size(); o > 0; ++m, o-- )			{				Segimage::point &p = *m;				if ( p.length != -1 )				{					if ( !p.processed )					{						Segimage::cs_sequence t;						cssl.push_back( t );						if ( construct_sequence( m, simage, cssl.back() ) <= 2 )						{							if ( cssl.back().front() != cssl.back().back() )							{								cssl.back().front()->length = -1;								cssl.back().front()->opp->num_ending--;							}							cssl.back().back()->length = -1;							cssl.back().back()->opp->num_ending--;							cssl.pop_back();							num_cs--;						}					}					num_cs++;				}			}			// 当没有交叉段时,创建一个孤立点(特殊的处理)			if ( !num_cs )			{				Segimage::singularpoint sp;				sp.x = 0;				sp.y = 0;				sp.pix_count = 0;				qlist< Segimage::point >::iterator j = n->begin();				while( j != n->end() )				{					if ( !segimage->take_over_segment( j->x, j->y, sp ) )						break;					++j;				}								if ( j == n->end() )	// 没有孤立的交叉段				{					if ( sp.pix_count != 0 ) // 还未被其它边界列表处理					{						sp.x /= sp.pix_count;						sp.y /= sp.pix_count;						tmp_spl.push_back( sp );					}				}				else			// 需要取消set filled标识				{					do {						segimage->undo_take_over_segment( j->x, j->y );					} while( j-- != n->begin() );				}			}		}	}	#ifdef SPEED_MEASURE		cout << "find sequences ( in s ): " << seconds_passed( curtime ) << endl;	#endif		// 检测孤立区域	for ( list<Segimage::cs_sequence>::iterator i = cssl.begin(); i != cssl.end(); ++i )	{		Segimage::cs_sequence_start csss;			csss.is_start = true;		csss.sequence = &( *i );		detect_singular_region( csss, simage, spl );		if ( i->front() != i->back() )		{			csss.is_start = false;			detect_singular_region( csss, simage, spl );		}	}	#ifdef SPEED_MEASURE		cout << "detect singular regions ( in s ): " << seconds_passed( curtime ) << endl;	#endif		{		list<Segimage::singularpoint>::iterator i = spl.begin();		while( i != spl.end() )		{			if ( i->cs_sequences.empty() ) // 孤立点已经合并,不再为空				i = spl.erase( i );			else			{				// 平衡点的完全计算				if ( i->pix_count != 0 )				{					i->x = i->x / i->pix_count;					i->y = i->y / i->pix_count;				}				++i;			}		}	}	#ifdef SPEED_MEASURE		cout << "locate singular points ( in s ): " << seconds_passed( curtime ) << endl;	#endif		// 合并孤立点	if ( !tmp_spl.empty() )		spl.splice( spl.end(), tmp_spl );}// 检测孤立区域void Image::detect_singular_region( Segimage::cs_sequence_start &csss, Segimage &simage, list<Segimage::singularpoint> &spl ){	Segimage::point &start = *( csss.is_start ? csss.sequence->front() : csss.sequence->back() );		Segimage::singularpoint t;	t.x = ( start.x + start.opp->x ) / 2;	t.y = ( start.y + start.opp->y ) / 2;	t.pix_count = 0;	spl.push_back( t );		// 填充点是当前的孤立点	start.singular_point = &( spl.back() );	simage.fill_region( &start );	start.singular_point->cs_sequences.push_back( csss );}// 获取下一个边界列表void Image::next_border_list( bool next ){	if ( draw_flags & draw_abstract_char )	{		if ( next )			match_char_pos++;								else if ( match_char_pos > 0 )			match_char_pos--;				else			return;	}	else	{		if ( next )			border_list_number++;		else			border_list_number--;				border_list_number = ( border_list_number + bl.size() + 1 ) % ( bl.size() + 1 );	}	repaint();}// 标记下一个csvoid Image::mark_next_cs( bool next ){	if ( next )		mark_cs++;	else		mark_cs--;	repaint();}// 改变线的粗细void Image::change_line_thickness( bool next ){	if ( next )		pen_size++;	else	{		if ( pen_size > 1 )			pen_size--;		else			return;	}	repaint();}// 建立快照void Image::makeSnapshot(){	if ( scan.width() != 0 )	{		kapp->config()->reparseConfiguration();		kapp->config()->setGroup("Image Snapshot");		double dpi = kapp->config()->readDoubleNumEntry("dpi",300);		double cm = kapp->config()->readDoubleNumEntry("cm",5);				bool  is_height;		QString token = kapp->config()->readEntry("aspect","square");		if ( token == "square" )			is_height = scan.height() > scan.width();		else 			is_height = token == "height";		int old_pen_size = pen_size;		pen_size = kapp->config()->readNumEntry("linethickness",3);				kapp->config()->writeEntry("dpi",dpi);		kapp->config()->writeEntry("cm",cm);		kapp->config()->writeEntry("aspect",token);		kapp->config()->writeEntry("linethickness",pen_size);		kapp->config()->sync();				if ( pen_size < 1 )			pen_size = old_pen_size;		double factor = 0;		int w = 0, h = 0;		if ( draw_flags & draw_abstract_char && abstract_char != NULL )		{			w = dpi ? qRound( cm*dpi / 2.54*1.2 ) : width();			h = dpi ? qRound( cm*dpi / 2.54*1.7 ) : height();		}		else		{			factor = dpi ? get_dpi_ratio( dpi, cm, is_height ) : get_ratio();			w = qRound( scan.width()*factor + 1 );			h = qRound( scan.height()*factor + 1 );		}		QPixmap pix( w, h );		drawRecognitionState( pix, factor );		if ( pix.save( "snapshot.png", "PNG" ) )			app->slotStatusMsg( "Snapshot of image saved..." );		else		{			QApplication::beep();			app->slotStatusMsg( "Snapshot of image could not be saved..." );		}	}}// 替代字符void Image::replace_char(){	if ( abstract_char != NULL )	{		bool ok;		QString str = KLineEditDlg::getText( QString( i18n( "Character to replace all variants of:" ) ), QString( "" ), &ok, this );		if ( ok )		{			int c = character_database::char_name_to_char_code( str[0].latin1() );			char_db.clear_char_def( c );			char_db.append_char_def( *abstract_char, c );		}	}}// 添加不同的字符void Image::append_variant_char(){	if ( abstract_char != NULL )	{		bool ok;		QString str = KLineEditDlg::getText( QString( i18n( "Character to append this variant to:" ) ), QString( "" ), &ok, this );		if ( ok )		{			int c = character_database::char_name_to_char_code( str[0].latin1() );			char_db.append_char_def( *abstract_char, c );		}	}}// 画图事件void Image::paintEvent( QPaintEvent * ){	QPixmap pix( size() );	drawRecognitionState( pix, scan.width() != 0 ? get_ratio() : 0 );	bitBlt( this, 0, 0, &pix );}// 绘制识别状态void Image::drawRecognitionState( QPixmap &pix, float factor ){	int diameter = qRound( factor/4 );	if ( diameter < 3 )		diameter = 3;	if ( draw_flags & draw_abstract_char && abstract_char != NULL )	{		pix.fill( QColor( "white" ) );		QPainter painter( &pix );				int x0 = pix.width() / 2;		int y0 = 12 * pix.height() / 17;		int one = qRound( pix.width()/1.2 < pix.height()/1.7 ? pix.width()/1.2 : pix.height()/1.7 );		QPen black_pen( black, pen_size );		painter.drawLine( x0-one / 2, y0, x0+one / 2, y0 );		painter.drawLine( x0, y0, x0, y0-one );				QPen pens[2][3] = { { QPen( QColor( "grey40" ), 	pen_size ), 				      QPen( QColor( "grey50" ), 	pen_size ), 				      QPen( QColor( "grey50" ), 	pen_size, DashLine ) }, 				    { QPen( QColor( "cyan" ), 		pen_size ), 				      QPen( QColor( "aquamarine" ), 	pen_size ), 				      QPen( QColor( "aquamarine" ), 	pen_size, DashLine ) } };		int db_nr = -1;		int db_var = -1;				      		if ( match_char_pos != 0 && ( match_char_pos != 1 || char_group.size() != 0 ) )		{			if ( match_char_pos <= char_group.size() )				db_nr = char_group.get_code( match_char_pos-1 );			else				db_nr = ( match_char_pos-char_group.size()-1-( char_group.size() == 0 ) ) % character_database::total_chars;						if ( char_db.get_shape_variations( db_nr ) )

⌨️ 快捷键说明

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