Image Segmentation in OpenCV Python with Watershed Algorithm

Image segmentation divides an image into distinct regions or objects. The Watershed algorithm is one of the most effective techniques for this task, treating grayscale images like topographical maps where pixel intensities represent elevations.

Understanding the Watershed Algorithm

The Watershed algorithm works by imagining water flowing from local minima (dark regions) until it meets boundaries between different regions. These boundaries become the segmentation lines, effectively separating objects in the image.

Complete Implementation

Here's a complete implementation of image segmentation using the Watershed algorithm ?

import cv2
import numpy as np
import matplotlib.pyplot as plt

# Create a sample image for demonstration
def create_sample_image():
    # Create a simple image with circles
    img = np.zeros((200, 200, 3), dtype=np.uint8)
    cv2.circle(img, (50, 50), 30, (255, 255, 255), -1)
    cv2.circle(img, (150, 50), 25, (255, 255, 255), -1)
    cv2.circle(img, (100, 130), 35, (255, 255, 255), -1)
    return img

# Load or create the image
image = create_sample_image()

# Step 1: Convert to grayscale
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)

# Step 2: Apply thresholding
ret, threshold = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

# Step 3: Remove noise with morphological operations
kernel = np.ones((3, 3), np.uint8)
opening = cv2.morphologyEx(threshold, cv2.MORPH_OPEN, kernel, iterations=2)

# Step 4: Find sure background region
sure_bg = cv2.dilate(opening, kernel, iterations=3)

# Step 5: Find sure foreground region
dist_transform = cv2.distanceTransform(opening, cv2.DIST_L2, 5)
ret, sure_fg = cv2.threshold(dist_transform, 0.7 * dist_transform.max(), 255, 0)

# Step 6: Find unknown region
sure_fg = np.uint8(sure_fg)
unknown = cv2.subtract(sure_bg, sure_fg)

# Step 7: Create markers for watershed
ret, markers = cv2.connectedComponents(sure_fg)
markers = markers + 1
markers[unknown == 255] = 0

# Step 8: Apply Watershed algorithm
markers = cv2.watershed(image, markers)

# Step 9: Visualize the result
result = image.copy()
result[markers == -1] = [0, 0, 255]  # Mark boundaries in red

print("Watershed segmentation completed successfully!")
print(f"Number of segments found: {len(np.unique(markers)) - 1}")

Key Steps Breakdown

Preprocessing

The image is first converted to grayscale and then thresholded to create a binary image. This separates objects from the background ?

import cv2
import numpy as np

# Create sample data
img = np.zeros((100, 100, 3), dtype=np.uint8)
cv2.circle(img, (30, 30), 20, (255, 255, 255), -1)
cv2.circle(img, (70, 70), 15, (255, 255, 255), -1)

# Convert to grayscale
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
print("Grayscale conversion completed")
print(f"Original shape: {img.shape}, Grayscale shape: {gray.shape}")
Grayscale conversion completed
Original shape: (100, 100, 3), Grayscale shape: (100, 100)

Marker Creation

The algorithm requires markers to identify different regions. These are created using distance transform and morphological operations ?

import cv2
import numpy as np

# Create binary image
img = np.zeros((50, 50), dtype=np.uint8)
img[10:20, 10:20] = 255
img[30:40, 30:40] = 255

# Apply distance transform
dist = cv2.distanceTransform(img, cv2.DIST_L2, 5)
print("Distance transform applied")
print(f"Max distance value: {dist.max():.2f}")
print(f"Distance transform shape: {dist.shape}")
Distance transform applied
Max distance value: 7.07
Distance transform shape: (50, 50)

Advantages and Applications

Advantage Description Best Use Case
Accurate Boundaries Precisely identifies object boundaries Medical imaging, cell counting
Handles Overlapping Objects Separates touching or overlapping objects Particle analysis
Robust to Noise Works well with preprocessed images Industrial inspection

Common Parameters

Key parameters that affect segmentation quality ?

  • Kernel size: Affects noise removal (typically 3x3 or 5x5)
  • Distance threshold: Controls foreground region detection (0.6-0.8 of max distance)
  • Morphological iterations: Number of opening/closing operations (2-3 usually sufficient)

Conclusion

The Watershed algorithm provides robust image segmentation by treating images as topographical surfaces. It excels at separating overlapping objects and creating precise boundaries, making it ideal for medical imaging, industrial inspection, and object counting applications.

Updated on: 2026-03-27T09:54:59+05:30

2K+ Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements