如何使用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
我們將獲得以下**輸出**視窗:

凸包以黃色繪製。它還顯示每個物體的填充率和等效直徑。
資料結構
網路
關係資料庫管理系統 (RDBMS)
作業系統
Java
iOS
HTML
CSS
Android
Python
C語言程式設計
C++
C#
MongoDB
MySQL
Javascript
PHP