Skip to content

Watershed transform

Monika Pulcová edited this page May 9, 2023 · 5 revisions

One of two used segmentation algorithms

Principle of watershed

watershed image taken from: Wikipedia

This algorithm can divide particles which are partially overlapping. Watershed transform works on principle of gradual flooding of binary mask from small connected regions called seeds. These seeds are difficult to find and there are plenty of possibilities how to do that. According to paper I decided to try perform ultimate erosion, which works on principle of loop with morphological erosion, which ends while roi (one seed) is convex. I did not manage to erode mask into perfect convex shapes, so it ends when different of convex hull and roi is 10 times smaller then size of roi.

Ultimate erosion code example

There is my implementation of ultimate erosion:

seeds = np.zeros(binary.shape, dtype=np.uint8)
        mask = binary.copy()

        while np.sum(mask) > 0:
            regions = erosion(mask)
            regions = label(regions)

            for i in range(1, np.max(regions) + 1):
                roi = regions == i
                convex_hull = convex_hull_image(roi)
                diff = convex_hull != roi
                diff = np.sum(diff.astype(np.float32))
                area = roi.astype(np.float32).sum()
                convex = (diff == 0 or 10 * diff < area) and area > 5 / pixel_size
                if convex:
                    seeds[roi] = 1
                    regions[regions == i] = 0
            mask = regions > 0

        seeds = dilation(seeds)
Clone this wiki locally