Watershed Segmentation Example

This example shows how to use the watershed on an image to make a segmentation.

The watershed segmentation is based on the usage of an image as a landscape, where each minimum is a basin of a lake. It simulates the filling of these basins and where two basins meet, it make a watershed line.

Meyer’s watershed from local minima

First, we import the modules needed to use it

from pylena import morpho
from skimage.data import camera
import matplotlib.pyplot as plt
import numpy as np

We first get an image

img = camera()

We compute the gradient

se = morpho.make_structuring_element_2d("disc", 2)
grad = morpho.gradient(img, se)

plt.figure(figsize=(8, 8))
plt.imshow(grad, cmap="gray")
plt.xticks([])
plt.yticks([])
plt.show()
example watershed

Then, we compute the watershed on this gradient.

ws, nlabel = morpho.watershed(img, 8)
print(f"Number of label: {nlabel}")
Number of label: 13563

We finally illustrate the resulting segmentation

np.random.seed(0)
color = np.random.randint(low=0, high=255, size=(np.max(ws) + 1, 3))
color[0, :] = 0  # Watershed lines are illustrated in black
colorized = color[ws]

plt.figure(figsize=(8, 8))
plt.imshow(colorized)
plt.xticks([])
plt.yticks([])
plt.show()
example watershed

The disadvantage of the watershed from local minima is the fact it over-segments the image. To solve this issue, it may be useful to provide some markers from which the watershed will start the flooding

Watershed segmentation from user markers

First, we provide the input markers.

markers = np.zeros(img.shape, dtype=np.int16)
markers[200:400, 100] = 1
markers[250:480, 450] = 1
markers[50, 50:450] = 1

Then, we compute the watershed from markers.

ws2, nlabel2 = morpho.watershed(img, 8, markers=markers)

Finally we illustrate

color2 = np.random.randint(low=0, high=255, size=(np.max(ws2) + 1, 3))
color2[0, :] = 0  # Watershed lines are illustrated in black
colorized2 = color2[ws2]

markers = morpho.dilation(markers.astype(np.uint8), se)
markers_illustration = np.zeros((img.shape[0], img.shape[1], 3), dtype=np.uint8)
markers_illustration[markers > 0, 0] = 255

plt.figure(figsize=(12, 6))
plt.subplot(121)
plt.title("Markers")
plt.imshow(markers_illustration)
plt.subplot(122)
plt.title("Watershed by markers")
plt.imshow(colorized2)
plt.tight_layout()
plt.show()
Markers, Watershed by markers

Total running time of the script: (0 minutes 0.565 seconds)

Gallery generated by Sphinx-Gallery