How to find the solidity and equivalent diameter of an object in an image using OpenCV Python?


The solidity of an object is computed as the ratio of contour area to its convex hull area. So to compute the solidity, we first have to find the contour area and convex hull area. The contour area of an object can be found using cv2.contourArea() function.

Equivalent Diameter is the diameter of the circle whose area is the same as the contour area. The solidity and equivalent diameter can be computed as below −

Syntax

area = cv2.contourArea(cnt)
hull = cv2.convexHull(cnt)
hull_area = cv2.contourArea(hull)
solidity = float(area)/hull_area
equi_diameter = np.sqrt(4*area/np.pi)

Where, cnt is a numpy array of the contour points of an object in the image.

Steps

You can use the following steps to compute solidity and equivalent diameter of an object in an image −

Import the required library. In all the following Python examples, the required Python library is OpenCV. Make sure you have already installed it.

import cv2

Read the input image using cv2.imread() and convert it to grayscale.

img = cv2.imread('star.png.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)

Apply thresholding on the grayscale image to create a binary image. Adjust the second argument for better detection of contour.

ret,thresh = cv2.threshold(gray,40,255,0)

Find the contours in the image using cv2.findContours() function.

contours, _ = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

Select a contour "cnt" or loop over all contours. Compute the solidity and equivalent diameter of the object. We first compute the contour area and convex hull area.

area = cv2.contourArea(cnt)
hull = cv2.convexHull(cnt)
hull_area = cv2.contourArea(hull)
solidity = float(area)/hull_area
equi_diameter = np.sqrt(4*area/np.pi)

Optionally you can draw the Convex Hull on the input image. And put the solidity and equivalent diameter as text on the image

cv2.drawContours(img, [hull], -1, (0,255,255), 3)

Print the solidity and equivalent diameter and display the image with the drawn convex hull and written text.

print("Solidity: ", solid)
print("Equivalent Diameter: ", dia)
cv2.imshow("Solidity & Equivalent Diameter", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

Let's have a look at some examples for more clear understanding.

Example 1

In this Python program, we compute the solidity and equivalent diameter of an object in the image. We draw the convex hull for the object in the image. We also put on the image the solidity and equivalent diameter value as text for the object.

# import required libraries import cv2 # load the input image img = cv2.imread('star.png') # convert the image to grayscale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # apply thresholding to convert grayscale to binary image ret,thresh = cv2.threshold(gray,40,255,0) # find the contours contours,hierarchy = cv2.findContours(thresh, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) print("Number of objects detected:", len(contours)) # define function to compute the solidity def solidity(cnt): area = cv2.contourArea(cnt) hull = cv2.convexHull(cnt) hull_area = cv2.contourArea(hull) solidity = float(area)/hull_area return solidity # define function to compute the equivalent diameter def eq_dia(cnt): area = cv2.contourArea(cnt) equi_diameter = np.sqrt(4*area/np.pi) return equi_diameter # select first contour cnt = contours[0] # find the solidity for this contour solid = solidity(cnt) solid= round(solid, 2) # find the equivalent diameter for this contour dia = eq_dia(cnt) dia =round(dia, 2) # draw convex hull on the image hull = cv2.convexHull(cnt) x1, y1 = hull[0][0] img = cv2.drawContours(img,[hull],0,(255,255,0),2) cv2.putText(img, f'Solidity={solid}', (x1, y1), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) cv2.putText(img, f'Equivalent Diameter={dia}', (x1, y1+30), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) print("Solidity: ", solid) print("Equivalent Diameter: ", dia) cv2.imshow("Solidity & Equivalent Diameter", img) cv2.waitKey(0) cv2.destroyAllWindows()

We will use this image as the Input File in this program −

Output

When we execute the above code, it will produce the following output −

Number of objects detected: 1 
Solidity: 0.7 
Equivalent Diameter: 164.4

And we get the following output window −

The output shows the detected object and convex hull is drawn in cyan color. The solidity and equivalent diameter of the detected object is written in green color.

Example 2

In this Python program, we compute the solidity and Equivalent diameter of multiple objects in the image. We draw the convex hull for each objects on the image. We also put the solidity and equivalent diameter as text for each object.

import cv2 import numpy as np img = cv2.imread('convexhull.png') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret,thresh = cv2.threshold(gray,100,255,0) contours,hierarchy = cv2.findContours(thresh, 1, 2) print("Number of objects detected:", len(contours)) def solidity(cnt): area = cv2.contourArea(cnt) hull = cv2.convexHull(cnt) hull_area = cv2.contourArea(hull) solidity = float(area)/hull_area return solidity def eq_dia(cnt): area = cv2.contourArea(cnt) equi_diameter = np.sqrt(4*area/np.pi) return equi_diameter for i, cnt in enumerate(contours): solid = solidity(cnt) solid= round(solid, 2) dia = eq_dia(cnt) dia =round(dia, 2) x,y,w,h = cv2.boundingRect(cnt) hull = cv2.convexHull(cnt) img = cv2.drawContours(img,[hull],0,(0,255,255),2) cv2.putText(img, f'Solidity={solid}', (x, y), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2) cv2.putText(img, f'Equivalent Diameter={dia}', (x, y+30), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (255, 255, 0), 2) print(f"Solidity of object {i+1}: ", solid) print(f"Equivalent Diameter of object {i+1}: ", dia) cv2.imshow("Solidity and Equi Diameter", img) cv2.waitKey(0) cv2.destroyAllWindows()

We will use this image as the Input File in this program −

Output

When we execute the above code, it will produce the following output

Number of objects detected: 3 
Solidity of object 1: 0.55 
Equivalent Diameter of object 1: 74.47 
Solidity of object 2: 0.73 
Equivalent Diameter of object 2: 102.72 
Solidity of object 3: 0.8 
Equivalent Diameter of object 3: 141.32

And we get the following output window −

The convex hull is drawn in yellow color. It also shows the solidity and equivalent diameters for each object.

Updated on: 28-Sep-2022

866 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements