如何使用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()

讓我們來看一些例子,以便更好地理解。

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

我們將獲得以下**輸出**視窗:

凸包以黃色繪製。它還顯示每個物體的填充率和等效直徑。

更新於:2022年9月28日

1K+ 次瀏覽

開啟你的職業生涯

透過完成課程獲得認證

開始學習
廣告