Why this simple case of watershed segmentation fails?

(Cross-posted on Wolfram Community)

I tried a simple experiment today with WatershedComponents. I took this image from: https://fr.mathworks.com/help/images/ref/watershed.html

I cropped the image img to remove the border

then i binarized the image

bin = Binarize[img];


the distance transform of the image yields dist:

dist = DistanceTransform[bin]//ImageAdjust;


Now to determine the seeds:

seeds = MaxDetect[dist]; (* notice two nice seeds in the image *)


finally using WatershedComponents i get this:

WatershedComponents[bin, seeds] // Colorize


Note: This is clearly how they should not be segmented. In contrast please see the segmentation performed by Matlab (link mentioned above). I tried using different methods but could not get a proper segmentation. Why is the background being labelled in the output? What am i doing wrong?

• What version of Mathematica are you using? I'm getting this on 11.1. In principle, even with your solution you can just multiply the result with your binary image to get a segmentation that separates the two blobs. – halirutan Nov 20 '17 at 17:52
• The Matlab code you linked does something different: L = watershed(D); L(~bw) = 0; - this passes the distance transform to the watershed function, not the binary image. And it sets the labels outside the binary mask to 0. I think that explains the different results. – Niki Estner Nov 20 '17 at 18:16
• @halirutan oddly enough if I use the image from the link and crop it myself and run the code I get the same answer that I posted above. However, if I use the img (with borders cropped) posted in the question I get what you get. Try and let me know. I am using 11.2 – Ali Hashmi Nov 20 '17 at 19:35
• @nikie i think WatershedComponents allows the user to pass markers as the second parameters. I expect the markers to grow from inside out until the expanding seeds touch (filling only the white pixels and not touching the background). There is no background in the final output which is what is confusing me. The background is being labelled which should not be the case ! – Ali Hashmi Nov 20 '17 at 19:39
• WatershedComponents basically fills basins starting at the seed points, until the whole image is filled. I think the output you see is exactly what it should be. If you want the background to be unlabeled, you have to remove the labels in the background yourself. That's what the Matlab code does, too. – Niki Estner Nov 20 '17 at 19:51

In the matlab example, D is the distance transform of the complement of the binary image. Next the complement of the transform is stored in D, and it is this image what is passed to watershed. In your code, bin contains the original, binarized image. Also mentioned by @halirutan, the results of the watershed are masked by the original image in the matlab code (D(~bw) = Inf) so the same should be done in Mathematica.
img = Import@"https://i.stack.imgur.com/4QcDM.png";