📄 image.cpp
字号:
#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 + -