如何使用 OpenCV Python 查找图像中对象的实体性和等效直径?

opencvpythonserver side programmingprogramming

对象的实体性计算为轮廓面积与其凸包面积之比。因此,要计算实体性,我们首先必须找到轮廓面积和凸包面积。可以使用 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()

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

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

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

输出

当我们执行上述代码时,它将产生以下输出 -

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

我们得到以下输出 窗口 -

输出显示检测到的物体和凸包以青色绘制。检测到的物体的硬度和等效直径以绿色书写。

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

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

输出

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

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

我们得到了以下输出窗口 −

凸包以黄色绘制。它还显示每个对象的坚固性和等效直径。


相关文章