基于区域和基于边缘的图像分割

1、图像分割的概念

图像分割是将图像分割成不同的区域或类别,并使这些区域或类别对应于不同的目标或者局部目标。每个区域包含具有相似属性的像素,并且图像中的每个像素都分配给这些类别之一。一个好的图像分割通常指同一类别的像素具有相似的强度值并形成一个连通区域,而相邻的不同类别的像素具有不同的值。分割技术可以是非上下文的(不考虑图像中特征和组像素之间的空间关系,只考虑一些全局属性,例如颜色或灰度值),也可以是上下文的(另外利用空间关系,例如对具有相似灰度的空间封闭像素分组)。

从分割的技术来说,图像分割方法主要分为两类:1.基于区域的方法:通过利用图像中同一区域的均匀性来识别不同的区域。2.基于边缘的方法:基本思路为先确定不同区域的边缘像素,然后将这些边缘像素连接起来,形成不同的分割区域。

2、基于边缘的图像分割方法

2.1 边缘检测分割

在本例中,我们将尝试使用基于边缘的分割来描绘硬币的轮廓。为此,先使用Canny边缘检测器获取特征的边缘,如下面的代码所示:

edges = canny(coins, sigma=2)
fig, axes = pylab.subplots(figsize=(10, 6))
axes.imshow(edges, cmap=pylab.cm.gray, interpolation='nearest')
axes.set_title('Canny detector'), axes.axis('off'), pylab.show()

运行上述代码,使用Canny边缘检测器得到的硬币轮廓如图所示:

然后使用scipy ndimage模块中的形态学函数binary_fill_holes()填充这些轮廓,如下面的代码所示:

from scipy import ndimage as ndi
fill_coins = ndi.binary_fill_holes(edges)
fig, axes = pylab.subplots(figsize=(10, 6))
axes.imshow(fill_coins, cmap=pylab.cm.gray, interpolation='nearest')
axes.set_title('filling the holes'), axes.axis('off'), pylab.show()

可以看得出这种方法并不是很健壮,因为没有完全闭合的轮廓没有被正确填充,如上图中还有一枚没有填充的硬币一样。

2.2 阈值分割

阈值分割主要运用于灰度图像的分割。如果一张灰度图中目标和背景之间的灰度值有差异,则可以通过阈值分割的方法把图中的目标和背景分开。如果只选取一个阈值的分割被称为单阈值分割,会将图像分割成目标和背景两部分;如果选取多个阈值的分割被称为多阈值分割,会将图形分割成多个区域。
这种阈值方法很常见的应用就是二值化,优点是:简单,通常运用在图像预处理阶段,如在CT图像中对于肺部组织的提取等。当然缺点也比较突出:对于多通道图像,特征值相差不大的图像,或者灰度值范围有较大重叠的图像分割效果较差。

在此特地提出大津法,二值化方法使用这么久一直都没有研究最合适的阈值选取问题,大津法(OTSU)是一种确定图像二值化分割阈值的算法,由日本学者大津于1979年提出。从大津法的原理上来讲,该方法又称作最大类间方差法,因为按照大津法求得的阈值进行图像二值化分割后,前景与背景图像的类间方差最大。
大津法本质就是将1-255的阈值逐一尝试,可以参考大津法

3、基于区域的图像分割方法

3.1 形态学分水岭算法

任何灰度图像都可以看作一个地形地貌面。如果这个面从它的最小值被淹没,并且阻止了不同来源的水的汇合,那么图像就被分割成两个不同的集合,即集水盆和分水岭线。如果将这种变换应用于图像梯度,在理论上集水盆应与图像的同质的灰度区域(片段)相对应。

然而,在实际应用中,由于梯度图像中存在噪声或局部不规则性,使用变换会对图像进行过度分割。为了防止过度分割,使用一组预定义标记,并从这些标记开始对地表面进行注水淹没。因此,通过分水岭变换分割图像的步骤如下:
(1)找到标记和分割准则(用于分割区域的函数,通常是图像对比度/梯度);
(2)利用这两个元素运行标记控制的分水岭算法。
现在,使用scikit-image中的形态学分水岭算法实现从图像的背景中分离出前景硬币。首先,使用图像的sobel梯度找到图像的高程图,如下面的代码所示:

elevation_map = sobel(coins)
fig, axes = pylab.subplots(figsize=(10, 6))
axes.imshow(elevation_map, cmap=pylab.cm.gray, interpolation='nearest')
axes.set_title('elevation map'), axes.axis('off'), pylab.show()

运行上述代码,输出高程图,如图所示:

紧接着,基于灰度值直方图的极值部分,计算背景标记和硬币标记,如下面的代码所示:

markers = np.zeros_like(coins)
markers[coins < 30] = 1
markers[coins > 150] = 2
print(np.max(markers), np.min(markers))
fig, axes = pylab.subplots(figsize=(10, 6))
a = axes.imshow(markers, cmap=plt.cm.hot, interpolation='nearest')
plt.colorbar(a)
axes.set_title('markers'), axes.axis('off'), pylab.show()

最后,利用分水岭变换,从确定的标记点开始注入高程图的区域,如下面的代码所示:

segmentation = morphology.watershed(elevation_map, markers)
fig, axes = pylab.subplots(figsize=(10, 6))
axes.imshow(segmentation, cmap=pylab.cm.gray, interpolation='nearest')
axes.set_title('segmentation'), axes.axis('off'), pylab.show()

运行上述代码,输出使用形态学分水岭算法进行分割后所得到的二值图像,如图所示。

3.2 区域生长算法

主要是参考的博客 区域增长算法
基于区域的分割方法
感觉在具体使用过程中,使用方法与聚类思想非常类似:1、区域生长:区域生长的基本思想是将具有相似性质的像素集中起来构建成分割区域。先确定种子点,再由种子点不断地向四周扩张生成;2、区域合并:区域合并可以看做区域生长的逆向过程,从整个图像出发,不断分割出子区域;直观上就是图片所有像素都有label,然后对临近的label进行合并;3、区域分裂合并:综合以上两种手段吧。

Original: https://blog.csdn.net/NCU_wander/article/details/123692689
Author: NCU_wander
Title: 基于区域和基于边缘的图像分割

原创文章受到原创版权保护。转载请注明出处:https://www.johngo689.com/632703/

转载文章受原作者版权保护。转载请注明原作者出处!

(0)

大家都在看

亲爱的 Coder【最近整理,可免费获取】👉 最新必读书单  | 👏 面试题下载  | 🌎 免费的AI知识星球