C++实现区域生长算法(Region growing algorithm)

区域生长算法的基本思想是将有相似性质的像素点合并到一起。对每一个区域要先指定一个种子点作为生长的起点,然后将种子点周围领域的像素点和种子点进行对比,将具有相似性质的点合并起来继续向外生长,直到没有满足条件的像素为止。
区域生长算法的设计主要由以下三点:生长种子点的确定,区域生长的条件,区域生长停止的条件。算法的实现步骤:

  1. 选取种子点:种子点可以输入,也可以通过输入的数据自动选取;
  2. 区域生长的条件:相邻象元(四通道或八通道)满足相应的阈值要求即可划分在一个图斑之中;
  3. 区域生长停止的条件:当所有的象元都已经划分在相应的图斑中时,算法结束。

参考代码如下:

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;
}

示例图像及结果:

在这里插入图片描述

欢迎大家批评指正。

  • 4
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

A-Chin

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值