1、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;Size_of_Array; coutsetw(6)fij; borderij=0; endl; count=0; flag=1; dir=7; /根据算法,确定首先查找下一个边界点的方向 /find the initial point (pixel) whose value is not zero. p0x=1;p
2、0y=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_1x=i; /记录倒数第二个点的i坐标 pn_1y=j; /记录倒数第二个点的j坐标 if (dir%2 =0) d
3、ir=(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; case 2: case 3: j=j-1; case 4: j=j-1; case 5: i=i+1;j=j-1; case 6: case 7: /判断dir方向指向的点是否为1,如果不为1,要按逆时针方向增加方向码dir的数值; while (fij!=1) / dir=(dir+1)%8; i=pn_1x; j=pn_1y; /坐标复原,以便重新根据当前增加的方
4、向码决定该方向的坐标i,j; if (flag=1) /这个判断只进行一次,以后由于标记flag改变,就不再需要记录了。 p1x=i; p1y=j; /pnx=i; /pny=j; flag=0; count=count+1;borderij=1; /border数组记录行走的轨迹; /还需要使用一个二为维数组依次记录行走的坐标/当前坐标,作为while结束条件判断pnx=i; pny=j; /存储方向码chaincodecount-1=dir; /coutp0x p0yp1xp1ypn_1xpn_1ypnxpny 共计count个链码 /画出表示边界的矩阵表示边界的矩阵:for(i=0;bo
5、rderij;/输出边界跟踪的初始点坐标位置:cout边界跟踪的初始点坐标位置:(,)/输出表示边界的方向码:count;setw(4)chaincodecount;/输出表示边界的坐标:输出表示边界的坐标i+) /没有输出最后一个点坐标tracei0tracei1;/*八邻域边界跟踪算法利用点的八邻域信息,选择下一个点作为边界点,这个算法需要选择一个开始点,可以选择图像上是目标点,在最上,最左的点。然后查看它的八邻域的点,从右下方45的位置开始寻找,如果是目标点,将沿顺时针90作为下一次寻找的方向,如果不是,则逆时针继续寻找,一旦找到重复上面的过程。*/void VessDibTrack(H
6、DIB hdib,vector& 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); / 计算图像每行的字节数/寻找开始点,
7、最右,最下/先行,后列POINT startPt,currPt;for (i = 0;cyDIB;+i) for (j = 0;cxDIB;+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 direction82
8、= -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.xNextPt.ycxDIB) FindPoint = TRUE; currPt.x = NextPt.x;
9、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:PickBoundary(BYTE* nVerct,int
10、(*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);/循环变量/开辟一块新的空间并初始化BYTE *pData=new BYT
11、EnByteWidth*nHeight;memset(pData,255,nByteWidth*nHeight);/像素值unsigned char pixel;/是否找到起始点及回到起始点bool bFindStartPoint;/是否扫描到一个边界点bool bFindPoint;typedef struct int Width; int Height;Position;/起始边界点与当前边界点Position StartPoint,CurrentPoint;/八个方向和起始扫描方向,依次是左上方、上方、右上方、右方、右下方、下方、左下方和左方。int Direction82= -1,1,
12、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 &i+) /取得当前指针处的像素值 pixel =*(m_lpBits+nWidth*j+i); if(pixel = 0) bFindStartPoint = true; StartPoint.Height = j; StartPoint.Width = i; / 指向目标图像倒数第j行,第
13、i个象素的指针 *(pData+nWidth*j+i) = 0; /由于起始点是在左下方,故起始扫描沿左上方向BeginDirect = 0;/跟踪边界CurrentPoint.Height = StartPoint.Height;CurrentPoint.Width = StartPoint.Width;int index=0;memset(nVerct,0,9999);bFindStartPoint) /从起始点一直找边界,直到再次找到起始点为止 bFindPoint = false;bFindPoint) /沿扫描方向,这里是左上方向获取一个像素 pixel = *(m_lpBits+n
14、Width*(CurrentPoint.Height + DirectionBeginDirect1)+ CurrentPoint.Width + DirectionBeginDirect0); bFindPoint = true; /存储边界点的矢量方向 nVerctindex = (BYTE)BeginDirect; /存储边界点的坐标 Coordinateindex0 = CurrentPoint.Width; Coordinateindex1 = CurrentPoint.Height; index+; CurrentPoint.Width = CurrentPoint.Width +
15、 DirectionBeginDirect0; CurrentPoint.Height = CurrentPoint.Height + DirectionBeginDirect1; /如果一圈以后找到了起始点,那么边界寻找完成 if(CurrentPoint.Height = StartPoint.Height & CurrentPoint.Width = StartPoint.Width) /将轮廓在新的位图中标示出来 *(pData+nWidth*CurrentPoint.Height+CurrentPoint.Width) = 0; /扫描的方向逆时针旋转两格 /为什么?因为逆时针旋转三格的象素绝对不是边界,不然当前点就不会是边界。 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