如何使用OpenCV Python在图像中找到对象的固体度和等效直径?

如何使用OpenCV Python在图像中找到对象的固体度和等效直径?

对象的固体度是由轮廓面积与其凸包面积的比率计算得出的。因此,要计算固体度,首先必须找到轮廓面积和凸包面积。可以使用 cv2.contourArea() 函数找到对象的轮廓面积。

等效直径是圆的直径,其面积与轮廓面积相同。可以按以下方式计算固体度和等效直径 –

语法

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)

其中, cnt 是图像中对象的轮廓点的numpy数组。

步骤

可以使用以下步骤来计算图像中对象的固体度和等效直径 –

导入所需的库。在以下所有Python示例中,所需的Python库为 OpenCV 。请确保您已经安装了它。

import cv2

使用 cv2.imread() 读取输入图像并将其转换为灰度。

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

对灰度图像应用阈值处理,以创建二进制图像。调整第二个参数以更好地检测轮廓。

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

使用 cv2.findContours() 函数查找图像中的轮廓。

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

选择轮廓“ cnt ”或循环遍历所有轮廓。计算对象的固体度和等效直径。首先计算轮廓面积和凸包面积。

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)

可选择在输入图像上绘制凸包。并在图像上放置固体度和等效直径文本。

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

打印固体度和等效直径并显示带有绘制的凸包和编写的文本的图像。

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

让我们看一些示例以更清楚地理解。

Example 1

在此Python程序中,我们计算图像中对象的固体度和等效直径。我们为图像中的对象绘制了凸包。我们还将对象的固体度和等效直径值作为文本放在图像上。

# 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()

我们将使用此图像作为此程序中的 输入文件

如何使用OpenCV Python在图像中找到对象的固体度和等效直径?

输出

当我们执行上面的代码时,它将产生以下输出−

检测到的对象数:1
固定度:0.7
等效直径:164.4

然后我们会在 窗口 中得到以下输出−

如何使用OpenCV Python在图像中找到对象的固体度和等效直径?

输出显示检测到的对象和凸包用青色绘制,检测到的对象的固定度和等效直径以绿色写出。

例2

在此Python程序中,我们计算图像中多个对象的固定度和等效直径。我们在图像上为每个对象绘制凸包。我们还将每个对象的固定度和等效直径作为文本放置。

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()

我们将使用此图像作为程序中的输入文件,操作如下:

如何使用OpenCV Python在图像中找到对象的固体度和等效直径?

输出结果

执行以上代码后,将产生以下输出结果 :

检测到的物体数量:3 
第1个物体的紧密度:0.55 
第1个物体的等效直径:74.47 
第2个物体的紧密度:0.73 
第2个物体的等效直径:102.72 
第3个物体的紧密度:0.8 
第3个物体的等效直径:141.32

然后,我们可以在下方窗口获取以下 输出结果

如何使用OpenCV Python在图像中找到对象的固体度和等效直径?

凸包用黄色绘制。它还显示每个物体的紧密度和等效直径。

Python教程

Java教程

Web教程

数据库教程

图形图像教程

大数据教程

开发工具教程

计算机教程

Python OpenCV