📄 segimage.h
字号:
/****************************************************************************** * 光学字符识别程序 * 文件名:segimage.h * 功能 :图像分割定义文件 * modified by PRTsinghua@hotmail.com******************************************************************************/#ifndef SEGIMAGE_H#define SEGIMAGE_H#include <iostream>#include <vector>#include <qimage.h> #include "common.h"#include "common_gfx.h"using std::ostream;class Segimage{private: enum { max_segment = 7, // 一个字符最大允许的分割数 vector_def_reserve = 10 // 对每个分段的缺省备用空间 };public: struct point; typedef list< point * > cs_sequence; typedef vector< vector< qlist< point > > > border_lists; typedef bool ( Segimage::* HandlePixelCallback)(int, int, void * ); struct cs_sequence_start { bool is_start; cs_sequence *sequence; bool get_straight_line( float &x1, float &y1, float &x2, float &y2 ); }; struct singularpoint { float x; float y; int pix_count; list< cs_sequence_start > cs_sequences; }; struct point { point( int init_x = 0, int init_y = 0 ) : x( init_x ), y( init_y ), ang( 0 ), dang( 0 ), length( -1 ), processed( false ), singular_point( NULL ), num_ending( 0 ), oang( 0 ), good_smoothed( false ) {}; void set_opposite( ringlist_iterator< point > opp ); friend inline bool operator==( const point &p1, const point &p2 ); friend inline bool operator!=( const point &p1, const point &p2 ); int x; int y; float ang; float dang; float length; // 到相反点的长度 bool processed; ringlist_iterator< point > opp; singularpoint *singular_point; int num_ending; float oang; // 原始角度 bool good_smoothed; // 平滑的效果 }; #pragma pack(1) struct pixel { bool is_border :1; bool is_filled :1; // 填充标识用来进行孤立点检测 unsigned int segment :max_segment; unsigned int processed :max_segment; // 仅当 ( is_border == true ) 时有效 list< ringlist_iterator< point > > border_points; list< point * > start_points; friend inline bool operator==( const pixel &p1, const pixel &p2 ); friend inline bool operator!=( const pixel &p1, const pixel &p2 ); }; #pragma pack() enum direction { down, right, up, left }; Segimage( int x, int y ); Segimage( const CharImage& img ); int detect_segments(); void get_border_lists( border_lists &l ); void fill_region( Segimage::point *sp ); bool take_over_segment( int x, int y, Segimage::singularpoint &sp ); void undo_take_over_segment( int x, int y ); void lineBresenham( int x0, int y0, int x1, int y1 ); void intersect_cs( Segimage::point &p ); ringlist_iterator< point > &find_opposite( const Segimage::point &p ); double avg_line_thickness(); pixel &get_pixel( int x, int y); bool set_pixel( int x, int y, int segment); void print( int mark_x, int mark_y); inline void get_bounding_box( int &x_min, int &x_max, int &y_min, int &y_max ) const { x_min = min_x; x_max = max_x; y_min = min_y; y_max = max_y; }private: struct opposite_data { bool first; int ax; int ay; int ex; int ey; }; struct intersect_data { int ax; int ay; point *p; }; void lineBresenham( int x0, int y0, int x1, int y1, HandlePixelCallback cb, void *cb_data ); void lineBresenham( int x0, int y0, float angle, HandlePixelCallback cb, void *cb_data ); bool draw_pixel( int x0, int y0, void * ) { return set_pixel( x0, y0, 9 ); }; bool find_opposite_pixel( int x0, int y0, void *cb_data ); bool intersect_pixel( int x0, int y0, void *cb_data ); void set_segment(int x, int y, unsigned int &segbits ); void fill(int x, int y, pixel &p, int segnr ); void fill_singular_region( int x, int y, Segimage::point *sp ); void set_processed( int x, int y ); bool draw_singular_pixel( int x0, int y0, void *p ); void clear(); float cs_total_length; int cs_number; int min_x, min_y, max_x, max_y; int size_x, size_y; pixel outer_pixel; vector< vector<pixel> > seg_img;};inline bool operator==( const Segimage::pixel &p1, const Segimage::pixel &p2 ){ return p1.is_border == p2.is_border && p1.segment == p2.segment && p1.processed == p2.processed;}inline bool operator!=( const Segimage::pixel &p1, const Segimage::pixel &p2 ){ return !(p1==p2);}inline bool operator==( const Segimage::point &p1, const Segimage::point &p2 ){ return p1.x == p2.x && p1.y == p2.y;}inline bool operator!=( const Segimage::point &p1, const Segimage::point &p2 ){ return !(p1==p2);}inline Segimage::direction operator++( Segimage::direction &d ){ if( d == Segimage::left ) return ( d = Segimage::down ); else return ( d = static_cast< Segimage::direction >( static_cast< int >( d ) + 1 ) );}inline Segimage::direction operator--( Segimage::direction &d ){ if( d == Segimage::down ) return ( d = Segimage::left ); else return ( d = static_cast< Segimage::direction >( static_cast< int >( d ) - 1 ) );}inline Segimage::direction leftof( Segimage::direction d ){ return ++d;}inline Segimage::pixel &Segimage::get_pixel( int x, int y ){ if( x < 0 || x >= size_x || y < 0 || y >= size_y ) return outer_pixel; else return seg_img[x][y];}inline bool Segimage::set_pixel( int x, int y, int segment ){ if( x < 0 || x >= size_x || y < 0 || y >= size_y ) return false; seg_img[x][y].is_border = false; seg_img[x][y].segment = segment; seg_img[x][y].processed = 0; return true;}inline void Segimage::set_segment( int x, int y, unsigned int &segbits ){ pixel &p = get_pixel(x,y); if( !p.is_border && p.segment > 1 ) segbits = segbits | ( 1 << ( p.segment - 2 ) );}inline ostream& operator<< ( ostream& o, Segimage::direction d ){ switch( d ) { case Segimage::down: o << "down"; break; case Segimage::right: o << "right"; break; case Segimage::up: o << "up"; break; case Segimage::left: o << "left"; break; default: o << "undefined"; } return o;}class SegWalker: public Walker{public: SegWalker( Segimage *image ) : img( image ) {} void walk_border( int start_x, int start_y, int seg, qlist<Segimage::point> *l );private: virtual bool is_border_pixel( int x, int y ) const { return img->get_pixel( x, y ).is_border; } virtual bool is_good_walker_start( int x, int y ) const; virtual void walker_process( int x, int y ); unsigned int segment; qlist<Segimage::point> *list; Segimage *img;};#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -