区域生长算法的基本思想是将有相似性质的像素点合并到一起。对每一个区域要先指定一个种子点作为生长的起点,然后将种子点周围领域的像素点和种子点进行对比,将具有相似性质的点合并起来继续向外生长,直到没有满足条件的像素为止。
区域生长算法的设计主要由以下三点:生长种子点的确定,区域生长的条件,区域生长停止的条件。算法的实现步骤:
- 选取种子点:种子点可以输入,也可以通过输入的数据自动选取;
- 区域生长的条件:相邻象元(四通道或八通道)满足相应的阈值要求即可划分在一个图斑之中;
- 区域生长停止的条件:当所有的象元都已经划分在相应的图斑中时,算法结束。
参考代码如下:
bool regiongrow(float *input, int nImgWidth, int nImgHeight, float threshold, float *output)
{
stack <PT> seed;
PT tempt;
vector <PT> tempploy;
vector < vector <PT> > polys;
PT* pts=new PT [nImgWidth * nImgHeight];
for(int i = 0; i < nImgHeight;++i)
{
for (int j = 0; j < nImgWidth; ++j)
{
pts[i * nImgWidth + j].pix = input[i * nImgWidth + j];
pts[i * nImgWidth + j].x = i;
pts[i * nImgWidth + j].y = j;
pts[i * nImgWidth + j].polynum = -1;
}
}
for(int i = 0; i < nImgHeight; ++i)
{
for (int j = 0; j < nImgWidth; ++j)
{
if(pts[i * nImgWidth + j].pix <= 0)
continue;
if(pts[i * nImgWidth + j].polynum > -1)
continue;
if(seed.empty() == true)
seed.push(pts[i * nImgWidth + j]);
while(!seed.empty() == true)
{
tempt = seed.top(); //取出栈顶元素
seed.pop(); //删除栈顶元素
tempploy.push_back(tempt); //将栈顶元素放入到临时图斑中
pts[(int)(tempt.x * nImgWidth + tempt.y)].polynum = polys.size(); //此时已有归属
for (int bufferX = -1; bufferX <= 1; ++bufferX)
{
for (int bufferY = -1; bufferY <= 1; ++bufferY)
{
//对该种子点的八邻域进行遍历
//判断所在是否在有效的范围内
if(tempt.x + bufferX < 0 || tempt.x + bufferX >= nImgHeight || tempt.y + bufferY < 0 || tempt.y + bufferY >= nImgWidth)
continue;
//判断是否有归属
if(pts[((int)tempt.x + bufferX) * nImgWidth + ((int)tempt.y + bufferY)].polynum > -1)
continue;
//判断是否满足阈值条件
if(abs(pts[((int)tempt.x + bufferX) * nImgWidth + ((int)tempt.y + bufferY)].pix - tempt.pix) <= threshold)
{
seed.push(pts[((int)tempt.x + bufferX) * nImgWidth + ((int)tempt.y + bufferY)]);
pts[((int)tempt.x + bufferX) * nImgWidth + ((int)tempt.y + bufferY)].polynum = polys.size();
}
}
}
}
polys.push_back(tempploy);
tempploy.clear();
}
}
for (int i = 0; i < polys.size(); ++i)
{
for(int j = 0; j < polys[i].size(); ++j)
{
output[(int)(polys[i][j].x * nImgWidth + polys[i][j].y)] = polys[i][j].pix;
}
}
}
delete [] pts;
return true;
}
示例图像及结果:
欢迎大家批评指正。