Mahotas - Conditional Watershed of Image



The term "watershed" is derived from the concept of a physical watershed, which is the boundary line separating different drainage basins. Similarly, the watershed algorithm aims to find boundaries or regions of separation in an image.

The watershed algorithm is a popular method used for image segmentation, which is the process of dividing an image into different regions.

Therefore, in image processing, a watershed image refers to an image that has undergone a process called watershed segmentation.

The watershed segmentation technique treats the pixel intensities in the image as a topographic surface, where the bright areas represent high elevations and the dark areas represent low elevations.

Watershed in Mahotas

Mahotas provides the conditional watershed function instead of the traditional watershed algorithm.

The conditional watershed in Mahotas is an enhanced version of the watershed algorithm that allows us to guide the segmentation process by providing specific markers.

Let us see the step−by−step procedure of how conditional watershed algorithm works in Mahotas −

Step 1 − Imagine we have an image and we want to divide it into different regions. With conditional watershed, we can mark certain areas in the image as markers that represent the regions we are interested in.

Step 2 − The algorithm then starts by filling these marked areas with water. The water will only flow within each marked region and won't cross the boundaries of other markers.

Step 3 − The result is a segmented image where each region is delineated by the boundaries defined by the markers you provided.

The mahotas.cwatershed() function

The cwatershed() function in Mahotas takes two inputs− the input image and a marker image, and returns an an output image which is segmented into distinct regions.

The marker image is a binary image where the foreground pixels (Boolean value 1) represent the boundaries for different regions.

Syntax

Following is the basic syntax of cwatershed() function in mahotas −

mahotas.cwatershed(surface, markers, Bc=None, return_lines=False) W, WL =
cwatershed(surface, markers, Bc=None, return_lines=True)

Parameters

The parameters accepted by the cwatershed() function is as follows −

  • surface − It represents the input image on which watershed segmentation will be performed. It is usually a grayscale image.

  • markers − It represents the markers for the watershed segmentation. The markers indicate regions of interest in an image.

  • Bc (optional) − It represents the structuring element used for neighborhood operations. If set to None, a default connectivity is used.

  • return_lines − It is a boolean flag that specifies whether to return the watershed lines in addition to the labeled image. If True, the function returns both the labeled image and the watershed lines.

    If False, only the labeled image is returned. By default, it is set to False.

Return Values

  • W or WL − It represents the labeled image obtained from the watershed segmentation, where each region is assigned a unique label. The shape of the labeled image is the same as the input image.

  • WL (optional) − This is only returned when return_lines parameter is set to True. It represents the watershed lines, which are the boundaries between the segmented regions in the image.

Example

In the following example, we are trying to display the basic conditional watershed segmentation of an image −

import mahotas as mh
import matplotlib.pyplot as plt
# Loading the input image
image = mh.imread('sea.bmp')
# Creating markers or seeds
markers = mh.imread('tree.tiff')
# Perform conditional watershed segmentation
segmented_image = mh.cwatershed(image, markers)
# Display all three images in one plot
plt.figure(figsize=(10, 5))
# Display image1
plt.subplot(1, 3, 1)
plt.imshow(image)
plt.title('Sea')
plt.axis('off')
# Display image2
plt.subplot(1, 3, 2)
plt.imshow(markers)
plt.title('Tree')
plt.axis('off')
# Display the segmented image
plt.subplot(1, 3, 3)
plt.imshow(segmented_image, cmap='gray')
plt.title('Segmented Image')
plt.axis('off')
plt.tight_layout()
plt.show()

Output

The output produced is as follows −

Watershed Image Mohatas

Conditional Watershed with Custom Structuring Element

A structuring element is a small binary image commonly represented as a matrix. It is used to analyze the local neighborhood of a reference pixel.

In the context of conditional watershed, a custom structuring element allows us to define the connectivity between pixels during the watershed process.

By customizing the structuring element, we can control how the the neighborhood of each pixel influences segmentation of an image.

Example

import mahotas as mh
import numpy as np
from pylab import imshow, show
# Load the image
image = mh.imread('nature.jpeg')
# Convert the image to grayscale
image_gray = mh.colors.rgb2grey(image).astype(np.uint8)
# Threshold the image
threshold = mh.thresholding.otsu(image_gray)
image_thresholded = image_gray > threshold
# Perform conditional watershed with custom structuring element
struct_element = np.array([[0, 1, 0], [1, 1, 1], [0, 1, 0]])
labels, _ = mh.label(image_thresholded, struct_element)
watershed = mh.cwatershed(image_gray.max() - image_gray, labels)
# Show the result
imshow(watershed)
show()

Output

Output of the above code is as follows −

Watershed Image Mohatas1
Advertisements