Image Segmentation in OpenCV
Introduction to Image Segmentation in OpenCV
Updated March 21, 2023
Learn more about OpenCV and Computer Vision from this YouTube Channel!
Image segmentation is the process of dividing an image into multiple segments or regions based on various features, such as color, texture, or intensity. It is a fundamental task in computer vision and has numerous applications, including object detection, face recognition, and medical imaging. In this tutorial, we will explore how to perform image segmentation using OpenCV, a popular computer vision library.
The most common approach to image segmentation is the thresholding method. This method involves setting a threshold value and classifying each pixel in the image based on whether its intensity is above or below the threshold. Pixels with intensities above the threshold are classified as belonging to one segment, while those below the threshold are classified as belonging to another.
Another approach to image segmentation is clustering, which groups similar pixels into segments based on their proximity in feature space. Clustering algorithms, such as k-means, are commonly used for image segmentation.
Image Segmentation in OpenCV
OpenCV provides several functions for image segmentation, including thresholding, contour detection, and watershed segmentation.
The thresholding function in OpenCV allows us to set a threshold value and convert an image into a binary image, where pixels with values above the threshold are set to one and those below are set to zero.
Here is an example of thresholding an image using OpenCV:
import cv2 img = cv2.imread('image.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) cv2.imshow('Original Image', img) cv2.imshow('Binary Image', thresh) cv2.waitKey(0) cv2.destroyAllWindows()
In this example, we first read in an image using cv2.imread and convert it to grayscale using
cv2.cvtColor. We then use the
cv2.threshold function to threshold the image with a threshold value of 127. The function returns two values: the threshold value used (‘ret’) and the thresholded image (‘thresh’).
Contours are the boundaries of objects in an image. The cv2.findContours function in OpenCV can be used to detect contours in an image. Here is an
import cv2 img = cv2.imread('image.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(img, contours, -1, (0, 255, 0), 3) cv2.imshow('Contours', img) cv2.waitKey(0) cv2.destroyAllWindows()
In this example, we first threshold the image using the same method as before. We then use the cv2.findContours function to detect contours in the thresholded image. The function returns a list of contours and a hierarchy of nested contours. We then use the cv2.drawContours function to draw the contours on the original image.
Watershed segmentation is a more advanced method of image segmentation that can be used to separate objects that are touching or overlapping. The cv2.watershed function in OpenCV can be used to perform watershed segmentation.
Here is an example:
import cv2 import numpy as np img = cv2.imread('image.jpg') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY_INV+cv2.THRESH_OTSU) # Noise removal kernel = np.ones((3,3),np.uint8) opening = cv2.morphologyEx(thresh,cv2.MORPH_OPEN,kernel, iterations = 2) # Sure background area sure_bg = cv2.dilate(opening,kernel,iterations=3) # Finding sure foreground area dist_transform = cv2.distanceTransform(opening,cv2.DIST_L2,5) ret, sure_fg = cv2.threshold(dist_transform,0.7*dist_transform.max(),255,0) # Finding unknown region sure_fg = np.uint8(sure_fg) unknown = cv2.subtract(sure_bg,sure_fg) # Marker labelling ret, markers = cv2.connectedComponents(sure_fg) # Add one to all labels so that sure background is not 0, but 1 markers = markers+1 # Now, mark the region of unknown with zero markers[unknown==255] = 0 markers = cv2.watershed(img,markers) img[markers == -1] = [255,0,0] cv2.imshow('Original Image', img) cv2.waitKey(0) cv2.destroyAllWindows()
In this example, we first read in an image using
cv2.imread and convert it to grayscale using
cv2.cvtColor. We then apply thresholding using the Otsu’s method to obtain a binary image.
We then perform noise removal and morphological opening to remove any small white noises in the image. We then dilate the image to obtain the sure background region.
We then use distance transform to obtain the sure foreground region. We threshold the distance transformed image to obtain a binary image, and then use it to obtain the sure foreground region.
We then find the unknown region by subtracting the sure foreground region from the sure background region. We then label the markers using the
Finally, we perform watershed segmentation using the
cv2.watershed function, and mark the boundaries of the segmented regions on the original image using the
In this tutorial, we explored the basics of image segmentation in OpenCV. We covered the theoretical background of image segmentation and demonstrated how to perform thresholding, contour detection, and watershed segmentation using OpenCV. We hope this tutorial has helped you understand the basics of image segmentation and how it can be used in computer vision applications.