/***********************************************************************************
**********
********** 如果此代码对您有帮助的话,请多来踩我的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