区域生长算法代码

合集下载

欧几里得与区域生长算法

欧几里得与区域生长算法

欧⼏⾥得与区域⽣长算法【摘⾃】https:///ironstark/p/5000147.html欧⼏⾥得与区域⽣长算法 基于欧式距离的分割和基于区域⽣长的分割本质上都是⽤区分邻⾥关系远近来完成的。

由于点云数据提供了更⾼维度的数据,故有很多信息可以提取获得。

欧⼏⾥得算法使⽤邻居之间距离作为判定标准,⽽区域⽣长算法则利⽤了法线,曲率,颜⾊等信息来判断点云是否应该聚成⼀类。

1.欧⼏⾥得算法 算法的原理在PCL相关的教程中已经说的⽐较清楚了,我不再给出伪代码。

我想⽤⼀个故事来讲讲这个问题。

从前有⼀个脑筋急转弯,说⼀个锅⾥有两粒⾖⼦,如果不⽤⼿,要怎么把它们分开。

当时的答案是⾖⼦本来就是分开的,⼜没黏在⼀起,怎么不叫分开。

OK,实际上欧⼏⾥德算法就是这个意思。

两团点云就像是两粒⾖⼦,只要找到某个合适的度量⽅式,就有办法把点云和点云分开。

区分⾖⼦我们⽤的⽅法可以归结于,两个⾖⼦之间的距离⼩于分⼦距离,所以它们并没有连在⼀起。

如果两团点云之间最近两点的距离⼩于单个点云内部点之间的距离,则可以由算法判断其分为两类。

假设总点云集合为A,聚类所得点云团为Q 具体的实现⽅法⼤致是:1. 找到空间中某点p10,有kdTree找到离他最近的n个点,判断这n个点到p的距离。

将距离⼩于阈值r的点p12,p13,p14....放在类Q⾥2. 在 Q\p10 ⾥找到⼀点p12,重复13. 在 Q\p10,p12 找到找到⼀点,重复1,找到p22,p23,p24....全部放进Q⾥4. 当 Q 再也不能有新点加⼊了,则完成搜索了按照我的理解,欧拉聚类⽤⼀个queue就可以很好的实现,试写⼀个伪代码如下:1 ClusterType cluster;2 std::queue<PointType> que;3 que.push(clouds->at(0));4 cluster->push(que.front());5while (!que.empty())6 {7 PointType point = que.front();8 std::vector<PointType> points_neighbor = kdtree->search(clouds, point, radius);//搜寻point的临近点9for (auto pt : points_neighbor)10 {11 que.push(pt);12 }13 cluster->push(point);14 que.pop();15 }16return cluster; 听起来好像这个算法并没什么⽤,因为点云总是连成⽚的,很少有什么东西会浮在空中让你来分。

python模拟植物生长算法

python模拟植物生长算法

python模拟植物生长算法植物生长算法(Plant Growth Algorithm, PGA)是一种启发式优化算法,其灵感来自于植物的生长过程。

它模拟了植物根系和叶子的生长规律,通过模拟这些生物的行为来优化问题的解。

下面是一个简单的Python代码示例,演示了如何使用植物生长算法来解决一个简单的优化问题(最小化目标函数):```pythonimport numpy as np# 定义目标函数def objective_func(x):return x[0]**2 + x[1]**2# 定义植物生长算法def plant_growth_algorithm(objective_func, num_plants,num_iterations):# 随机初始化种子点(植物的位置)plants = np.random.rand(num_plants, 2) * 10 - 5for i in range(num_iterations):# 对每个植物计算目标函数值,并选择最优的植物plant_values = [objective_func(plant) for plant in plants]best_plant_idx = np.argmin(plant_values)best_plant = plants[best_plant_idx]# 生成新的植物new_plants = []for plant in plants:# 根据最优植物的位置和随机因子生成新的位置new_plant = plant + np.random.rand(2) * (best_plant - plant)new_plants.append(new_plant)plants = np.array(new_plants)return best_plant# 使用植物生长算法求解最小化问题best_solution = plant_growth_algorithm(objective_func,num_plants=50, num_iterations=100)print("Best solution:", best_solution)```在这个例子中,我们定义了一个简单的目标函数`objective_func`,它的参数是一个二维向量。

区域生长 形态学 分水岭算法

区域生长 形态学  分水岭算法

n r 数 h(rk ) nk 表示。其中, k 是第K级灰度, k 是灰
度级为 rk的像素个数。
通常迚行归一化处理,n是图像中像素的总数 n p ( rk ) k ,我们也可以称为 n 灰度级为 rk 发生的概率估计。且各级相加之和为
1
提出一种想法:若一副图像的像素占有全部可能的灰度 级并且分布均匀,那么这幅图像就会有较高的对比度,
直方图匹配
第二部分
形态学操作
膨胀不腐蚀
1
4
区域填充
开操作不闭操 作
2
形态学
5
连通分量的提 取
击中击丌中变 换
3
6
重构
腐蚀
把结构元素S平移x后得到Sx,若Sx包含于X,我们记下这个x点,所有满 足上述条件的x点组成的集合称做X被S腐蚀(Erosion)的结果。用公式表示为:
腐蚀的方法是,拿S的原点和X上的点一个一个地对比,如果S上的所有点 都在X的范围内,则S的原点对应的点保留,否则将该点去掉。
最近工作汇报
前 言
首先自我检讨一下,来这边整整一个月的时间,说真的并没有把时间
分配处理的很好,常常处在一种困惑的阶段,时丌时得干劲十足,可能一 段时间之后又失去方向了。。。丌过丌管怎么样,还是在一定程度上有所
迚步,首先是渐渐收敛了玩的心,再者就是戒多戒少学到了一些知识,希
望在今后的日子里,可以更好得利用自己的学习时间,提高效率,和大家 沟通交流,自己也能有更多的IDEA,再接再励 O(∩_∩)O
且灰度级动态范围大
直方图均衡
直方图均衡化:顾名思义,就是通过灰度变换将一幅图象转换 为另一幅具有均衡直方图,即在每个灰度级上都具有相同的象 素点数的过程, Ps ( s ) 1 直方图均衡化变换:设灰度变换s=T(r)为斜率有限的非减连续 可微函数,它将输入图象Ii(x,y)转换为输出图象Io(x,y),输 入图象的直方图为Hi(r),输出图象的直方图为Ho(s),则根据直 方图的含义,经过灰度变换后对应的小面积元相等: Ho(s)ds=Hi(r)dr

Python图像分割之区域增长法

Python图像分割之区域增长法

Python图像分割之区域增长法 原⽂链接:⼀、简介 区域增长法是⼀种已受到计算机视觉界⼗分关注的图像分割⽅法。

它是以区域为处理对象的,它考虑到区域内部和区域之间的同异性,尽量保持区域中像素的临近性和⼀致性的统⼀。

这样就可以更好地分辨图像真正的边界。

基于区域的分割⽅法的关键在于定义⼀个⼀致性准则,⽤来判断两个邻接的区域是否可以合并,⼀致则将两区域合并,直到不能合并为⽌。

区域增长的⽅法是在图像上选定⼀个种⼦点,记录下该点的灰度值,作为⼀致性判断的标准阈值,此外还需要定义⼀个标准差。

算法的主要过程是,依次⽤图像的每⼀个像素的灰度值和标准阈值相减,判断结果是否⼩于标准差,是则将该点和种⼦点合并,不是则保持像素点的灰度值不变。

这样处理后的图像就是⽤区域分割法处理后的边缘分割图像。

⼆、实例下⾯我们通过⼀个例⼦来进⾏详细的解释 上图⽰意的是区域增长的过程,图中的⽅格表⽰图像的像素点,⽅格中的数值表⽰像素点的灰度值。

(a)表⽰开始选取的⽣长点,在⽣长的过程中,每个⽣长点都将本⾝上下左右4个像素点和初试选取的⽣长点⽐较灰度值,如果灰度值的差的绝对值在设定的阈值内,则认为这些点是属于相同区域并将其合并,否则将灰度差⼤于设定阈值的点删除,重复检查区域内的像素点,直到没有像素点可以合并位置。

不妨设上图的阈值为2,(b)中4个点和初始点的灰度差都不⼤于2,所以合并;(c)中只有部分满⾜条件,所以只合并满⾜条件的像素点,并且(c)区域周围邻域中没有点再满⾜条件,因此⽣长结束。

三、算法步骤通过上述⽰例,我们可以总结出区域增长法的⼀般步骤如下:1)对图像⾃上⽽下,⾃左⽽右扫描,找到第1个还没有访问过的像素, 设该像素为(x0, y0);2)以(x0, y0)为中⼼, 考虑(x0, y0)的8邻域像素(x, y),如果其邻域满⾜⽣长准则, 将(x, y)与(x0, y0)合并(在同⼀区域内), 同时将(x, y)压⼊堆栈; 3)从堆栈中取出⼀个像素, 把它当作(x0, y0)返回到上⼀步骤;4)当堆栈为空时返回到步骤1;5)重复步骤1 - 4直到图像中的每个点都被访问过时,算法结束。

fpgrowth算法代码

fpgrowth算法代码

fpgrowth算法代码FP-Growth算法是一种高效的关联规则挖掘算法,其主要原理是将数据集转换为频繁模式的树形结构来进行挖掘。

以下是FP-Growth 算法的Python代码实现:首先,我们需要定义一个类来表示FP树的节点:class TreeNode:def __init__(self, name_value, num_count, parent_node): = name_valueself.count = num_countself.parent = parent_nodeself.children = {}self.next = None其中,name表示节点的名称,count表示节点的计数值,parent表示节点的父节点,children表示节点的子节点,next表示指向相同元素项的不同节点。

然后,我们需要定义一个类来实现FP-Growth算法:class FPGrowth:def __init__(self, min_sup=1):self.min_sup = min_supself.freq_items = {}self.head_table = {}self.tree = Nonedef fit(self, data_set):self.build_head_table(data_set)self.build_FP_tree(data_set)self.mine_freq_items()def build_head_table(self, data_set):for trans in data_set:for item in trans:self.head_table[item] =self.head_table.get(item, 0) + data_set[trans]for item in self.head_table.copy():if self.head_table[item] < self.min_sup:del(self.head_table[item])for item in self.head_table:self.freq_items[frozenset([item])] =self.head_table[item]def build_FP_tree(self, data_set):self.tree = TreeNode('Null Set', 1, None)for trans, count in data_set.items():sorted_items = [item for item in trans if item in self.head_table]sorted_items.sort(key=lambda x:self.head_table[x], reverse=True)if len(sorted_items) > 0:self.insert_tree(sorted_items, count,self.tree)def insert_tree(self, items, count, cur_node):first_item = items[0]if first_item in cur_node.children:cur_node.children[first_item].count += countelse:cur_node.children[first_item] =TreeNode(first_item, count, cur_node)if self.head_table[first_item] is None:self.head_table[first_item] =cur_node.children[first_item]else:self.update_headtable(cur_node.children[first_item], self.head_table[first_item])if len(items) > 1:self.insert_tree(items[1:], count,cur_node.children[first_item])def update_headtable(self, target_node, next_node): while (next_node.next is not None):next_node = next_node.nextnext_node.next = target_nodedef mine_freq_items(self):freq_item_set = set(self.freq_items.keys())if len(freq_item_set) == 0:return Nonesorted_items = sorted(self.freq_items.items(), key=lambda x: x[1])for item in sorted_items:base_set = set(item[0])freq_set = frozenset(base_set)self.freq_items[freq_set] = item[1]conditional_tree =self.get_conditional_tree(base_set)if conditional_tree is not None:conditional_fpg = FPGrowth(self.min_sup)conditional_fpg.tree = conditional_treeconditional_fpg.build_head_table(self.create_conditional_db(b ase_set))conditional_fpg.mine_freq_items()for freq_item_set, count inconditional_fpg.freq_items.items():full_freq_set = freq_item_set | freq_set self.freq_items[full_freq_set] =self.freq_items.get(full_freq_set, 0) + countdef get_conditional_tree(self, base_set):if base_set is None or len(base_set) == 0:return Noneitem_count = {}for trans in self.head_table:item_set = set()cur_node = self.head_table[trans]while (cur_node is not None):iflen(base_set.intersection(set(cur_))) > 0:item_set.add(cur_)cur_node = cur_node.nextif len(item_set) > 0:item_count[trans] = item_setif len(item_count) == 0:return Noneconditional_tree = TreeNode('Null Set', 1, None)for trans, item_set in item_count.items():sorted_items = [item for item in list(item_set)if item in self.head_table]if len(sorted_items) > 0:self.insert_tree(sorted_items,data_set[trans], conditional_tree)return conditional_treedef create_conditional_db(self, base_set):new_db = {}for trans, count in data_set.items():base_set_list = [item for item in trans if itemin base_set]if len(base_set_list) > 0:base_set_list.sort(key=lambda x:self.head_table[x], reverse=True)new_db[frozenset(base_set_list)] = countreturn new_dbdef get_freq_items(self):return self.freq_items在FP-Growth类中,fit函数用于对数据集进行频繁模式挖掘,其中分别调用了build_head_table、build_FP_tree和mine_freq_items三个函数。

opencv 区域生长分割算法

opencv 区域生长分割算法

OpenCV中没有直接提供区域生长分割算法,但你可以使用OpenCV的其它功能来实现区域生长分割。

区域生长的基本思想是将具有相似性质的像素组合在一起,形成一个区域。

在实现时,首先选择一个种子点,然后按照某种规则将与种子点性质相似的相邻像素加入到区域中,直到没有可加入的像素为止。

以下是一个简单的Python代码示例,使用OpenCV实现基于像素值的区域生长分割:```pythonimport cv2import numpy as np# 读取图像img = cv2.imread('image.jpg', 0)# 定义种子点seed = (50, 50)# 定义生长规则,这里使用像素值criteria = (cv2.TERM_CRITERIA_EPS + cv2.TERM_CRITERIA_MAX_ITER, 100, 0.2)# 执行区域生长分割_, label, stats, centroid = cv2.connectedComponentsWithStats(img, connectivity=8, ltype=cv2.CV_32S, seedPoint=seed)# 将结果二值化label = label.astype(np.uint8)ret, label = cv2.threshold(label, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)# 显示结果cv2.imshow('segmented image', label)cv2.waitKey(0)cv2.destroyAllWindows()```在这个示例中,我们首先读取图像,然后定义一个种子点。

接下来,我们使用`cv2.connectedComponentsWithStats()`函数执行区域生长分割,该函数返回每个连通组件的标签、连通组件的统计信息(包括连通组件的尺寸、边界矩形等)和连通组件的中心点。

Matlab程序遗传算法大津法区域生长法迭代法分割图像

Matlab程序遗传算法大津法区域生长法迭代法分割图像

Matlab程序:遗传算法/大津法/区域生长法/迭代法分割图像区域生长的图像分割程序image=imread('mri1.bmp');I=rgb2gray(image);figure,imshow(I),title('原始图像')I=double(I);[M,N]=size(I);[y,x]=getpts; %获得区域生长起始点x1=round(x); %横坐标取整y1=round(y); %纵坐标取整seed=I(x1,y1); %将生长起始点灰度值存入seed中Y=zeros(M,N); %作一个全零与原图像等大的图像矩阵Y,作为输出图像矩阵Y(x1,y1)=1; %将Y中与所取点相对应位置的点设置为白场sum=seed; %储存符合区域生长条件的点的灰度值的和suit=1; %储存符合区域生长条件的点的个数count=1; %记录每次判断一点周围八点符合条件的新点的数目threshold=15; %域值while count>0s=0; %记录判断一点周围八点时,符合条件的新点的灰度值之和count=0;for i=1:Mfor j=1:Nif Y(i,j)==1if (i-1)>0 && (i+1)<(M+1) && (j-1)>0 && (j+1)<(N+1) %判断此点是否为图像边界上的点for u= -1:1 %判断点周围八点是否符合域值条件for v= -1:1 %u,v为偏移量if Y(i+u,j+v)==0 & abs(I(i+u,j+v)-seed)<=threshold& 1/(1+1/15*abs(I(i+u,j+v)-seed))>0.8%判断是否未存在于输出矩阵Y,并且为符合域值条件的点Y(i+u,j+v)=1; %符合以上两条件即将其在Y中与之位置对应的点设置为白场count=count+1;s=s+I(i+u,j+v); %此点的灰度之加入s中endendendendendendendsuit=suit+count; %将n 加入符合点数计数器中sum=sum+s; %将s加入符合点的灰度值总合中seed=sum/suit; %计算新的灰度平均值endfigure,imshow(Y),title('分割后图像')。

区域生长算法(附MATLAB代码实现)

区域生长算法(附MATLAB代码实现)

区域⽣长算法(附MATLAB代码实现)⼀、理论概念 区域⽣长是按照事先定义的⽣长准则将⼀个像素或者⼦区域逐步聚合成⼀个完整独⽴的连通区域过程。

对于图像感兴趣⽬标区域R,z为区域R上事先发现的种⼦点,按照规定的⽣长准则逐步将与种⼦点z⼀定邻域内符合相似性判据的像素合并成⼀个种⼦群以备下⼀阶段的⽣长,这样不断的进⾏循环⽣长直到满⾜⽣长停⽌条件为⽌,从⽽完成了对感兴趣区域由⼀个种⼦点⽣长为⼀个独⽴连通区域的过程。

其中相似性判据可以是像素灰度值、颜⾊、纹理特征等图像信息。

因此区域⽣长算法⼀般分为三个步骤实现:(1) 确定⽣长种⼦点(2) 规定⽣长准则(3) 确定⽣长停⽌条件实际⼯程应⽤中区域⽣长算法常被⽤于对⼆值化图像指定连通区域的分割。

图1以图⽂⽅式对区域⽣长算法的三步骤进⾏解释:①原始⼆值化图像(a)中的红⾊标注的像素为指定⽣长点;②图像(b)和(c)是采⽤不同⽣长准则进⾏区域⽣长的结果,其中图(b)是在4邻域下,待测像素与⽣长点像素灰度值相等的像素集合。

正如图中所⽰第1次⽣长时,与⽣长点像素灰度相等的像素有上、下、左、右四个像素,接着第⼆次⽣长时,就由前⼀次已经⽣长的像素按照同样的准则进⾏下去,直到遇到图像边界或背景区域时⽣长停⽌。

图(c)是在8邻域下,待测像素与⽣长点像素灰度值相等的像素集合。

⼆、MATLAB⽰例代码实现2.1 主函数⽂件%主⽂件clc;clear all;close all;%申明全局变量 R:区域⽣长的结果图像;BW:⼆值化图像;counter:感兴趣连通区域的像素个数%row:图像的⾏数;col:图像的列数global R BW counter row colI = imread('E:\MATLAB仿真\fsr.bmp');I = I(:,:,1);[row,col] = size(I);figure,imshow(I);level = graythresh(I);BW = im2bw(I,level);figure,imshow(BW);[y0,x0] = getpts;x0 = uint32(x0);y0 = uint32(y0);counter = 0;R = zeros(row,col);R = uint8(R);fsrRegiongrow(x0,y0,4);% fsrRegiongrow1(x0,y0,4);figure,imshow(R);2.2 函数模块1function fsrRegiongrow(x0,y0,mode)%功能:通过函数递归⽅法对⼆值化图像指定连通区域实现区域⽣长%输⼊参数: x0,y0表⽰⽣长点像素坐标,mode表⽰以多⼤邻域进⾏区域⽣长,常取mode = 4;mode = 8;%输出参数: void%作者&时间:奔跑在湘边———2016年5⽉6⽇global R BW counter row colif 8 == modefor i = -1 : 1for j = -1 : 1x1 = x0 + i;y1 = y0 + j;%⽣长准则:判断⽣长点8邻域内像素的各⾃灰度值是否与⽣长点所在像素灰度值相等if x1 > 0 && x1 <= row && y1 > 0 && y1 <= col && BW(x1,y1) == BW(x0,y0) && 0 == R(x1,y1)R(x1,y1) = 255;counter = counter + 1;fsrRegiongrow(x1,y1,mode);endendendelseif 4 == modefor i = -1 : 1x1 = x0 + i;y1 = y0;if x1 > 0 && x1 <= row && y1 > 0 && y1 <= col && BW(x1,y1) == BW(x0,y0) && 0 == R(x1,y1)R(x1,y1) = 255;counter = counter + 1;fsrRegiongrow(x1,y1,mode);endendx1 = x0;y1 = y0 - 1;if x1 > 0 && x1 <= row && y1 > 0 && y1 <= col && BW(x1,y1) == BW(x0,y0) && 0 == R(x1,y1)R(x1,y1) = 255;counter = counter + 1;fsrRegiongrow(x1,y1,mode);endx1 = x0;y1 = y0 + 1;if x1 > 0 && x1 <= row && y1 > 0 && y1 <= col && BW(x1,y1) == BW(x0,y0) && 0 == R(x1,y1)R(x1,y1) = 255;counter = counter + 1;fsrRegiongrow(x1,y1,mode);endendend2.3 函数模块2function fsrRegiongrow1(x0,y0,mode)%功能:模拟栈的先进后出思路对⼆值化图像指定连通区域实现区域⽣长%输⼊参数: x0,y0表⽰⽣长点像素坐标,mode表⽰以多⼤邻域进⾏区域⽣长,常取mode = 4;mode = 8;%输出参数: void%作者&时间:奔跑在湘边———2016年5⽉6⽇global R BW counter row colzhan = zeros(row*col,2);%创建栈数组pzhan = 1; %栈计数zhan(pzhan,1) = x0;zhan(pzhan,2) = y0;R(x0,y0) = 255;counter = 1;if 8 == modewhile pzhan > 0x1 = zhan(pzhan,1);%出栈y1 = zhan(pzhan,2);pzhan = pzhan - 1; %栈计数减⼀for i = -1 : 1for j = -1 : 1%⽣长准则:判断⽣长点8邻域内像素的各⾃灰度值是否与⽣长点所在像素灰度值相等if x1+i > 0 && x1+i <= row && y1+j > 0 && y1+j <= col && BW(x1+i,y1+j) == BW(x1,y1) && R(x1+i,y1+j) ~= R(x1,y1) R(x1+i,y1+j) = R(x1,y1);counter = counter + 1;pzhan = pzhan + 1; %栈计数增⼀zhan(pzhan,1) = x1 + i;%⼊栈zhan(pzhan,2) = y1 + j;endendendendelseif 4 == modewhile pzhan > 0x1 = zhan(pzhan,1);y1 = zhan(pzhan,2);pzhan = pzhan - 1;for i = -1 : 2 : 1j = 0;if x1+i > 0 && x1+i <= row && y1+j > 0 && y1+j <= col && BW(x1+i,y1+j) == BW(x1,y1) && R(x1+i,y1+j) ~= R(x1,y1)R(x1+i,y1+j) = R(x1,y1);counter = counter + 1;pzhan = pzhan + 1;zhan(pzhan,1) = x1 + i;zhan(pzhan,2) = y1 + j;endendfor j = -1 : 2 : 1i = 0;if x1+i > 0 && x1+i <= row && y1+j > 0 && y1+j <= col && BW(x1+i,y1+j) == BW(x1,y1) && R(x1+i,y1+j) ~= R(x1,y1)R(x1+i,y1+j) = R(x1,y1);counter = counter + 1;pzhan = pzhan + 1;zhan(pzhan,1) = x1 + i;zhan(pzhan,2) = y1 + j;endendendendend三、说明在基于MATLAB7.11.0(R2010b)平台调⽤函数模块fsrRegiongrow时,MATLAB会弹出如下警告??? Maximum recursion limit of 500 reached. Use set(0,'RecursionLimit',N)to change the limit. Be aware that exceeding your available stack space can crash MATLAB and/or your computer.Error in ==> fsrRegiongrow上述警告表⽰递归次数超出了MATLAB默认值,也就是说待处理的感兴趣连通区域像素个数太多(⼤于500),此时⽤户可以尝试通过提⽰的set函数来修改函数递归次数,但是本⽂通过测试发现如果递归次数超出1591时(不同的平台该值可能不同),MATLAB软件会⾃动⽴即关闭。

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

区域增长算法/***************************************************** ************ \\函数名称:* RegionGrow()** \\输入参数:* CDib * pDib - 指向CDib类的指针,含有原始图象信息* unsigned char * pUnRegion - 指向区域生长结果的指针** \\返回值:* 无** \\说明:* pUnRegion指针指向的数据区存储了区域生长的结果,其中1(逻辑)表示* 对应象素为生长区域,0表示为非生长区域* 区域生长一般包含三个比较重要的问题:* 1. 种子点的选取* 2. 生长准则* 3. 终止条件* 可以认为,这三个问题需要具体分析,而且每个问题解决的好坏直接关系到* 区域生长的结果。

* 本函数的种子点选取为图像的中心,生长准则是相邻象素的象素值小于* nThreshold, 终止条件是一直进行到再没有满足生长准则需要的象素时为止******************************************************* ********************/void RegionGrow(CDib * pDib, unsigned char * pUnRegion, int nThreshold){static int nDx[]={-1,0,1,0};static int nDy[]={0,1,0,-1};// 遍历图象的纵坐标// int y;// 遍历图象的横坐标// int x;// 图象的长宽大小CSize sizeImage = pDib->GetDimensions();int nWidth = sizeImage.cx ;int nHeight = sizeImage.cy ;// 图像在计算机在存储中的实际大小CSize sizeImageSave = pDib->GetDibSaveDim();// 图像在内存中每一行象素占用的实际空间int nSaveWidth = sizeImageSave.cx;// 初始化memset(pUnRegion,0,sizeof(unsigned char)*nWidth*nHeight);// 种子点int nSeedX, nSeedY;// 设置种子点为图像的中心nSeedX = nWidth /2 ;nSeedY = nHeight/2 ;// 定义堆栈,存储坐标int * pnGrowQueX ;int * pnGrowQueY ;// 分配空间pnGrowQueX = new int [nWidth*nHeight];pnGrowQueY = new int [nWidth*nHeight];// 图像数据的指针unsigned char * pUnchInput =(unsigned char * )pDib->m_lpImage; // 定义堆栈的起点和终点// 当nStart=nEnd, 表示堆栈中只有一个点int nStart ;int nEnd ;//初始化nStart = 0 ;nEnd = 0 ;// 把种子点的坐标压入栈pnGrowQueX[nEnd] = nSeedX;pnGrowQueY[nEnd] = nSeedY;// 当前正在处理的象素int nCurrX ;int nCurrY ;// 循环控制变量int k ;// 图象的横纵坐标,用来对当前象素的4邻域进行遍历int xx;int yy;while (nStart<=nEnd){// 当前种子点的坐标nCurrX = pnGrowQueX[nStart];nCurrY = pnGrowQueY[nStart];// 对当前点的4邻域进行遍历for (k=0; k<4; k++){// 4邻域象素的坐标xx = nCurrX+nDx[k];yy = nCurrY+nDy[k];// 判断象素(xx,yy) 是否在图像内部// 判断象素(xx,yy) 是否已经处理过// pUnRegion[yy*nWidth+xx]==0 表示还没有处理// 生长条件:判断象素(xx,yy)和当前象素(nCurrX,nCurrY) 象素值差的绝对值if ( (xx < nWidth) && (xx>=0) && (yy<nHeight) && (yy>=0)&& (pUnRegion[yy*nWidth+xx]==0) &&abs(pUnchInput[yy*nSaveWidth+xx] -pUnchInput[nCurrY*nSaveWidth+nCurrX])<nThreshold ){// 堆栈的尾部指针后移一位nEnd++;// 象素(xx,yy) 压入栈pnGrowQueX[nEnd] = xx;pnGrowQueY[nEnd] = yy;// 把象素(xx,yy)设置成逻辑1(255)// 同时也表明该象素处理过pUnRegion[yy*nWidth+xx] = 255 ;}}nStart++;}// 释放内存delete []pnGrowQueX;delete []pnGrowQueY;pnGrowQueX = NULL ;pnGrowQueY = NULL ;}对于2D图象的组织增长,使用递归也是一种不错的选择,但需要注意栈空间需要设大一些。

而在3D数据场上,递归几乎是不可行的,栈空间经常会出现溢出的情况,因此不具备实用性。

2D组织增长伪代码如下组织增长(Image* pImage, int i, ing j, byte* mask){if 不满足增长条件(pImage, i,j, mask)return;设置标记(mask, i, j);组织增长(pImage, i-1, j, mask);组织增长(pImage, i+1, j, mask);组织增长(pImage, i, j-1, mask);组织增长(pImage, i, j+1, mask);}至于将递归程序改为迭代程序,可以看一看《程序设计方法学》区域增长算法区域增长的算法实现: 1)根据图像的不同应用选择一个或一组种子,它或者是最亮或最暗的点,或者是位于点簇中心的点 2...通过像素集合的区域增长算法实现: 区域A 区域B 种子像素增长.3)增长的规则4)结束条件.BOOL RegionGrow(int nSeedX, int nSeedY, BYTE * pUnchInput,int nWidth, int nHeight, BYTE * pUnRegion,CRect &R){int nDx[] = {-1,1,0,0};int nDy[] = {0,0,-1,1};int nSaveWidth = nWidth;// 定义堆栈,存储坐标int * pnGrowQueX ;int * pnGrowQueY ;// 分配空间pnGrowQueX = new int [nWidth*nHeight];pnGrowQueY = new int [nWidth*nHeight];// 定义堆栈的起点和终点// 当nStart=nEnd, 表示堆栈中只有一个点int nStart ;int nEnd ;//初始化nStart = 0 ;nEnd = 0 ;// 把种子点的坐标压入栈pnGrowQueX[nEnd] = nSeedX;pnGrowQueY[nEnd] = nSeedY;// 当前正在处理的象素int nCurrX ;int nCurrY ;// 循环控制变量int k ;// 图象的横纵坐标,用来对当前象素的8邻域进行遍历int xx;int yy;while (nStart<=nEnd){// 当前种子点的坐标nCurrX = pnGrowQueX[nStart];nCurrY = pnGrowQueY[nStart];// 对当前点的4邻域进行遍历for (k=0; k<4; k++){// 4邻域象素的坐标xx = nCurrX+nDx[k];yy = nCurrY+nDy[k];// 判断象素(xx,yy) 是否在图像内部// 判断象素(xx,yy) 是否已经处理过// pUnRegion[yy*nWidth+xx]==0 表示还没有处理// 生长条件:判断象素(xx,yy)和当前象素(nCurrX,nCurrY) 象素值差的绝对值if ( (xx < nWidth) && (xx>=0) && (yy>=0) && (yy<nHeight)&& (pUnRegion[yy*nWidth+xx]==0) &&(pUnchInput[yy*nSaveWidth+xx]==1)){// 堆栈的尾部指针后移一位nEnd++;// 象素(xx,yy) 压入栈pnGrowQueX[nEnd] = xx;pnGrowQueY[nEnd] = yy;// 把象素(xx,yy)设置成逻辑1(255)// 同时也表明该象素处理过pUnRegion[yy*nWidth+xx] = 255 ;}}nStart++;}//找出区域的范围int nMinx=pnGrowQueX[0], nMaxx=pnGrowQueX[0],nMiny=pnGrowQueY[0], nMaxy = pnGrowQueY[0];for (k=0; k<nEnd; k++){if (pnGrowQueX[k] > nMaxx)nMaxx = pnGrowQueX[k];if (pnGrowQueX[k] < nMinx)nMinx = pnGrowQueX[k];if (pnGrowQueY[k] > nMaxy)nMaxy = pnGrowQueY[k];if (pnGrowQueY[k] < nMiny)nMiny = pnGrowQueY[k];}if ((nMaxy - nMiny) > 40 && (nMaxx - nMinx) > 40){R.left = nMinx;R.right = nMaxx;R.top = nMiny;R.bottom = nMaxy;return TRUE;}// 释放内存delete []pnGrowQueX;delete []pnGrowQueY;pnGrowQueX = NULL ;pnGrowQueY = NULL ;return FALSE;}//调用方法void OnButton(LPBYTE S,int ImageWidth,int ImageHeight){int i=0,j=0;CRect rect;LPBYTE lpFlag = new BYTE[ImageWidth*ImageHeight];memset(lpFlag,0,ImageWidth*ImageHeight);for (i=0; i<ImageHeight; i++){for (j=0; j<ImageWidth; j++){if (S[i*ImageWidth+j] == 1 && lpFlag[i*ImageWidth+j] == 0) {RegionGrow(j, i, S, ImageWidth, ImageHeight, lpFlag,rect); }}}if(lpFlag!=NULL){delete []lpFlag;lpFlag = NULL;}}区域增长算法递归实现void RegionGrowTwo(int nSeedX, int nSeedY, BYTE * pUnchInput,BYTE * D, int nWidth, int nHeight, BYTE * pUnRegion,int &iLeft,int & iRight,int & iTop,int & iBottom){int nDx[] = {-1,1,0,0};int nDy[] = {0,0,-1,1};int k=0;int nCurrX ;int nCurrY ;int xx=0,yy=0;nCurrX = nSeedX;nCurrY = nSeedY;if(nCurrX<iLeft)iLeft = nCurrX;if(nCurrX>iRight)iRight = nCurrX;if(nCurrY<iTop)iTop = nCurrY;if(nCurrY>iBottom)iBottom = nCurrY;// pUnRegion[nCurrY*nWidth+nCurrX] = 255 ;// 对当前点的4邻域进行遍历int times = 0;for (k=0; k<4; k++){// 4邻域象素的坐标xx = nCurrX+nDx[k];yy = nCurrY+nDy[k];// 判断象素(xx,yy) 是否在图像内部// 判断象素(xx,yy) 是否已经处理过// pUnRegion[yy*nWidth+xx]==0 表示还没有处理// 生长条件:判断象素(xx,yy)和当前象素(nCurrX,nCurrY) 象素值差的绝对值if ( (xx < nWidth) && (xx>=0) && (yy>=0) && (yy<nHeight)&& (pUnRegion[yy*nWidth+xx]==0) &&(pUnchInput[yy*nWidth+xx]==1)){// 同时也表明该象素处理过pUnRegion[yy*nWidth+xx] = 255 ;if(xx<iLeft)iLeft = xx;if(xx>iRight)iRight = xx;if(yy<iTop)iTop = yy;if(yy>iBottom)iBottom = yy;RegionGrowTwo(xx,yy,pUnchInput,D,nWidth,nHeight,pUnRegion, iLeft,iRight,iTop,iBottom);}elsetimes++;}}/** 区域增长,递归实现* S,源图象D,目标图象ImageWidth,ImageHeight,表示图象的宽、高*/void RegionGrowOne(BYTE *S,BYTE *D,int ImageWidth,int ImageHeight){int iLeft=0,iRight=0,iTop=0,iBottom=0;int k1,k2,k3,k4,ii1=0,off=0;int i=0,j=0;LPBYTE lpFlag = new BYTE[ImageWidth*ImageHeight];memset(lpFlag,0,ImageWidth*ImageHeight);memcpy(D,S,ImageWidth*ImageHeight);for (i=0; i<ImageHeight; i++){for (j=0; j<ImageWidth; j++){if (S[i*ImageWidth+j] == 1 && lpFlag[i*ImageWidth+j] == 0) {iLeft=65535,iRight=0,iTop=65535,iBottom=0;RegionGrowTwo(j,i,S,D,ImageWidth,ImageHeight,lpFlag,iLeft,iRig ht,iTop,iBottom);if((iRight-iLeft)>40 && (iBottom-iTop)>40) //表示区域大于40*40时就画出边框{//画边框k1 = (iLeft -1 )<0 ?0:(iLeft -1 );k2 = (iRight+1)>=ImageWidth?(ImageWidth-1):(iRight+1);k3 = (iTop-1)<0?0:(iTop-1);k4 = (iBottom+1)>=ImageHeight?(ImageHeight-1):(iBottom+1); for(ii1 = k1;ii1 <= k2;ii1++){off = ii1 + k3*ImageWidth;D[off] = 11;off = ii1 + k4*ImageWidth;D[off] = 11;}for(ii1 = k3 ;ii1<=k4;ii1++){off = ii1 * ImageWidth + k1;D[off] = 11;off = ii1 * ImageWidth + k2;D[off] = 11;}/////////////////////////////////////////////////}}}}if(lpFlag!=NULL){delete []lpFlag;lpFlag = NULL;}}求区域生长的源代码!!!楼主zhangfeigreat(大鹏)2004-09-04 10:45:48 在VC/MFC / 图形处理/算法提问本人现在急需这方面的源代码,不知道哪位好心人能提供给我,最好还能附加点说明,呵呵本人将不胜感激!!!先谢了!! 问题点数:20、回复次数:11Top1 楼AlexSu(AlexSu)回复于2004-09-04 13:39:10 得分0我有,你图像是二值的还是灰度的?彩色的或是灰度图像要有区域生长的阈值的来确定的。

相关文档
最新文档