////////////////////////////////////////////////////////////////////////////// //文件 ImageVector.h //主要功能: // //程序编写: 2005-12-07 ///////////////////////////////////////////////////////////////////////////// #pragma once #include "ImageTraceBase.h" namespace NImage { #define TG_FORWARD (+1) #define TG_BACKWARD (-1) typedef struct __stuLinkRecord { union{ struct{ void *m_pData; int dataType; }; char user_data[8]; }; struct __stuLinkRecord *m_pPrev; struct __stuLinkRecord *m_pNext; } CLinkRecord; typedef struct __stuLinkHead { CLinkRecord *m_pHead; CLinkRecord *m_pLast; CLinkRecord *m_pCurrent; int count; } CLinkHead; typedef enum __emLinkLoc{ TG_ERROR=-1, TG_HEAD, TG_TAIL, TG_AFTER, TG_BEFORE, TG_CURRENT } emLinkLoc; typedef enum __emListStatusCode{ LSC_SUCCESS = 0, LSC_MATCH_FOUND, LSC_MATCH_NOT_FOUND, LSC_BAD_SEARCH_DIR, LSC_BAD_START_LOC, LSC_BAD_STOP_LOC, LSC_BAD_LIST, LSC_BAD_COMPARE_FUNCTION, LSC_ITEMS_NOT_PURGED, LSC_PURGE_POLY_FAILED } emListStatusCode; class CLinkList { public: CLinkList(void); int AddListItem(CLinkHead *list, emLinkLoc loc, void *data, int dataType); CLinkHead* CreateList(void); void * DeleteListItem(CLinkHead *list, emLinkLoc del_loc, emLinkLoc ret_loc); int GetListCount(CLinkHead *list); int GetDataType(CLinkHead *list); void * GetListData(CLinkHead *list); emListStatusCode PurgeList(CLinkHead *list); void RearrangeList(CLinkHead *list, int dir); emLinkLoc SetListCurrpntr(CLinkHead *list, emLinkLoc set_loc); int AppendList(CLinkHead *ldst, CLinkHead *lsrc); int DestroyFreeList(CLinkHead *p_list); int EmptyFreeList(CLinkHead *p_list); void * SetListData(CLinkHead *list, void *data); int AddListData(CLinkHead *list, emLinkLoc loc, void *data); int GetListUserData(CLinkHead *list, void *user_data); int SetListUserData(CLinkHead *list, emLinkLoc set_loc, void *data); void * GetListUserDataAddr(CLinkHead *list); protected: void* ChangeListData(CLinkHead* list, void *prev_data, void *new_data); int ClearList(CLinkHead* p_list); CLinkHead* CreateFillList(int count, int size); emListStatusCode SearchList(CLinkHead* list, emLinkLoc start_loc, emLinkLoc stop_loc, emLinkLoc sdir, int (*cmp) (void *, void *), void *cmp_data); void* SeekDelete(CLinkHead* list, void *data); int SetListDataType(CLinkHead* list, int dataType); }; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////////// typedef POSITION (*FUN_AddImageCurve) (CCurve *curve); class CFlushPoly { public: CFlushPoly(void); virtual ~CFlushPoly(void); void update_min_max_pnt(CPoint *p_imgp, CPoint *p_min_imgp, CPoint *p_max_imgp); double img_points_dist(CPoint *p_imgp0, CPoint *p_imgp1); int flush_polyline(CLinkHead *p_polyline_list, double min_polyline_lenght); int opt_flush_polyline(CLinkHead *p_polyline_list, double pnt_error_tolerance, double min_polyline_lenght); CPoint2D m_pointOrg; CSize8 m_scale; CScreenXY* m_pSxy; FUN_AddImageCurve m_pFunAddCurve; }; //////////////////////////////////////////////////////////////////////////////////////////////////////////////////// #define HORIZONTAL_LINE 0 #define VERTICAL_LINE 1 #define read_bit(m,n) (((((BYTE *)(m))[(n) >> 3]) & (1 << (7-((n) & 7)))) ? 1:0) #define read_bit2(fp,m,n) (((((BYTE *)(m))[(n) >> 3]) & (1 << (7-((n) & 7)))) ? (fp):(1-(fp))) #define set_bit(m,n) ((BYTE *)(m))[(n) >> 3] |= (1 << (7-((n) & 7))) #define clear_bit(m,n) ((BYTE *)(m))[(n) >> 3] &= (~(1 << (7-((n) & 7)))) #define clear_pixel(m,n,b) \ { \ if((b)!=0) \ set_bit(m,n); \ else \ clear_bit(m,n); \ } #define get_line_size(x) ((((x)+31)/32)*4) #define get_raw_img_line(p,lsz,nl) ((BYTE*)GetPixelAddress(0, nl)) #define same_point(p0,p1) (((p0)->x==(p1)->x) && ((p0)->y==(p1)->y)) #define line_type(p0,p1) (((p0)->x==(p1)->x)?VERTICAL_LINE:HORIZONTAL_LINE) #define pnt_distance_2(p0,p1) ((((p0)->x-(p1)->x)*((p0)->x-(p1)->x))+ \ (((p0)->y-(p1)->y)*((p0)->y-(p1)->y))) typedef struct __PolylineRecord{ CLinkHead *p_poly_list; CPoint prev_pnt0; CPoint last_pnt0; CPoint pnt0; CPoint prev_pnt1; CPoint last_pnt1; CPoint pnt1; } polyline; typedef struct ins_polyline_record { int insert_location; CPoint link_pnt; CPoint pnt; polyline *p_polyline; } ins_polyline; typedef struct scan_data_record { int current_line; BYTE *p_raw_ptr; BYTE *p_lines; BYTE *p_line; BYTE *p_next_line; BYTE *p_nnext_line; BYTE *v_open; CLinkHead *p_polylines_list; CLinkHead **pp_gating_polylines; int number_of_polylines; } scan_data; typedef struct vect_poly_record { CLinkHead *p_poly_list; CPoint prev_pnt; CPoint last_pnt; CPoint pnt; } vect_poly; typedef struct __stuScanError { int back_ground; double pnt_error_tolerance; //容许量 double min_polyline_lenght; } SCAN_ERROR; //for tree typedef struct node_record { int red; void *data; void *key; struct node_record *l; struct node_record *r; } NodeRecord; typedef struct tree_record { int (*compare_keys) (void *, void *); int sizeof_key; void *init_key; NodeRecord *head; NodeRecord *z; NodeRecord *x; NodeRecord *g; NodeRecord *p; NodeRecord *gg; } TreeRecord; typedef void *HTREE; class CHTree { public: CHTree(void); HTREE tree_create(int sizeof_key,void *init_key, int (*compare_keys)(void *,void *)); int tree_insert(HTREE htree,void *key,void *data); void * tree_search(HTREE htree,void *key); int tree_search_multi(HTREE htree,void *key, int (*search_callback)(void *,void *), void *p_param); int tree_free(HTREE htree); int tree_empty(HTREE htree); void * tree_delete(HTREE htree,void *key); void * tree_delete_from_data(HTREE htree,void *key,void *data); NodeRecord* alloc_node(TreeRecord * p_tree, void *key, int red, void *data, NodeRecord * l, NodeRecord * r); int tree_search_equals(TreeRecord* p_tree, void *key, NodeRecord* x, int (*search_callback) (void *, void *), void *p_param); static void free_node(NodeRecord * p_node, int free_data); static void tree_empty_ll(TreeRecord* p_tree, NodeRecord* x); static NodeRecord *rotate(TreeRecord* p_tree, void *key, NodeRecord* y); static int tree_cmp_keys(TreeRecord* p_tree, void *key1, void *key2); static int split(TreeRecord* p_tree, void *key); static void tree_free_ll(TreeRecord * p_tree, NodeRecord * x); }; //图像全自动矢量化 class CImageVector : public CImageTraceBase { public: CImageVector(void); virtual ~CImageVector(void); int CenterLineConvert(double pnt_error_tolerance, double min_polyline_lenght); //输出中心线 int DoubleLineConvert(double pnt_error_tolerance, double min_polyline_lenght); //输出轮廓线(双线) CFlushPoly m_flush; SCAN_ERROR m_error; protected: int BmpFileGetBackground(int x_samples, int y_samples); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// protected://输出中心线 CLinkHead* CL_GetNodePoints(void); HTREE CL_GetPointsTree(CLinkHead * p_pnts_list); int CL_ThinImage(void); int CL_DoThinning(BYTE * p_prev_mod_line, BYTE * p_curr_mod_line); int CL_DoStep(BYTE * p_prev_mod_line, BYTE * p_curr_mod_line, int (*step_check_func) (BYTE *)); int CL_DoVectorize(HTREE node_pnts_htree, CLinkHead * p_node_pnts_list); int CL_FindStartPoint(int yy_start, CPoint * p_imgp); void CL_GetNextPoint(CPoint * p_start_imgp, int direction, CPoint * p_imgp); int CL_TracePoint( int curr_direction, HTREE node_pnts_htree, vect_poly * p_vect_poly, CPoint * p_imgp, int *p_poly_flushed_flag ); vect_poly* CL_CreateVectPoly(CPoint * p_imgp); void CL_FreeVectPoly(vect_poly * p_vect_poly); int CL_AddVectPolyPoint(vect_poly * p_vect_poly, CPoint * p_imgp); int CL_GetImagePixel(int back_ground, int xx, int yy); void CL_ClearImagePixel(int back_ground, int xx, int yy); CHTree m_tree; ////////////////////////////////////////////////////////////////////////////////////////////////////////////////// protected://输出轮廓线(双线) int DL_NextLine(scan_data * p_scd); int DL_ScanCurrentLine(scan_data * p_scd); int DL_CreateNewPolyline(scan_data * p_scd, CPoint* p_img_pnt0, CPoint* p_img_pnt1); int DL_RemovePolyline(scan_data * p_scd, polyline * p_polyline); int DL_FlushAllPolylines(scan_data * p_scd); int DL_ResyncPolylineLists(scan_data * p_scd); int DL_AddLine(scan_data* p_scd, CPoint* p_img_pnt0, CPoint* p_img_pnt1); int DL_AddPointInPoly(polyline * p_ins_polyline, CPoint * p_imgp, int insert_location); int DL_AddPolyGate(scan_data * p_scd, int gate, polyline * p_polyline); int DL_RemovePolyGate(scan_data * p_scd, int gate, polyline * p_polyline); int DL_TryToJoinPolylines(scan_data * p_scd, polyline * p_owner_polyline, CPoint * p_join_pnt, int pnt_location); int DL_TransferPolylinePoints(polyline * p_dest_polyline, polyline * p_src_polyline, int insert_location, int direction); int DL_GetInsertInfo(scan_data * p_scd, CPoint * p_img_pnt0, CPoint * p_img_pnt1, ins_polyline * p_iply); int DL_GetInsertLink( CLinkHead* p_gating_poly_list, CPoint* p_img_pnt0, CPoint* p_img_pnt1, ins_polyline * p_iply); }; }; extern CLinkList m_link;