区域生长法图像分割的实现方法

本文介绍一种区域生长法进行图像分割的数据组织方式和实现方法,给出了核心代码,可用该方法实现立体匹配中的非法点检测。

区域生长法图像分割是直接根据像素的相似性和连通性来对图像进行聚类的算法。基本原理是,给出若干种子点,然后依次对这些种子点进行如下操作,直到种子点集合为空:判断种子点四邻域或八邻域的像素点是否和种子点相似(灰度相似或其他测度相似),如果相似则将该点加入种子点集合,否则不作处理。

该算法原理很简单,但在数据结构的组织上却需要技巧,本文介绍一种简易的数据组织方式实现该算法。

如上图所示,左图为一幅W*H大小的图像示意图,利用区域生长法图像分割算法,该图像被分割(聚类)为7块;右图为相应的数据结构,图像分割的结果属于图像空间数据,其实就是一系列的像素点坐标数组或与像素点坐标直接关联的属性数组如FLAG的数组等,这个数组的维度一定是W*H,而分割结果体现在数组元素的排列顺序:同一类别的元素连续存储。然而类别的界限无法用该数组表明,而只能用另外一个描述数组,这里我们称之为图像空间数据的“元数据”数据,这个数组的有效维度为空间数据的类别数,即7,每个元素代表的是空间数据数组中每个类别的元素个数,其实也就相应地表明了每个类别的指针位置。

下面,我们说明这个算法的代码实现过程:

首先定义图像空间数据的结构体和几个重要变量:

	typedef struct{
		unsigned short x;
		unsigned short y;
	}seedpoint;
	enum FLAG{VALID, INVALID, VALID_SEG,INVALID_SEG};//图像空间数据标示
	FLAG *flag;//图像空间数据标示数组
	seedpoint *InvalidSeedPts;//种子点数组
	int num_InvalidSeedPts;//种子点数量
	seedpoint *segmentation_invalidpts;//存储分割结果的数组
	seedpoint *temp_invalidpts;//算法中临时变量
	int num_classes;//分割类别数目
	int *num_class;//空间数据“元数据”数组,存储分割结果每个类别的数目

区域生长法图像分割的算法实现为:

void Segmentation(int delt_connect)
{
	int counter=0;
	int temp_num_invalidpts=0;

	seedpoint point,temppoint;
	for (int i=0;i<num_InvalidSeedPts;i++)
	{
		point = InvalidSeedPts[i];
		if (flag[point.x*width+point.y] == VALID)
		{
			segmentation_invalidpts[counter] = point;
			counter++;

			temp_num_invalidpts=0;
			temp_invalidpts[temp_num_invalidpts] = point;
			temp_num_invalidpts++;
			int j=0;

			flag[point.x*width+point.y] = VALID_SEG;

			while (j<temp_num_invalidpts)
			{
				point = temp_invalidpts[j];
				if ((point.x>0)&&(point.x<(height-1))&&(point.y>0)&&(point.y<(width-1)))
				{
					int index1 = point.x*width+point.y;
					if((flag[(point.x-1)*width+point.y]==VALID))
					{
						temppoint.x = point.x-1;
						temppoint.y = point.y;

						int index2 = temppoint.x*width+temppoint.y;
						int delt = abs(buf[index1] - buf[index2]);

						if(delt < delt_connect)
						{
							segmentation_invalidpts[counter] = temppoint;
							counter++;
							temp_invalidpts[temp_num_invalidpts] = temppoint;
							temp_num_invalidpts++;
							flag[(point.x-1)*width+point.y]=VALID_SEG;
						}
					}
					if((flag[(point.x+1)*width+point.y]==VALID))
					{
						temppoint.x = point.x+1;
						temppoint.y = point.y;

						int index2 = temppoint.x*width+temppoint.y;
						int delt = abs(buf[index1] - buf[index2]);

						if(delt < delt_connect)
						{
							segmentation_invalidpts[counter] = temppoint;
							counter++;
							temp_invalidpts[temp_num_invalidpts] = temppoint;
							temp_num_invalidpts++;
							flag[(point.x+1)*width+point.y]=VALID_SEG;
						}
					}
					if((flag[point.x*width+point.y+1]==VALID))
					{
						temppoint.x = point.x;
						temppoint.y = point.y+1;

						int index2 = temppoint.x*width+temppoint.y;
						int delt = abs(buf[index1] - buf[index2]);

						if(delt < delt_connect)
						{
							segmentation_invalidpts[counter] = temppoint;
							counter++;
							temp_invalidpts[temp_num_invalidpts] = temppoint;
							temp_num_invalidpts++;
							flag[point.x*width+point.y+1]=VALID_SEG;
						}
					}
					if((flag[point.x*width+point.y-1]==VALID))
					{
						temppoint.x = point.x;
						temppoint.y = point.y-1;

						int index2 = temppoint.x*width+temppoint.y;
						int delt = abs(buf[index1] - buf[index2]);

						if(delt < delt_connect)
						{
							segmentation_invalidpts[counter] = temppoint;
							counter++;
							temp_invalidpts[temp_num_invalidpts] = temppoint;
							temp_num_invalidpts++;
							flag[point.x*width+point.y-1]=VALID_SEG;
						}
					}
				}
				j++;
			}
			num_class[num_classes] = temp_num_invalidpts;
			num_classes++;
		}
	}
}

利用该算法,我们检测一幅立体匹配视差图中非法点,其实就是对分割结果进行检测,即将类别元素数小于一定阈值的类别标示为非法点,检测结果如下:

  

其中,左图为原始结果,中图为非法点检测结果,右图为非法点FLAG图像。

时间: 2024-10-31 20:22:56

区域生长法图像分割的实现方法的相关文章

基于区域生长的图像分割法问题(1)

matlab I The input character is not valid in MATLAB statements or expressions. 今天在用基于区域生长的图像分割法时出现了这个问题,总结一下 解决办法 1.保存的文件名是否非法,不要用汉字保存 2.是否使用了汉字输入Editor 3.imread的图片是否是汉字,数字开头等非法内容

基于图像分割的立体匹配方法

1.绪论 立体匹配是三维重建系统的关键步骤,并且作为一种非接触测量方法在工业以及科研领域具有重要的应用价值.为了完成匹配工作以及获取场景的稠密视差图,可以通过构建能量函数对应立体匹配的约束条件.复杂能量函数的全局最优解通常是NP难问题.相对于其他全局优化算法相比如模拟退火.梯度下降.动态规划等,图割算法不仅精度高,收敛速度快,并且对于光照变化.弱纹理等区域的匹配效果也比其他算法好. 2.图割算法 计算机视觉领域的大部分问题可以转换为标号问题,在立体匹配中视差的求解就是对图像的像素在视察范围内的离

PHP的两个科学计数法转换为字符串的方法

不常用,所以整理在这里,分享给同行使用 方法一:取尾数法 public function NumToStr($num) { if (stripos($num, 'e') === false) return $num; $num = trim(preg_replace('/[=\'"]/', '', $num, 1), '"'); //出现科学计数法,还原成字符串 $result = ""; while ($num > 0) { $v = $num - floo

回溯法的解空间表示方法

回溯法解题时通常包含3个步骤: 1. 针对所给问题,定义问题的解空间: 2. 确定易于搜索的解空间结构: 3. 以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索. 对于问题的解空间结构通常以树或图的形式表示,常用的两类典型的解空间树是子集树和排列树.当所给的问题是从n个元素的集合S中找到S满足某种性质的子集时,相应的解空间树称为子集树.例如,n个物品的0-1背包问题所对应的解空间树是一棵子集树,这类子集树通常有2**n个叶结点,遍历子集树的算法需要O(2**n)计算时间.当所给问题

SA:T1编写主函数法和T2Matlab自带的SA工具箱GUI法,两种方法实现对二元函数优化求解——Jason niu

%SA:T1法利用Matlab编写主函数实现对定义域[-5,5]上的二元函数求最优解-Jason niu [x,y] = meshgrid(-5:0.1:5,-5:0.1:5); z = x.^2 + y.^2 - 10*cos(2*pi*x) - 10*cos(2*pi*y) + 20; figure mesh(x,y,z) hold on xlabel('x') ylabel('y') zlabel('z') title('SA:利用SA最优化,定义域[-5,5]上的二元函数z = x^2

navicat cannot create file 文件名、目录名或卷标语法不正确 解决方法

配置了mycat,用navicat连接8066端口,点击“查询”的时候发现出现报错: 开始以为是mycat的配置有问题,找了好久都没发现错误.根据提示信息进入到相应的目录发现每个连接其实就是一个windows文件夹 大家看看我的连接名 这里连接名使用了“:”,尝试修改后发现确实可以. 原因是:Windows系统文件名不能有英文 [ :] 的原因.

基于遗传算法的Ostu法在图像分割中的应用

像素关系相邻像素       位于坐标(x,y)处的像素P有4个水平和垂直的相邻像素,其坐标为: (x+1,y),(x-1,y),(x,y+1),(x,y-1) 这组相邻元素称为P的4邻域.用N4(P)表示.类似于十字形. P的4个对角相邻像素坐标如下: (x+1,y+1),(x+1,y-1),(x-1,y+1),(x-1,y+1) 用ND(P)表示.这些点与N4(P)的4个点一起称为P的8邻域,用N8(P)表示. 邻接,连通,区域和边界 V是定义邻接性的灰度值集合.在二值图像中,如果把具有1值

几何画板追踪法构造阴影方法

几何图形中常常有几条曲线相交,围成一个区域,或者几个图形叠加,有一个重叠部分,如何突出显示这个部分呢?本文教你利用几何画板追踪法画阴影. 以两个圆相交部份为例,操作步骤如下: 利用圆工具绘制两个相交圆.利用线段工具在两圆相交的部份绘制一条线段,端点落在两个圆上. 选中线段,选择“显示”——“追踪线段”.上下移动线段,反复扫描.如果阴影太稀疏,可以增加扫描次数.隐藏线段. 以上内容向大家介绍了利用几何画板追踪法构造阴影的方法,操作非常简单,只要能够理解追踪法即可.几何画板阴影的构造方法有很多,比如

区域生长算法(C# 实现)

区域生长算法 2014年9月19日 17:01:44 大道理一摆: (以下说明转载,感觉写的很好) 历史:区域生长是一种古老的图像分割方法,最早的区域生长图像分割方法是由Levine等人提出的.该方法一般有两种方式,一种是先给定图像中要分割的目标物体内的一个小块或者说种子区域(seed point),再在种子区域基础上不断将其周围的像素点以一定的规则加入其中,达到最终将代表该物体的所有像素点结合成一个区域的目的:另一种是先将图像分割成很多的一致性较强,如区域内像素灰度值相同的小区域,再按一定的规