Image segmentation using Morphological operations in Python
Last Updated :
05 Aug, 2025
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:
OTSU's ThresholdingStep 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:
OutputBy 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
Python Fundamentals
Python Data Structures
Advanced Python
Data Science with Python
Web Development with Python
Python Practice