📄 于八方向链码的边界跟踪代码.txt
字号:
于八方向链码的边界跟踪代码,其中nVerct数组存储的是边界点的矢量方向,Coordinate存储的是边界点的坐标。
//函数 OnProcessTrace()
void CSkagonView::OnProcessTrace()
{
if(DibObject.pDib==NULL)
{
MessageBox("请先载入一幅位图","Error",MB_ICONERROR | MB_OK);
return;
}
if(DibObject.GetNumberOfColors() != 256)
{
MessageBox("您处理的图片不是256色图","Error",MB_ICONERROR | MB_OK);
return;
}
struct EdgePoint
{
BYTE nCurrenVerct; //当前矢量,即在轮廓跟踪中的前一个搜索方向
CPoint CurrenPoint; //当前点的坐标
};
//CArray <EdgePoint,EdgePoint&> TraceArray;
//获取位图的宽,高,以及每行字节数
int nWidth=DibObject.GetWidth();
int nByteWidth=DibObject.GetByteWidth();
int nHeight=DibObject.GetHeight();
//循环变量
int i,j;
//开辟一块新的空间
BYTE *pData=new BYTE[nByteWidth*nHeight];
memset(pData,255,nByteWidth*nHeight);
//像素值
unsigned char pixel;
//是否找到起始点及回到起始点
bool bFindStartPoint;
//是否扫描到一个边界点
bool bFindPoint;
typedef struct
{
int Width;
int Height;
}Position;
//起始边界点与当前边界点
Position StartPoint,CurrentPoint;
//八个方向和起始扫描方向,依次是左上方、上方、右上方、右方、右下方、下方、左下方和左方。
int Direction[8][2]={ {-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 = PointOld(i,j);
if(pixel == 0)
{
bFindStartPoint = true;
StartPoint.Height = j;
StartPoint.Width = i;
// 指向目标图像倒数第j行,第i个象素的指针
Point(i,j) = 0;
}
}
}
//由于起始点是在左下方,故起始扫描沿左上方向
BeginDirect = 0;
//跟踪边界
bFindStartPoint = false;
CurrentPoint.Height = StartPoint.Height;
CurrentPoint.Width = StartPoint.Width;
int index=0;
memset(nVerct,0,9999);
while(!bFindStartPoint)
{
//从起始点一直找边界,直到再次找到起始点为止
bFindPoint = false;
while(!bFindPoint)
{
//沿扫描方向,这里是左上方向获取一个像素
pixel = PointOld( CurrentPoint.Width + Direction[BeginDirect][0],
CurrentPoint.Height + Direction[BeginDirect][1] );
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;
}
//将轮廓在新的位图中标示出来
Point(CurrentPoint.Width,CurrentPoint.Height) = 0;
//扫描的方向逆时针旋转两格
//为什么?因为逆时针旋转三格的象素绝对不是边界,不然当前点就不会是边界。
BeginDirect--;
if(BeginDirect == -1)
BeginDirect = 7;
BeginDirect--;
if(BeginDirect == -1)
BeginDirect = 7;
}
else
{
//扫描方向顺时针旋转一格
BeginDirect++;
if(BeginDirect == 8)
BeginDirect = 0;
}
}
}
//边界跟踪时,边界点数
m_nNumNode =index;
memcpy(DibObject.m_pData,pData,nByteWidth*nHeight);
delete pData;
FileIndex++;
Invalidate(); //重绘
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -