基于8临域的边界跟踪代码.docx

上传人:b****5 文档编号:4643030 上传时间:2022-12-07 格式:DOCX 页数:13 大小:18.58KB
下载 相关 举报
基于8临域的边界跟踪代码.docx_第1页
第1页 / 共13页
基于8临域的边界跟踪代码.docx_第2页
第2页 / 共13页
基于8临域的边界跟踪代码.docx_第3页
第3页 / 共13页
基于8临域的边界跟踪代码.docx_第4页
第4页 / 共13页
基于8临域的边界跟踪代码.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

基于8临域的边界跟踪代码.docx

《基于8临域的边界跟踪代码.docx》由会员分享,可在线阅读,更多相关《基于8临域的边界跟踪代码.docx(13页珍藏版)》请在冰豆网上搜索。

基于8临域的边界跟踪代码.docx

基于8临域的边界跟踪代码

#include

#include

#defineNumberOfPossiblePoints64

#defineSize_of_Array8

voidmain()

{

intf[Size_of_Array][Size_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};

intborder[Size_of_Array][Size_of_Array];//也用0,1表示,border数组记录行走的轨迹;

int

trace[NumberOfPossiblePoints][2];

//还需要使用一个二为维数组依次记录行走的坐标

intchaincode[NumberOfPossiblePoints];//存储方向码

intdir;

inti,j;

intflag;

intcount;

intp0x,p0y;//初始点坐标

intp1x,p1y;//记录找到的第二个点的坐标

intpn_1x,pn_1y,pnx,pny;//用来记录目标坐标

//Initializationforsomearrays:

for(i=0;i

{

chaincode[i]=0;

for(j=0;j<2;j++)

trace[i][j]=0;

}

//begin,let'sfirstlookattheoriginaldataand,atthesametime,clearborderarray:

for(i=0;i

{

for(j=0;j

{

cout<

border[i][j]=0;

}

cout<

}

count=0;

flag=1;

dir=7;//根据算法,确定首先查找下一个边界点的方向

//findtheinitialpoint(pixel)whosevalueisnotzero.

p0x=1;p0y=2;

i=p0x;

j=p0y;

border[i][j]=1;

trace[count][0]=i;trace[count][1]=j;

//repeat

//为了使循环正常进行下去,必须要求行走的步数超过1,否则由于

//第一步找到p0,p1点后,由于这是对于最后pn-1,pn点赋值为p0和p1的坐标,循环退出。

//在while循环条件中增加对于count的判断,当count小于2的时候,不应该结束。

while

(count<2||(pn_1x!

=p0x)||(pn_1y!

=p0y)||(pnx!

=p1x)||(pny!

=p1y))

{

//记录行走的坐标,进行do-while循环的结束条件判断使用

//如果记录的边界点为:

p0,p1,....pn-1,pn(假如有n+1个边界点,p0为初始点,n>=2)

//则:

当pn-1==p0,同时pn==p1时结束边界跟踪

//

pn_1x=i;//记录倒数第二个点的i坐标

pn_1y=j;//记录倒数第二个点的j坐标

if(dir%2==0)

dir=(dir+7)%8;

else

dir=(dir+6)%8;

switch(dir)//根据当前的方向dir确定该方向的新的坐标i,j

{

case0:

{j=j+1;break;}

case1:

{i=i-1;j=j+1;break;}

case2:

{i=i-1;break;}

case3:

{i=i-1;j=j-1;break;}

case4:

{j=j-1;break;}

case5:

{i=i+1;j=j-1;break;}

case6:

{i=i+1;break;}

case7:

{i=i+1;j=j+1;break;}

}

//判断dir方向指向的点是否为1,如果不为1,要按逆时针方向增加方向码dir的数值;

while(f[i][j]!

=1)

{

//

dir=(dir+1)%8;

i=pn_1x;

j=pn_1y;//坐标复原,以便重新根据当前增加的方向码决定该方向的坐标i,j;

switch(dir)//根据当前的方向dir确定该方向的新的坐标i,j

{

case0:

{j=j+1;break;}

case1:

{i=i-1;j=j+1;break;}

case2:

{i=i-1;break;}

case3:

{i=i-1;j=j-1;break;}

case4:

{j=j-1;break;}

case5:

{i=i+1;j=j-1;break;}

case6:

{i=i+1;break;}

case7:

{i=i+1;j=j+1;break;}

}

}

if(flag==1)//这个判断只进行一次,以后由于标记flag改变,就不再需要记录了。

{

p1x=i;

p1y=j;

//pnx=i;

//pny=j;

flag=0;

}

count=count+1;

border[i][j]=1;//border数组记录行走的轨迹;

//还需要使用一个二为维数组依次记录行走的坐标

trace[count][0]=i;trace[count][1]=j;

//当前坐标,作为while结束条件判断

pnx=i;

pny=j;

//存储方向码

chaincode[count-1]=dir;

//cout<

"<

}

cout<<"共计"<

//画出表示边界的矩阵

cout<<"表示边界的矩阵:

"<

for(i=0;i

{

for(j=0;j

cout<

cout<

}

//输出边界跟踪的初始点坐标位置:

cout<<"边界跟踪的初始点坐标位置:

("<

//输出表示边界的方向码:

for(i=0;i

cout<

cout<

//输出表示边界的坐标:

cout<<"输出表示边界的坐标"<

for(i=0;i

cout<<"("<

cout<

}

/*八邻域边界跟踪算法

利用点的八邻域信息,

选择下一个点作为边界点,

这个算法需要选择一个开始点,

可以选择图像上是目标点,在最上,最左的点。

然后查看它的八邻域的点,从右

下方

45°的位置开始寻找,如果是目标点,将沿顺时针

90°作为下一次寻找的

方向,如果不是,则逆时针

45°继续寻找,一旦找到重复上面的过程。

*/

voidVessDibTrack(HDIBhdib,vector&pt)//八邻域

{

unsignedchar*lpSrc;

LPSTRlpDIB=(LPSTR):

:

GlobalLock((HGLOBAL)hdib);

intcxDIB=(int):

:

DIBWidth(lpDIB);//SizeofDIB-x

intcyDIB=(int):

:

DIBHeight(lpDIB);//SizeofDIB-y

LPSTRlpDIBBits=:

:

FindDIBBits(lpDIB);

longlLineBytes=WIDTHBYTES(cxDIB*8);//计算图像每行的字节数

//寻找开始点,最右,最下

//先行,后列

inti,j;

POINTstartPt,currPt;

for(i=0;i

{

for(j=0;j

{

lpSrc=(unsignedchar*)lpDIBBits+

lLineBytes*(cyDIB-1-i)+j;

if(*lpSrc==0)//是黑点

{

startPt.x=i;

startPt.y=j;

//停止条件

i=cyDIB;

j=cxDIB;

}

}

}

//设置方向数组

//intdirection[8][2]={{-1,-1},{0,-1},{1,-1},{1,0},{1,1},{0,1},{-1,1},{-1,0}};

intdirection[8][2]={{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0}};

intstartDirect

BOOLFindStartPoint=FALSE;

BOOLFindPoint=FALSE;

//开始跟踪

currPt.x=startPt.x;

currPt.y=startPt.y;

POINTNextPt

intNextPtValue;

startDirect=0;

intcnt=0;

while(!

FindStartPoint&&cnt<100000)

{

FindPoint=FALSE;

pt.push_back(currPt);

while(!

FindPoint)

{

//沿预定方向扫描,寻找下一个点

NextPt.x=currPt.x+direction[startDirect][1];

NextPt.y=currPt.y+direction[startDirect][0];

lpSrc=(unsignedchar*)lpDIBBits+lLineBytes*(cyDIB-1-NextPt.x)+NextPt.y;

//NextPtValue=GetPiexValue(hdib,NextPt.x,NextPt.y);

NextPtValue=*lpSrc;

if(NextPtValue==0&&NextPt.x>=0&&NextPt.x=0&&NextPt.y

{

FindPoint=TRUE;

currPt.x=NextPt.x;

currPt.y=NextPt.y;

if(currPt.x==startPt.x&&currPt.y==startPt.y)

{

FindStartPoint=TRUE;

}

startDirect=startDirect-2;

if(startDirect<0)startDirect=startDirect+8;

}

else

{

startDirect=startDirect+1;

if(startDirect>=8)startDirect=startDirect-8;

}

}

cnt++;

}

:

:

GlobalUnlock((HGLOBAL)hdib);

}

//于八方向链码的边界跟踪代码,其中nVerct数组存储的是边界点的矢量方向,Coordinate存储的是边界点的坐标。

BOOLCDib:

:

PickBoundary(BYTE*nVerct,int(*Coordinate)[2])

{

if(NULL==m_lpBits)

returnFALSE;

structEdgePoint

{

BYTEnCurrenVerct;//当前矢量,即在轮廓跟踪中的前一个搜索方向

CPointCurrenPoint;//当前点的坐标

};

//CArrayTraceArray;

//获取位图的宽,高,以及每行字节数

intnWidth=m_nWidth;

intnHeight=m_nHeight;

intnByteWidth=BYTE_PER_LINE(m_nWidth,m_nBitCount);

//循环变量

inti,j;

//开辟一块新的空间并初始化

BYTE*pData=newBYTE[nByteWidth*nHeight];

memset(pData,255,nByteWidth*nHeight);

//像素值

unsignedcharpixel;

//是否找到起始点及回到起始点

boolbFindStartPoint;

//是否扫描到一个边界点

boolbFindPoint;

typedefstruct

{

intWidth;

intHeight;

}Position;

//起始边界点与当前边界点

PositionStartPoint,CurrentPoint;

//八个方向和起始扫描方向,依次是左上方、上方、右上方、右方、右下方、下方、左下方和左方。

intDirection[8][2]={{-1,1},{0,1},{1,1},{1,0},{1,-1},{0,-1},{-1,-1},{-1,0}};

intBeginDirect;

//先找到最左下方的边界点

bFindStartPoint=false;

for(j=1;j

bFindStartPoint;j++)

{

for(i=1;i

bFindStartPoint;i++)

{

//取得当前指针处的像素值

pixel=*(m_lpBits+nWidth*j+i);

if(pixel==0)

{

bFindStartPoint=true;

StartPoint.Height=j;

StartPoint.Width=i;

//指向目标图像倒数第j行,第i个象素的指针

*(pData+nWidth*j+i)=0;

}

}

}

//由于起始点是在左下方,故起始扫描沿左上方向

BeginDirect=0;

//跟踪边界

bFindStartPoint=false;

CurrentPoint.Height=StartPoint.Height;

CurrentPoint.Width=StartPoint.Width;

intindex=0;

memset(nVerct,0,9999);

while(!

bFindStartPoint)

{

//从起始点一直找边界,直到再次找到起始点为止

bFindPoint=false;

while(!

bFindPoint)

{

//沿扫描方向,这里是左上方向获取一个像素

pixel=*(m_lpBits+nWidth*(CurrentPoint.Height+Direction[BeginDirect][1])+

CurrentPoint.Width+Direction[BeginDirect][0]);

if(pixel==0)

{

bFindPoint=true;

//存储边界点的矢量方向

nVerct[index]=(BYTE)BeginDirect;

//存储边界点的坐标

Coordinate[index][0]=CurrentPoint.Width;

Coordinate[index][1]=CurrentPoint.Height;

index++;

CurrentPoint.Width=CurrentPoint.Width+Direction[BeginDirect][0];

CurrentPoint.Height=CurrentPoint.Height+Direction[BeginDirect][1];

//如果一圈以后找到了起始点,那么边界寻找完成

if(CurrentPoint.Height==StartPoint.Height&&

CurrentPoint.Width==StartPoint.Width)

{

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);

deletepData;

returnTRUE;

}

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 高中教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1