分水岭算法的详细介绍(附c代码)

本文详细介绍了分水岭算法的概念,探讨其在图像处理中的应用,并提供了C语言实现代码示例。
摘要由CSDN通过智能技术生成

分水岭算法(Watershed Algorithm)

所谓分水岭算法有好多种实现算法,拓扑学,形态学,浸水模拟和降水模拟等方式。要搞懂就不容易了。Watershed Algorithm(分水岭算法),顾名思义,就是根据分水岭的构成来考虑图像的分割。现实中我们可以或者说可以想象有山有湖的景象,那么那一定是水绕山,山围水的情形。当然在需要的时候,要人工构筑分水岭,以防集水盆之间的互相穿透。而区分高山(plateaus)与水的界线,以及湖与湖之间的间隔或都是连通的关系,就是我们可爱的分水岭(watershed)。为了得到一个相对集中的集水盆,那么让水涨到都接近周围的最高的山顶就可以了,再涨就要漏水到邻居了,而邻居,嘿嘿,水质不同诶,会混淆自我的。那么这样的话,我们就可以用来获取边界灰阶大,中间灰阶小的物体区域了,它就是集水盆。
浸水法,就是先通过一个适当小的阈值得到起点,即集水盆的底;然后是向周围淹没也就是浸水的过程,直到得到分水岭。当然如果我们要一直淹没到山顶,即是一直处理到图像灰阶最高片,那么,当中就会出现筑坝的情况,不同的集水盆在这里想相遇了,我们要洁身自爱,到这里为止,因为都碰到边界了;那么即使在相遇时没有碰到最高灰阶的地方,也需要人工构筑分水岭,区分不同的区域。不再上山。构筑属于自己的分水岭在计算机图形学中,可利用灰度表征地貌高。图像中我们可以利用灰度高与地貌高的相似性来研究图像的灰度在空间上的变化。这是空域分析,比如还可以通过各种形式的梯度计算以得到算法的输入,进行浸水处理。分水岭具有很强的边缘检测能力,对微弱的边缘也有较好的效果。这与分水岭扩张的阈值的设置有关系,阈值可以决定集水盆扩张的范围。但自我构筑的能力却不受影响。为会么这么说呢?为什么有很强的边缘检测能力,而又能得到相对集中的连通的集水盆?现实中很好办,我们在往凹地加水的时候,直到它涨到这一块紧凑的山岭边缘就不加了;但是如果有一条小山沟存在,那没办法,在初始阈值分割的时候,也就是山沟与集水盆有同样的极小值,而且它们之间是以这个高度一直连接的。那没关系,我们将它连通。在图像上呢?如何实现?看看算法,算法思想是这样的:首先准备好山和初始的水。这山就是我们的初始图像了,比如用自然获取的图像的梯度来表征山地的每一点的高度吧;而初始的水就是在阈值记为Thre底下,所有的低于这个高度的整个山地都加水,直到这个阈值Thre高度。从而有三个初始量:unsigned char** Ori_image、char** Seed_image和int** Label_image。最后一个是为最终的结果做准备的。当然要做好初始化,比如,Ora_image赋值为原图像(256色灰度图)的梯度值,Seed_image则是初始状态下有水的置位,无水的复位,而Label_image则全初始化为0,最终得到的是各点对应的区域号
接下来是考虑将已加的水进行记录,记录成连通的区域,也就是看看有多少个互不相关的集水盆,有五个,那么我们就涨出五个湖,而且尽可能的高,只要大家想到不溢出。在算法上,有多少个连通的区域就记录成多少个数据结构,工夫就在于如何将这些连通的区域连接成一块,并由一个数据结构来表达了。很好,我们准备用一个向量容器来实现初始保存,保存所有标记区域种子队列的数组,里面放的是种子队列的指针vector<queue<POINT>*> vque; ,而且这个队列是由一系列属于同一个区域的图像点组成,我们来自一个集水盆:);其保存方式是这样的:queue<point> *pque=new queue<point>[256];vque.push_back(pque),这样便将一个成员放进到这个区域来了,即容器--集水盆的保管都,容器中的每个指针,都指向一个集水盆,也就是我们要的连通区域;所以我们可以方便地由这个容器数据结构直接读值的方便性进行操作,一个脚标就可以得到一个区域(队列指针)的指针;而每个队列还不简单,并不是一列整形数那么易搞,所以说啊,这个算法,真头痛,这个队列的一个成员是一个点;而注意到vque里存放的一256个队列的的起始指针,真够残忍的。也就是说vque [m] [n]就表达了一个队列,这个队列里可以存储操作一系列的点;显然容量取256是因为所有的初始或者是最终的区域中可能有0-256之间的不同的灰阶的点,那么我一个区域分用256个队列来记录这些成员点啦,很有可能,这里就只有一个集水盆,那么,256个灰阶的点都存在一个区域就有可能了统计初始连通区域的方法是,八连通邻域法(还有其他方法:四连通域,六连通域),即从逐一扫描输入的Seed_image的每个像素点,将所有的标记了的初始集水盆一一纳入各自的区域,这是整修图像的扫描,形成外循环。先创建一个临时队列quetem,用来处理当前初始集水盆的连通连接,将逐一扫描到的属于一个特定的初始集水盆区域的可生长点暂存,并形成一个内循环。对当前扫描点的处理是,首先判断该点是否为某个初始集水盆的点,如果不是跳过;接下来是,如果是初始集水盆的点,那么它的八连通域中是否存在不可生长的点(这里的不可生长是指Seed_image中没有标记的点),扫描的八连通邻域中的点是可生长的,即有标记的,则将之加入到临时队列中que

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值