1、基于8临域的边界跟踪代码#include #include #define NumberOfPossiblePoints 64 #define Size_of_Array 8 void main() int fSize_of_ArraySize_of_Array= 0,0,0,0,0,0,0,0, 0,0,1,1,0,0,0,0, 0,0,1,1,0,0,0,0, 0,1,1,1,1,0,0,0, 0,0,1,1,1,1,0,0, 0,0,1,1,0,0,0,0, 0,0,0,0,0,0,0,0, 0,0,0,0,0,0,0,0; int borderSize_of_ArraySize_of_
2、Array; /也用0,1表示,border数组记录行走的轨迹; int traceNumberOfPossiblePoints2; /还需要使用一个二为维数组依次记录行走的坐标 int chaincodeNumberOfPossiblePoints;/存储方向码 int dir; int i,j; int flag; int count; int p0x,p0y;/初始点坐标 int p1x,p1y;/记录找到的第二个点的坐标 int pn_1x,pn_1y,pnx,pny;/用来记录目标坐标 / Initialization for some arrays : for (i=0;iNumb
3、erOfPossiblePoints;i+) chaincodei=0; for(j=0;j2;j+) traceij=0; /begin , lets first look at the original data and, at the same time ,clear border array: for(i=0;iSize_of_Array;i+) for(j=0;jSize_of_Array;j+) coutsetw(6)fij; borderij=0; coutendl; count=0; flag=1; dir=7; /根据算法,确定首先查找下一个边界点的方向 /find the
4、initial point (pixel) whose value is not zero. p0x=1;p0y=2; i=p0x; j=p0y; borderij=1; tracecount0=i;tracecount1=j; /repeat / 为了使循环正常进行下去,必须要求行走的步数超过1,否则由于/ 第一步找到p0, p1点后,由于这是对于最后pn-1, pn点赋值为p0和p1的坐标,循环退出。/ 在while循环条件中增加对于count的判断,当count小于2的时候,不应该结束。while (count=2) / 则:当pn-1=p0 , 同时pn=p1时结束边界跟踪/ pn_1
5、x=i; /记录倒数第二个点的i坐标 pn_1y=j; /记录倒数第二个点的j坐标 if (dir%2 =0) dir=(dir+7)%8; else dir=(dir+6)%8; switch (dir) /根据当前的方向dir确定该方向的新的坐标i,j case 0: j=j+1;break; case 1: i=i-1;j=j+1;break; case 2: i=i-1;break; case 3: i=i-1; j=j-1;break; case 4: j=j-1;break; case 5: i=i+1;j=j-1;break; case 6: i=i+1;break; case
6、7: i=i+1;j=j+1;break; /判断dir方向指向的点是否为1,如果不为1,要按逆时针方向增加方向码dir的数值; while (fij!=1) / dir=(dir+1)%8; i=pn_1x; j=pn_1y; /坐标复原,以便重新根据当前增加的方向码决定该方向的坐标i,j; switch (dir) /根据当前的方向dir确定该方向的新的坐标i,j case 0: j=j+1;break; case 1: i=i-1;j=j+1;break; case 2: i=i-1;break; case 3: i=i-1; j=j-1;break; case 4: j=j-1;bre
7、ak; case 5: i=i+1;j=j-1;break; case 6: i=i+1;break; case 7: i=i+1;j=j+1;break; if (flag=1) /这个判断只进行一次,以后由于标记flag改变,就不再需要记录了。 p1x=i; p1y=j; /pnx=i; /pny=j; flag=0; count=count+1; borderij=1; /border数组记录行走的轨迹; /还需要使用一个二为维数组依次记录行走的坐标 tracecount0=i;tracecount1=j; /当前坐标,作为while结束条件判断 pnx=i; pny=j; /存储方向码
8、 chaincodecount-1=dir; /coutp0x p0y p1x p1y pn_1x pn_1y pnx pnyendl; cout 共计count个链码endl; /画出表示边界的矩阵 cout表示边界的矩阵: endl; for(i=0;iSize_of_Array;i+) for(j=0;jSize_of_Array;j+) coutsetw(6)borderij; coutendl; /输出边界跟踪的初始点坐标位置: cout边界跟踪的初始点坐标位置:(p0x,p0y)endl; /输出表示边界的方向码: for(i=0;icount;i+) coutsetw(4)cha
9、incodecount; coutendl; /输出表示边界的坐标: cout输出表示边界的坐标endl; for(i=0;icount;i+) /没有输出最后一个点坐标 cout(tracei0,tracei1); coutendl; /*八邻域边界跟踪算法 利用点的八邻域信息,选择下一个点作为边界点,这个算法需要选择一个开始点,可以选择图像上是目标点,在最上,最左的点。然后查看它的八邻域的点,从右下方45的位置开始寻找,如果是目标点,将沿顺时针90作为下一次寻找的方向,如果不是,则逆时针45继续寻找,一旦找到重复上面的过程。*/ void VessDibTrack(HDIB hdib,ve
10、ctor& pt) /八邻域 unsigned char *lpSrc; LPSTR lpDIB = (LPSTR) :GlobalLock(HGLOBAL)hdib); int cxDIB = (int) :DIBWidth(lpDIB); / Size of DIB - x int cyDIB = (int) :DIBHeight(lpDIB); / Size of DIB - y LPSTR lpDIBBits=:FindDIBBits (lpDIB); long lLineBytes = WIDTHBYTES(cxDIB * 8); / 计算图像每行的字节数 /寻找开始点,最右,最下
11、/先行,后列 int i,j; POINT startPt,currPt; for (i = 0;icyDIB;+i) for (j = 0;jcxDIB;+j) lpSrc = (unsigned char*)lpDIBBits + lLineBytes * (cyDIB -1 - i) + j; if (*lpSrc=0) /是黑点 startPt.x = i; startPt.y = j; /停止条件 i = cyDIB; j = cxDIB; /设置方向数组 / int direction82 = -1,-1,0,-1,1,-1,1,0,1,1,0,1,-1,1,-1,0; int d
12、irection82 = -1,1,0,1,1,1,1,0,1,-1,0,-1,-1,-1,-1,0; int startDirect BOOL FindStartPoint = FALSE; BOOL FindPoint = FALSE; /开始跟踪 currPt.x = startPt.x; currPt.y = startPt.y; POINT NextPt int NextPtValue; startDirect = 0; int cnt= 0; while(!FindStartPoint&cnt=0&NextPt.x=0&NextPt.ycxDIB) FindPoint = TRUE
13、; currPt.x = NextPt.x; currPt.y = NextPt.y; if (currPt.x = startPt.x&currPt.y = startPt.y) FindStartPoint = TRUE; startDirect = startDirect-2; if(startDirect=8) startDirect = startDirect-8; cnt +; :GlobalUnlock(HGLOBAL) hdib);/于八方向链码的边界跟踪代码,其中nVerct数组存储的是边界点的矢量方向,Coordinate存储的是边界点的坐标。BOOL CDib:PickB
14、oundary(BYTE* nVerct,int (*Coordinate)2)if(NULL = m_lpBits) return FALSE;struct EdgePoint BYTE nCurrenVerct; /当前矢量,即在轮廓跟踪中的前一个搜索方向 CPoint CurrenPoint; /当前点的坐标;/CArray TraceArray;/获取位图的宽,高,以及每行字节数int nWidth=m_nWidth;int nHeight=m_nHeight;int nByteWidth=BYTE_PER_LINE(m_nWidth,m_nBitCount);/循环变量int i,j
15、;/开辟一块新的空间并初始化BYTE *pData=new BYTEnByteWidth*nHeight;memset(pData,255,nByteWidth*nHeight);/像素值unsigned char pixel;/是否找到起始点及回到起始点bool bFindStartPoint;/是否扫描到一个边界点bool bFindPoint;typedef struct int Width; int Height;Position;/起始边界点与当前边界点Position StartPoint,CurrentPoint;/八个方向和起始扫描方向,依次是左上方、上方、右上方、右方、右下方
16、、下方、左下方和左方。int Direction82= -1,1,0,1,1,1,1,0,1,-1,0,-1,-1,-1,-1,0 ;int BeginDirect;/先找到最左下方的边界点bFindStartPoint = false;for (j = 1;j nHeight-1 & !bFindStartPoint;j+) for(i = 1;i nWidth-1 & !bFindStartPoint;i+) /取得当前指针处的像素值 pixel =*(m_lpBits+nWidth*j+i); if(pixel = 0) bFindStartPoint = true; StartPoin
17、t.Height = j; StartPoint.Width = i; / 指向目标图像倒数第j行,第i个象素的指针 *(pData+nWidth*j+i) = 0; /由于起始点是在左下方,故起始扫描沿左上方向BeginDirect = 0;/跟踪边界bFindStartPoint = false;CurrentPoint.Height = StartPoint.Height;CurrentPoint.Width = StartPoint.Width;int index=0;memset(nVerct,0,9999);while(!bFindStartPoint) /从起始点一直找边界,直到
18、再次找到起始点为止 bFindPoint = false; while(!bFindPoint) /沿扫描方向,这里是左上方向获取一个像素 pixel = *(m_lpBits+nWidth*(CurrentPoint.Height + DirectionBeginDirect1)+ CurrentPoint.Width + DirectionBeginDirect0); if(pixel = 0) bFindPoint = true; /存储边界点的矢量方向 nVerctindex = (BYTE)BeginDirect; /存储边界点的坐标 Coordinateindex0 = Curre
19、ntPoint.Width; Coordinateindex1 = CurrentPoint.Height; index+; CurrentPoint.Width = CurrentPoint.Width + DirectionBeginDirect0; CurrentPoint.Height = CurrentPoint.Height + DirectionBeginDirect1; /如果一圈以后找到了起始点,那么边界寻找完成 if(CurrentPoint.Height = StartPoint.Height & CurrentPoint.Width = StartPoint.Width
20、) bFindStartPoint = true; /将轮廓在新的位图中标示出来 *(pData+nWidth*CurrentPoint.Height+CurrentPoint.Width) = 0; /扫描的方向逆时针旋转两格 /为什么?因为逆时针旋转三格的象素绝对不是边界,不然当前点就不会是边界。 BeginDirect-; if(BeginDirect = -1) BeginDirect = 7; BeginDirect-; if(BeginDirect = -1) BeginDirect = 7; else /扫描方向顺时针旋转一格 BeginDirect+; if(BeginDirect = 8) BeginDirect = 0; /边界跟踪时,边界点数m_nNumNode =index;memcpy(m_lpBits,pData,nByteWidth*nHeight);delete pData;return TRUE;
copyright@ 2008-2022 冰豆网网站版权所有
经营许可证编号:鄂ICP备2022015515号-1