/***********************************************************************************
**********
********** 如果此代碼對您有幫助的話,請多來踩我的Blog
**********
************************************************************************************/
int i, j, nHeight, nWidth; // 圖像的高度和寬度
bool pbFlag[nHeight][nWidth]; // 聲明一個大小爲nHeight*nWidth的矩形
int xStart, xEnd, yStart, yEnd;
/////////////////////////////////////////////////////////////////////////////////
typedef struct __XYPOSITION // 定義一個圖像中座標的數據類型
{
int xPos; // x方向的座標
int yPos; // y方向的座標
}XYPOSITION, *PXYPOSITION;
XYPOSITION *pPosBottom, *pPosTop;
XYPOSITION pXYPos[nWidth*nHeight]; // 聲明一個堆棧
// 初始化,根據二維數據的地圖初始化
for(i=0; i <nHeight; i++ ) // 列掃描
{
for(j=0; j <nWidth; j++ ) // 行掃描
{
// 如果地圖數據爲障礙物1,則pbFlag[i][j]=false
// 否則pbFlag[i][j] = true
}
}
// 第一次搜索
for(i=0; i <nHeight; i++ ) // 列掃描
{
for(j=0; j <nWidth; j++ ) // 行掃描
{
if( pbFlag[i][j] )
{
// 初始化圖像區域的位置
xStart = j;
xEnd = j;
yStart = i;
yEnd = i;
pPosBottom = pXYPos;
pPosTop = pXYPos+1;
// 記錄白色點的座標
(*pPosBottom).xPos = j;
(*pPosBottom).yPos = i;
(*pPosBottom).pbCurrentPos = pbFlag+i*nWidth+j;
pbFlag[i][j] = false;
while( pPosBottom != pPosTop )
{
// 提取出搜索列表中的象素點
X = (*pPosBottom).xPos;
Y = (*pPosBottom++).yPos;
/*****************************
八鄰域處理過程
*****************************/
/************************************
處理第一行的情況
**********************************/
// 搜索第一行的情況
if( Y>0 )
{
Y1 = (Y-1);
// 處理左上角的點
if( X>0 )
{
if( pbFlag[Y1][X-1] )
{
X1 = (X-1);
(*pPosTop).xPos = X1;
(*pPosTop).yPos = Y1;
// 記錄區域的大小
xStart = min(xStart, X1);
yStart = min(yStart, Y1);
// 標識爲已經搜索過
pbFlag[Y1][X1] = false;
}
}
// 處理正上邊的點
if( pbFlag[Y1][X])
{
(*pPosTop).xPos = X;
(*pPosTop).yPos = Y1;
// 記錄區域的大小
yStart = min(yStart, Y1);
// 標識爲已經搜索過
pbFlag[Y1][X] = false;
}
// 處理右上角的點
X1 = (X+1);
if( X1 <nWidth )
{
if( pbFlag[Y1][X1] )
{
(*pPosTop).xPos = X1;
(*pPosTop).yPos = Y1;
// 記錄區域的大小
xEnd = max(xEnd, X1);
yStart = min(yStart, Y1);
// 標識爲已經搜索過
pbFlag[Y1][X1] = false;
}
}
}
/******************************************************************
處理第二行的情況
*****************************************************************/
// 搜索第二行的情況
// 處理正左邊的點
if( X>0 )
{
if( pbFlag[Y][X-1] )
{
X1 = (X-1);
(*pPosTop).xPos = X1;
(*pPosTop).yPos = Y;
// 記錄區域的大小
xStart = min(xStart, X1);
// 標識爲已經搜索過
pbFlag[Y][X1] = false;
}
}
// 處理正右邊的點
X1 = (X+1);
if( X1 <nWidth )
{
if( pbFlag[Y][X1])
{
(*pPosTop).xPos = X1;
(*pPosTop).yPos = Y;
// 記錄區域的大小
xEnd = max(xEnd, X1);
// 標識爲已經搜索過
pbFlag[Y][X1] = false;
}
}
/*******************************************************************
處理第三行的情況
******************************************************************/
// 搜索第三行的情況
if( (Y+1) <nHeight )
{
Y1 = (Y+1);
// 處理左下角的點
if( X>0 )
{
if( pbFlag[Y1][X-1])
{
X1 = (X-1);
(*pPosTop).xPos = X1;
(*pPosTop).yPos = Y1;
// 記錄區域的大小
xStart = min(xStart, X1);
yEnd = max(yEnd, Y1);
// 標識爲已經搜索過
pbFlag[Y1][X1] = false;
}
}
// 處理正下邊的點
if( pbFlag[Y1][X])
{
(*pPosTop).xPos = X;
(*pPosTop).yPos = Y1;
// 記錄區域的大小
yEnd = max(yEnd, Y1);
// 標識爲已經搜索過
pbFlag[Y1][X] = false;
}
// 處理右下角的點
X1 = (X+1);
if( X1 <nWidth )
{
if( pbFlag[Y1][X+1])
{
(*pPosTop).xPos = X1;
(*pPosTop).yPos = Y1;
// 記錄區域的大小
xEnd = max(xEnd, X1);
yEnd = max(yEnd, Y1);
// 標識爲已經搜索過
pbFlag[Y1][X1] = false;
}
}
}
} // while
/*******************************************************************
輸出搜索到的子區域塊
******************************************************************/
if( xStart != 0 // 去除左邊
&& xEnd != (nWidth-1) // 去除右邊
&& yStart != 0 // 去除上邊
&& yEnd != (nHeight-1) // 去除下邊
)
{
pPosBottom = pXYPos;
while( pPosBottom != pPosTop )
{
// 輸出圖形中被障礙物包圍的所有點的座標X,Y
X = (*pPosBottom).xPos;
Y = (*pPosBottom ++).yPos;
}
}
}
} // for j
} // for i