You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
294 lines
9.2 KiB
C++
294 lines
9.2 KiB
C++
//////////////////////////////////////////////////////////////////////////////
|
|
//Îļþ 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;
|