Open In App

Image segmentation using Morphological operations in Python

Last Updated : 05 Aug, 2025
Comments
Improve
Suggest changes
6 Likes
Like
Report

Segmentation is the process of dividing an image into meaningful regions to separate objects from the background for further analysis. This is often achieved by applying morphological operations which is a shape-based techniques primarily performed on binary images.

Among these, dilation and erosion are two fundamental operators used to refine object boundaries and remove noise within segmented regions.

Step 1: Import the required libraries

Import Numpy, OpenCV and Matplotlib.

Python
import numpy as np
import cv2
from matplotlib import pyplot as plt
from google.colab import files

Step 2: Upload and Decode the Image

Upload an image file and convert the raw file data into an image array for processing.

Python
uploaded = files.upload()
for file in uploaded.keys():
    img = cv2.imdecode(np.frombuffer(
        uploaded[file], np.uint8), cv2.IMREAD_COLOR)

Step 3: Convert to Greyscale and Blur

  • Convert the image to grayscale for easier processing.
  • Use Gaussian blur to reduce noise and help with more accurate segmentation.
Python
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
blurred = cv2.GaussianBlur(gray, (5, 5), 0)

Step 4: Apply OTSU's Thresholding

OTSU's thresholding is an automatic method that determines the optimal threshold value to separate the foreground and background in a grayscale image by maximizing the difference between the two classes.

  • Automatically binarize the image to separate foreground (objects) from background.
  • Display the binary image using matplotlib.
Python
ret, thresh = cv2.threshold(
    gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)
plt.imshow(thresh, cmap='gray')
plt.axis('off')
plt.show()

Output:

taj
OTSU's Thresholding

Step 5: Morphological Closing and Background Dilation

  • Perform closing to fill small holes and unify nearby regions.
  • Dilate the closed image to further expand object areas and clarify boundaries.
Python
kernel = np.ones((9, 9), np.uint8)
closing = cv2.morphologyEx(thresh, cv2.MORPH_CLOSE, kernel, iterations=3)

bg = cv2.dilate(closing, kernel, iterations=2)

Step 6: Contour Filtering and Object Mask Creation

  • Find external contours (outlines of main objects).
  • Keep only contours with area greater than 1,000 pixels, filtering out small noise.
  • Fill these contours into a new mask to isolate major object regions.
Python
contours, _ = cv2.findContours(
    closing, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE)
result = np.zeros(gray.shape, dtype=np.uint8)
for contour in contours:
    if cv2.contourArea(contour) > 1000:
        cv2.fillPoly(result, [contour], 255)

Step 7: Morphological Opening and Erosion

  • Apply opening to remove small foreground artefacts.
  • Finish by eroding to refine and clean up the boundaries of the segmented objects.
Python
kernel_open = np.ones((6, 6), np.uint8)
opened_result = cv2.morphologyEx(
    result, cv2.MORPH_OPEN, kernel_open, iterations=2)

kernel_erode = np.ones((9, 9), np.uint8)
final_result = cv2.erode(opened_result, kernel_erode, iterations=2)

Step 8: Result

Python
final_result = cv2.erode(opened_result, kernel_erode, iterations=2)
plt.imshow(final_result, cmap='gray')
plt.axis('off')
plt.show()

Output:

taj2
Output

By combining thresholding with targeted morphological operations, we can efficiently segment and extract meaningful objects from an image, removing noise and clarifying boundaries.

You can download source code from here.


Explore