Search code examples
pythonimage-segmentationscikit-imagewatershed

How to import Skimage to segment an image with watershed?


I'm trying to use Skimage to segment an image with watershed, but I always get this error. Do you have a solution please?

AttributeError: module 'skimage.morphology' has no attribute 'watershed'

Source code : https://scikit-image.org/docs/0.12.x/auto_examples/xx_applications/plot_coins_segmentation.html

import numpy as np
import matplotlib.pyplot as plt
import cv2

from skimage.feature import canny
from scipy import ndimage as ndi
from skimage import morphology
from skimage.filters import sobel
from skimage import data
from skimage.color import label2rgb


coins = data.coins()
hist = np.histogram(coins, bins=np.arange(0, 256))

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(8, 3))
ax1.imshow(coins, cmap=plt.cm.gray, interpolation='nearest')
ax1.axis('off')
ax2.plot(hist[1][:-1], hist[0], lw=2)
ax2.set_title('histogram of grey values')

    # Threshold
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(6, 3), sharex=True, sharey=True)
ax1.imshow(coins > 100, cmap=plt.cm.gray, interpolation='nearest')
ax1.set_title('coins > 100')
ax1.axis('off')
ax1.set_adjustable('box')
ax2.imshow(coins > 150, cmap=plt.cm.gray, interpolation='nearest')
ax2.set_title('coins > 150')
ax2.axis('off')
ax2.set_adjustable('box')
margins = dict(hspace=0.01, wspace=0.01, top=1, bottom=0, left=0, right=1)
fig.subplots_adjust(**margins)


elevation_map = sobel(coins)

fig, ax = plt.subplots(figsize=(4, 3))
ax.imshow(elevation_map, cmap=plt.cm.gray, interpolation='nearest')
ax.axis('off')
ax.set_title('elevation_map')

markers = np.zeros_like(coins)
markers[coins < 30] = 1
markers[coins > 150] = 2

fig, ax = plt.subplots(figsize=(4, 3))
ax.imshow(markers, cmap=plt.cm.Spectral, interpolation='nearest')
ax.axis('off')
ax.set_title('markers')


segmentation = morphology.watershed(elevation_map, markers)

fig, ax = plt.subplots(figsize=(4, 3))
ax.imshow(segmentation, cmap=plt.cm.gray, interpolation='nearest')
ax.axis('off')
ax.set_title('segmentation')


segmentation = ndi.binary_fill_holes(segmentation - 1)
labeled_coins, _ = ndi.label(segmentation)
image_label_overlay = label2rgb(labeled_coins, image=coins)

fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(6, 3), sharex=True, sharey=True)
ax1.imshow(coins, cmap=plt.cm.gray, interpolation='nearest')
ax1.contour(segmentation, [0.5], linewidths=1.2, colors='y')
ax1.axis('off')
ax1.set_adjustable('box')
ax2.imshow(image_label_overlay, interpolation='nearest')
ax2.axis('off')
ax2.set_adjustable('box')

fig.subplots_adjust(**margins)

plt.show()

Error on line : segmentation = morphology.watershed(elevation_map, markers)


Solution

  • You are for some reason looking at the old documentation for scikit-image, version 0.12. (See the 0.12.x in the URL that you shared.) You can look at the examples for the latest released version at:

    https://scikit-image.org/docs/stable/auto_examples/

    Concretely for your code, you need to update the import to from skimage.segmentation import watershed.