?? 于八方向鏈碼的邊界跟蹤代碼.txt
字號:
于八方向鏈碼的邊界跟蹤代碼,其中nVerct數(shù)組存儲的是邊界點的矢量方向,Coordinate存儲的是邊界點的坐標(biāo)。
//函數(shù) 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; //當(dāng)前矢量,即在輪廓跟蹤中的前一個搜索方向
CPoint CurrenPoint; //當(dāng)前點的坐標(biāo)
};
//CArray <EdgePoint,EdgePoint&> TraceArray;
//獲取位圖的寬,高,以及每行字節(jié)數(shù)
int nWidth=DibObject.GetWidth();
int nByteWidth=DibObject.GetByteWidth();
int nHeight=DibObject.GetHeight();
//循環(huán)變量
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;
//起始邊界點與當(dāng)前邊界點
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++)
{
//取得當(dāng)前指針處的像素值
pixel = PointOld(i,j);
if(pixel == 0)
{
bFindStartPoint = true;
StartPoint.Height = j;
StartPoint.Width = i;
// 指向目標(biāo)圖像倒數(shù)第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;
//存儲邊界點的坐標(biāo)
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;
}
//將輪廓在新的位圖中標(biāo)示出來
Point(CurrentPoint.Width,CurrentPoint.Height) = 0;
//掃描的方向逆時針旋轉(zhuǎn)兩格
//為什么?因為逆時針旋轉(zhuǎn)三格的象素絕對不是邊界,不然當(dāng)前點就不會是邊界。
BeginDirect--;
if(BeginDirect == -1)
BeginDirect = 7;
BeginDirect--;
if(BeginDirect == -1)
BeginDirect = 7;
}
else
{
//掃描方向順時針旋轉(zhuǎn)一格
BeginDirect++;
if(BeginDirect == 8)
BeginDirect = 0;
}
}
}
//邊界跟蹤時,邊界點數(shù)
m_nNumNode =index;
memcpy(DibObject.m_pData,pData,nByteWidth*nHeight);
delete pData;
FileIndex++;
Invalidate(); //重繪
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -