如何在OpenCV Python中查詢和繪製圖像輪廓的凸包?


凸包看起來類似於輪廓逼近,但它並非完全是輪廓逼近。凸包是圍繞物體的凸曲線。凸曲線總是凸出的,或者至少是平的。凸包查詢凸性缺陷並對其進行修正。

語法

要查詢凸包,我們使用以下函式:

hull = cv2.convexHull(cnt, hull, clockwise, returnPoints)

引數

  • cnt是輪廓點。它表示為輪廓點的陣列。

  • hull是輸出,通常我們避免使用它。

  • clockwise – 方向標誌。如果為True,則輸出凸包的方向為順時針方向,否則為逆時針方向。

  • returnPoints – 預設設定為True。

輸出 – 當returnPoints設定為True時,它返回凸包點的座標。如果設定為False,則返回對應於凸包點的輪廓點的索引。

因此,為了獲得凸包,我們通常使用以下方法:

hull = cv2.convexHull(cnt)

要繪製凸包點的輪廓,請使用此函式:

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

步驟

您可以使用以下步驟查詢並繪製圖像輪廓的凸包:

匯入所需的庫。在所有以下Python示例中,所需的Python庫是OpenCV。確保您已經安裝了它。

import cv2

使用cv2.imread()讀取輸入影像並將其轉換為灰度影像。

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

對灰度影像應用閾值處理以建立二值影像。

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

使用cv2.findContours()函式查詢影像中的輪廓。

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

選擇輪廓cnt或迴圈遍歷所有輪廓。使用cv2.convexHull(cnt)函式查詢輪廓cnt的凸包。

cnt = contours[0]
hull = cv2.convexHull(cnt)

將凸包點傳遞給以下函式,在輸入影像上繪製凸包。

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

顯示繪製了凸包的影像。

cv2.imshow("Convex Hull", img)
cv2.waitKey(0)
cv2.destroyAllWindows()

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

示例1

在下面的Python程式中,我們檢測影像中的輪廓並查詢第一個輪廓的凸包。我們還在影像上繪製第一個輪廓和凸包。

# import required libraries import cv2 # load the input image img = cv2.imread('six-point-star.png') # convert the input image to grayscale gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) # apply thresholding to convert grayscale to binary image ret,thresh = cv2.threshold(img1,150,255,0) # find the contours contours,hierarchy = cv2.findContours(thresh, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) print("Number of contours detected:", len(contours)) # select the first contour cnt = contours[0] # find the convex hull using the contour hull = cv2.convexHull(cnt) # draw contour and convex hull on the input image img = cv2.drawContours(img,[cnt],0,(255,0,0),2) img = cv2.drawContours(img,[hull],0,(0,255,255),3) # display the image with drawn contour and convex hull cv2.imshow("Convex Hull", img) cv2.waitKey(0) cv2.destroyAllWindows()

我們將在上面的程式程式碼中使用以下影像作為輸入檔案

輸出

執行上述程式碼後,將產生以下輸出

Number of contours detected: 1

我們將得到以下輸出視窗,顯示影像中檢測到的第一個輪廓和凸包:

輪廓以藍色繪製,凸包以黃色繪製。注意輪廓和凸包之間的區別。

示例2

在這個例子中,我們檢測影像中的輪廓並查詢所有輪廓的凸包。我們還在影像上繪製所有輪廓和凸包。

import cv2 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, cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE) print("Number of contours detected:", len(contours)) # Find the convex hull for all the contours for cnt in contours: hull = cv2.convexHull(cnt) img = cv2.drawContours(img,[cnt],0,(0,255,0),2) img = cv2.drawContours(img,[hull],0,(0,0,255),3) # Display the image with convex hull drawn on it cv2.imshow("Convex Hull", img) cv2.waitKey(0) cv2.destroyAllWindows()

我們將在本程式中使用此影像作為輸入檔案

輸出

執行上述程式碼後,將產生以下輸出

Number of contours detected: 3

我們將得到以下輸出視窗,顯示影像中檢測到的輪廓和凸包:

凸包以紅色顯示,輪廓以綠色顯示。注意輪廓和凸包之間的區別。

更新於:2022年9月28日

4K+ 次瀏覽

啟動您的職業生涯

透過完成課程獲得認證

開始學習
廣告