分割和超像素算法的比较#

此示例比较了四种流行的低级图像分割方法。由于很难获得良好的分割,并且“良好”的定义通常取决于应用程序,因此这些方法通常用于获得过度分割,也称为超像素。然后,这些超像素将作为更复杂的算法(例如条件随机场 (CRF))的基础。

Felzenszwalb 的高效基于图的分割#

该快速二维图像分割算法在 [1] 中提出,在计算机视觉界很受欢迎。该算法具有单个 scale 参数,该参数会影响分割大小。实际的分割大小和数量可能会因局部对比度而异。

快速移位图像分割#

快速移位是一种相对较新的二维图像分割算法,它基于核化均值漂移的近似值。因此,它属于局部模式搜索算法族,并应用于由颜色信息和图像位置组成的 5D 空间 [2]

快速移位的好处之一是它实际上可以同时在多个尺度上计算分层分割。

快速移位有两个主要参数:sigma 控制局部密度近似的尺度,max_dist 选择生成的分层分割中的级别。颜色空间中的距离和图像空间中的距离之间也存在权衡,由 ratio 给出。

SLIC - 基于 K 均值的图像分割#

该算法只是在颜色信息和图像位置的 5d 空间中执行 K 均值,因此与快速移位密切相关。由于聚类方法更简单,因此它非常高效。此算法必须在 Lab 颜色空间中工作才能获得良好的结果。该算法迅速兴起,现在得到广泛使用。有关详细信息,请参见 [3]compactness 参数在颜色相似度和接近度之间进行权衡,就像快速移位的情况一样,而 n_segments 为 K 均值选择中心的数量。

梯度图像的紧凑分水岭分割#

分水岭不是采用彩色图像作为输入,而是需要灰度梯度图像,其中亮像素表示区域之间的边界。该算法将图像视为景观,其中亮像素形成高山峰。然后,从给定的标记开始淹没此景观,直到单独的洪水盆地在山峰处汇合。然后,每个不同的盆地形成不同的图像片段。[4]

与 SLIC 一样,还有一个额外的紧凑度参数,它使标记更难淹没远处的像素。这使得分水岭区域的形状更加规则。[5]

Felzenszwalbs's method, SLIC, Quickshift, Compact watershed
Felzenszwalb number of segments: 194
SLIC number of segments: 196
Quickshift number of segments: 695
Watershed number of segments: 256

import matplotlib.pyplot as plt
import numpy as np

from skimage.data import astronaut
from skimage.color import rgb2gray
from skimage.filters import sobel
from skimage.segmentation import felzenszwalb, slic, quickshift, watershed
from skimage.segmentation import mark_boundaries
from skimage.util import img_as_float

img = img_as_float(astronaut()[::2, ::2])

segments_fz = felzenszwalb(img, scale=100, sigma=0.5, min_size=50)
segments_slic = slic(img, n_segments=250, compactness=10, sigma=1, start_label=1)
segments_quick = quickshift(img, kernel_size=3, max_dist=6, ratio=0.5)
gradient = sobel(rgb2gray(img))
segments_watershed = watershed(gradient, markers=250, compactness=0.001)

print(f'Felzenszwalb number of segments: {len(np.unique(segments_fz))}')
print(f'SLIC number of segments: {len(np.unique(segments_slic))}')
print(f'Quickshift number of segments: {len(np.unique(segments_quick))}')
print(f'Watershed number of segments: {len(np.unique(segments_watershed))}')

fig, ax = plt.subplots(2, 2, figsize=(10, 10), sharex=True, sharey=True)

ax[0, 0].imshow(mark_boundaries(img, segments_fz))
ax[0, 0].set_title("Felzenszwalbs's method")
ax[0, 1].imshow(mark_boundaries(img, segments_slic))
ax[0, 1].set_title('SLIC')
ax[1, 0].imshow(mark_boundaries(img, segments_quick))
ax[1, 0].set_title('Quickshift')
ax[1, 1].imshow(mark_boundaries(img, segments_watershed))
ax[1, 1].set_title('Compact watershed')

for a in ax.ravel():
    a.set_axis_off()

plt.tight_layout()
plt.show()

脚本的总运行时间: (0 分钟 3.103 秒)

由 Sphinx-Gallery 生成的图库