[SciPy-User] watershed question

Emmanuelle Gouillart emmanuelle.gouillart@normalesup....
Sun Apr 25 07:34:45 CDT 2010


	Dear Scipy users,

	I'm wondering if any of you is familiar with
ndimage.watershed_ift and could provide a usage example. I'm asking this
because my attempts to use this function yield quite counter-intuitive
results compared to what I understand of the watershed algorithm, or what
Matlab's watershed function returns for the same problem.  

	Below is an example of what I'm trying to do; I would like to
separate connected objects along constrictions. In the example, I create
two overlapping circles that I would like to separate with the watershed
transform. To do so, I perform the watershed transform of the opposite
of the distance transform (distance to the background of the objects)
with markers located at the minima of the negative distance transform. 

	I would expect the watershed transform to separate the connected
circles along the constriction, as Matlab does (see
http://sd-2116.dedibox.fr/scipy_examples/watershed_matlab.png), but
instead, it seems that the marker with the smallest (positive) distance
completely "invades" the basin of the marker with the greatest distance
to the background. A picture of what I obtain can be found on 
http://sd-2116.dedibox.fr/scipy_examples/watershed_example.png,
and below is the code that computes the watershed

**********
import numpy as np
from scipy import ndimage

# initial image: two overlapping circles
x, y = np.indices((40, 40))
x1, y1, x2, y2 = 14, 14, 22, 26
r1, r2 = 8, 10
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)
# Use distance transform to perform watershed segmentation
distance = ndimage.distance_transform_bf(image)

# Markers array: two markers located at each circle's center;
# negative markers are background markers 
markers = np.zeros_like(image).astype(np.int8)
markers[distance==0] = -1
markers[x1, y1] = 1
markers[x2, y2] = 2

# ndimage.watershed_ift needs np.uint8 or np.uint16 as input dtype
distance = -distance
distance -= distance.min()
distance = (255*distance/distance.max()).astype(np.uint8)

# Compute watershed transform
ws = ndimage.watershed_ift(distance, markers.astype(np.int8))
***********

>>> (ws == 1).sum()
474
>>> (ws == 2).sum()
1


Is it a bug that the watershed transform doesn't separate regions along
the ridges of the array 'distance'? Am I doing something wrong? 

Any comments will be very welcome.

Thanks in advance,

Emmanuelle


More information about the SciPy-User mailing list