分水岭分割

分水岭是一种经典算法,用于 分段 也就是说,用于分离图像中的不同对象。

从用户定义的标记开始,分水岭算法将像素值视为局部地形(高程)。该算法从标记泛洪流域,直到属于不同标记的流域在分水岭上相遇。在许多情况下,标记被选为图像的局部最小值,从中淹没盆地。

在下面的例子中,两个重叠的圆将被分开。要做到这一点,需要计算一幅图像,即到背景的距离。选择该距离的最大值(即,距离的相反的最小值)作为标志,从这些标志中泛滥的盆地沿着分水岭线将两个圆分开。

看见 Wikipedia 以获取有关该算法的更多详细信息。

Overlapping objects, Distances, Separated objects
import numpy as np
import matplotlib.pyplot as plt
from scipy import ndimage as ndi

from skimage.segmentation import watershed
from skimage.feature import peak_local_max


# Generate an initial image with two overlapping circles
x, y = np.indices((80, 80))
x1, y1, x2, y2 = 28, 28, 44, 52
r1, r2 = 16, 20
mask_circle1 = (x - x1)**2 + (y - y1)**2 < r1**2
mask_circle2 = (x - x2)**2 + (y - y2)**2 < r2**2
image = np.logical_or(mask_circle1, mask_circle2)

# Now we want to separate the two objects in image
# Generate the markers as local maxima of the distance to the background
distance = ndi.distance_transform_edt(image)
coords = peak_local_max(distance, footprint=np.ones((3, 3)), labels=image)
mask = np.zeros(distance.shape, dtype=bool)
mask[tuple(coords.T)] = True
markers, _ = ndi.label(mask)
labels = watershed(-distance, markers, mask=image)

fig, axes = plt.subplots(ncols=3, figsize=(9, 3), sharex=True, sharey=True)
ax = axes.ravel()

ax[0].imshow(image, cmap=plt.cm.gray)
ax[0].set_title('Overlapping objects')
ax[1].imshow(-distance, cmap=plt.cm.gray)
ax[1].set_title('Distances')
ax[2].imshow(labels, cmap=plt.cm.nipy_spectral)
ax[2].set_title('Separated objects')

for a in ax:
    a.set_axis_off()

fig.tight_layout()
plt.show()

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

Gallery generated by Sphinx-Gallery