OpenCV 查詢輪廓

Ammar Ali 2022年5月17日
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)

輸出:

使用 opencv 查詢輪廓

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)

輸出:

影象頂部的輪廓

作者: Ammar Ali
Ammar Ali avatar Ammar Ali avatar

Hello! I am Ammar Ali, a programmer here to learn from experience, people, and docs, and create interesting and useful programming content. I mostly create content about Python, Matlab, and Microcontrollers like Arduino and PIC.

LinkedIn Facebook

相關文章 - Python OpenCV