I'm trying to separate connected objects. It seems that Python and the watershed algorithm (scipy implementation) are well-suited to handle this.
Here is my image and automatically generated watershed seed points (local maxima of the thresholded and distance-transformed image):
seeds = myGenSeeds( image_grey )
So far, so good; there is a seed for every object.
Things break down when I run the watershed though:
segmented = ndimage.measurements.watershed_ift( 255 - image_grey, seeds)`
Both the top-middle cluster and the centre cluster are poorly separated. In the top cluster, one object flooded around the other two. In the centre cluster, though it might be too small to see here, the centre seed flooded to only a few pixels.
I have two questions:
- Is the watershed algorithm a good choice for separating objects like this?
- If so, is there some sort of pre-processing that I've got do do to make the image more suitable for watershed segmentation?
You should apply the multilevel thresholding method after the distance transform step. The center of your objects will have the highest pixel value in the resulting gray level image after converting the distance conversion image to the gray level image. Here you can find the centers of the objects starting from the highest value of the threshold. Look this paper https://www.researchgate.net/publication/303703322_A_Multi-level_Thresholding_Based_Segmentation_Method_for_Microscopic_Fluorescence_In_Situ_Hybridization_FISH_Images
I found this thread because I am having the same problem with
watershed_ift
. I recommend just using thewatershed
function inskimage.morphology
. It accepts float inputs, so you don't lose resolution on the greyscale image, and it actually floods the entire basin, while theift
approach only seems to flood the isovalues where the markers lie.EDIT: Be sure to multiply your distance transform by -1 so the peaks become valleys, or else you won't get any watersheds!
The watershed algorithm is a simple and robust segmentation algorithm. Your data seems to be okay for that kind of segmentation algorithm. Special preprocessing is not needed as far as I can see. Of course you saw yourself already that in cases it's a bit on the verge.
Watershed is often used but does not take any special knowledge about the objects that you want to identify into account. In that way there might be more sophisticated algorithms available.
Also there might be more sophisticated versions of the watershed algorithm available. This Python module called Watershed 2.0 has parameters (unlike the scipy version). I would tweak the parameters a bit and see if the result can be improved.
Ilastik is a tool often used for automatic segmentation. It incorporates semi-automatic learning (basically you give train it by giving examples and from that it learns the important features).