How to find and draw Convex Hull of an image contour in OpenCV Python?
OpenCV is one of the most popular computer vision libraries available today. It is used to process, analyze, and manipulate images and videos. One of the useful features of OpenCV is the ability to find the convex hull of an image contour. The convex hull is the smallest convex polygon that contains all of the points in a set. In this article, we will learn how to find and draw the convex hull of an image contour in OpenCV Python.
What is a Convex Hull?
A convex hull is a closed polygon that completely encapsulates a set of points on a plane. It is the smallest polygon that can be drawn around a set of points such that the polygon can be drawn without any dents or indentations. The convex hull can be useful when trying to simplify the shape of an object in an image or when trying to extract the boundary of an object.
Finding the Convex Hull of an Image Contour
The first step to finding the convex hull of an image contour is to create a binary image from the original image. A binary image is a black and white image where the pixel values are either 0 or 255. We can create a binary image from an original image by converting it to grayscale and then applying a threshold. The threshold value determines which pixels are set to 255 (white) and which pixels are set to 0 (black).
import cv2
import numpy as np
#Read image
img = cv2.imread('image.jpg')
#Convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#Apply threshold
ret,thresh = cv2.threshold(gray,127,255,1)
Next, we need to find the contours in the binary image. Contours are the boundaries of objects in an image. We can use the findContours() function in OpenCV to find the contours. The function takes in the binary image and a mode parameter that specifies how the contours should be retrieved. We can retrieve all of the contours by setting the mode parameter to cv2.RETR_LIST.
#Find contours
contours = cv2.findContours(thresh.copy(),cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)[0]
Now that we have the contours, we can find the convex hull of each contour using the convexHull() function in OpenCV. The function takes in the contour and a clockwise parameter that specifies whether the output should be in clockwise order. We can set the parameter to True to get the output in clockwise order.
#Loop through contours and find convex hull
for cnt in contours:
hull = cv2.convexHull(cnt, clockwise=True)
Finally, we can draw the convex hull on the original image using the drawContours() function in OpenCV. The function takes in the original image, the convex hull, the index of the contour to draw (-1 to draw all contours), and a color and thickness parameter.
#Draw convex hull
cv2.drawContours(img,[hull],-1,(0,0,255),2)
Putting it all together, we get the following code:
import cv2
import numpy as np
#Read image
img = cv2.imread('image.jpg')
#Convert to grayscale
gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#Apply threshold
ret,thresh = cv2.threshold(gray,127,255,1)
#Find contours
contours = cv2.findContours(thresh.copy(),cv2.RETR_LIST,cv2.CHAIN_APPROX_SIMPLE)[0]
#Loop through contours and find convex hull
for cnt in contours:
hull = cv2.convexHull(cnt, clockwise=True)
#Draw convex hull
cv2.drawContours(img,[hull],-1,(0,0,255),2)
#Display result
cv2.imshow('Convex Hull',img)
cv2.waitKey(0)
cv2.destroyAllWindows()
Conclusion
In this article, we learned how to find and draw the convex hull of an image contour in OpenCV Python. We first created a binary image from the original image and then found the contours in the binary image. We then used the convexHull() function to find the convex hull of each contour and the drawContours() function to draw the convex hull on the original image. The ability to find the convex hull of an image contour can be useful when trying to simplify the shape of an object in an image or when trying to extract the boundary of an object.