OpenCV 查詢輪廓
本教程將討論使用 Python 中 OpenCV 的 findContours()
函式查詢影象中存在的輪廓。
在 Python 中使用 OpenCV 的 findContours()
函式查詢影象中的輪廓
輪廓是通過將點與物件的邊界連線起來形成的曲線。在影象中,存在多個物件,並且找到影象的輪廓,我們可以獲得有關物件形狀的資訊,因為輪廓會突出影象中存在的物件的邊界。
如果我們知道物體的形狀,我們可以很容易地猜出影象中存在哪些物體。輪廓廣泛用於分析形狀以及檢測和識別物體。
我們可以使用 OpenCV 的 findContours()
函式來查詢影象中存在的輪廓。我們必須使用二值影象來找到輪廓以獲得更好的精度。
如果給定的影象不是二進位制的,我們可以將其轉換為二進位制。例如,在彩色影象的情況下,我們必須使用 OpenCV 的 cvtColor()
函式將影象轉換為灰度。
我們可以使用 OpenCV 的 threshold() 函式中的灰度影象來找到二值影象。之後,我們可以使用 findContours()
函式和二值影象來查詢輪廓。
如果我們想顯示輪廓,我們必須建立一個繪圖並使用 drawContours()
函式繪製輪廓。繪圖應與給定影象大小相同,以更好地視覺化輪廓。
我們可以使用 numpy
庫的 zeros() 函式建立與給定影象相同大小的黑色繪圖。
例如,讓我們使用 imread()
函式讀取影象,將其轉換為二進位制比例,然後找到輪廓並顯示它們。請參閱下面的程式碼。
import cv2
import numpy as np
image = cv2.imread("cat.jpg")
cv2.imshow("Original Image", image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("Gray Image", gray)
_, binary = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
cv2.imshow("Binary image", binary)
contours, hierarchy = cv2.findContours(
binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
drawing = np.zeros((gray.shape[0], gray.shape[1], 3), dtype=np.uint8)
CountersImg = cv2.drawContours(drawing, contours, -1, (255, 255, 0), 3)
cv2.imshow("Contours", CountersImg)
cv2.waitKey(0)
輸出:
findContours()
函式返回兩個輸出引數。第一個輸出引數包含輪廓的位置點和列表中的座標。第二個輸出引數包含輪廓的層次結構。
findContours()
函式的第一個輸入是二進位制或灰度影象。第二個輸入引數是用於定義輪廓層次結構的檢索模式。
我們可以在檢索模式中傳遞不同的值,例如 cv2.RETR_LIST
檢索所有輪廓,cv2.RETR_EXTERNAL
僅檢索外部計數器,cv2.RETR_COMP
檢索 2 級層次結構中的輪廓,以及 cv2.RETR_TREE
檢索完整層次結構中的輪廓。findContours()
函式的第三個輸入引數是用於儲存邊界點的近似方法。
cv2.CHAIN_APPROX_NONE
方法儲存所有邊界點,但有時我們不需要所有邊界點。我們可以使用 cv2.CHAIN_APPROX_SIMPLE
方法來儲存起點和終點輪廓。
我們還可以定義一個偏移量,它將根據 findContours()
函式中的偏移量移動每個輪廓。我們還可以使用 OpenCV 的 drawContours()
函式在給定影象上顯示輪廓。
drawContours()
函式的第一個引數是我們要繪製輪廓的影象。第二個引數是輪廓,第三個是輪廓索引。
第三個引數是輪廓的顏色,可以定義為 RGB 三元組。第四個引數是輪廓的厚度,可以定義為整數。
例如,讓我們在給定影象的頂部顯示輪廓。請參閱下面的程式碼。
import cv2
import numpy as np
image = cv2.imread("cat.jpg")
cv2.imshow("Original Image", image)
gray = cv2.cvtColor(image, cv2.COLOR_BGR2GRAY)
cv2.imshow("Gray Image", gray)
_, binary = cv2.threshold(gray, 100, 255, cv2.THRESH_BINARY)
cv2.imshow("Binary image", binary)
contours, hierarchy = cv2.findContours(
binary, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE
)
drawing = np.zeros((gray.shape[0], gray.shape[1], 3), dtype=np.uint8)
CountersImg = cv2.drawContours(drawing, contours, -1, (255, 255, 0), 3)
cv2.imshow("Contours", CountersImg)
ImgWithCounter = cv2.drawContours(image, contours, -1, (255, 255, 0), 3)
cv2.imshow("Image with counters", ImgWithCounter)
cv2.waitKey(0)
輸出: