一、簡介
OpenCV是一個強大且流行的計算機視覺庫,廣泛應用於各種領域,如機器人、安防、自動駕駛、醫療等。OpenCV提供了許多函數和演算法來處理圖像和視頻的問題,而輪廓檢測是其中之一。輪廓是由圖像中的連續點組成的曲線,其表示了這個物體的邊界。輪廓檢測可以在計算機視覺領域中起到非常重要的作用,例如圖像分割、物體識別、運動跟蹤、手勢識別等。
二、基本函數
OpenCV提供了許多輪廓檢測的函數,其中最常用的函數是findContours()。該函數可用於在二進位圖像中找到所有的輪廓。該函數返回的結果是一組點的列表,每個列表代表一個輪廓。在使用findContours()函數之前,我們需要將圖像轉換為二進位圖像,即使得背景為黑色,物體為白色的圖像。接下來是 findContours()函數的基本使用:
import cv2 img = cv2.imread('image.tif') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(img, contours, -1, (0,0,255), 3) cv2.imshow('image', img) cv2.waitKey(0) cv2.destroyAllWindows()
以上代碼展示了如何使用findContours()函數來檢測圖像的輪廓。首先讀入一張圖像,將其轉換為灰度圖像,然後將灰度圖像轉換為二進位圖像。接著使用findContours()函數找到圖像中所有的輪廓,繪製出所有輪廓,並將結果列印出來。
三、檢測模式
1. RETR_EXTERNAL
該模式只檢測最外層的輪廓,忽略不在外部的輪廓。
img = cv2.imread('image.tif') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) cv2.drawContours(img, contours, -1, (0,0,255), 3) cv2.imshow('image', img) cv2.waitKey(0) cv2.destroyAllWindows()
2. RETR_TREE
該模式會檢測所有的輪廓,並且將其組合成一個樹形結構,每個輪廓都有一個父輪廓和子輪廓。
img = cv2.imread('image.tif') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) for i in range(len(contours)): if hierarchy[0][i][3] == -1: cv2.drawContours(img, contours, i, (0, 255, 0), 2) cv2.imshow('image', img) cv2.waitKey(0) cv2.destroyAllWindows()
以上代碼展示了如何使用RETR_TREE模式檢測圖像的輪廓,並展示了如何訪問輪廓的層次結構。
四、逼近方法
逼近方法是指我們可以用一條直線或一個多邊形來逼近一個輪廓。這對於降低計算量和壓縮數據是非常有用的。OpenCV提供了多種逼近方法,包括:
- cv2.CHAIN_APPROX_NONE:存儲所有的邊界點
- cv2.CHAIN_APPROX_SIMPLE:只存儲拐角點
- cv2.CHAIN_APPROX_TC89_L1
- cv2.CHAIN_APPROX_TC89_KCOS
1. cv2.CHAIN_APPROX_NONE
使用cv2.CHAIN_APPROX_NONE模式,可以檢測出圖像的所有輪廓點。下面是代碼示例:
img = cv2.imread('image.tif') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) for cnt in contours: cv2.drawContours(img, [cnt], 0, (0,255,0), 3) cv2.imshow('image', img) cv2.waitKey(0) cv2.destroyAllWindows()
2. cv2.CHAIN_APPROX_SIMPLE
使用cv2.CHAIN_APPROX_SIMPLE模式,只保存重要的拐角點,可以大大減小存儲空間。下面是代碼示例:
img = cv2.imread('image.tif') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE) for cnt in contours: cv2.drawContours(img, [cnt], 0, (0,255,0), 3) cv2.imshow('image', img) cv2.waitKey(0) cv2.destroyAllWindows()
3. cv2.approxPolyDP()
除了cv2.CHAIN_APPROX_SIMPLE以外,我們還可以使用cv2.approxPolyDP()函數對輪廓進行逼近。該函數會將輪廓逼近為一條直線或一組多邊形。下面是代碼示例:
img = cv2.imread('image.tif') gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY) contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE) for cnt in contours: epsilon = 0.01 * cv2.arcLength(cnt, True) approx = cv2.approxPolyDP(cnt, epsilon, True) cv2.drawContours(img, [approx], 0, (0,255,0), 3) cv2.imshow('image', img) cv2.waitKey(0) cv2.destroyAllWindows()
五、結論
本文詳細介紹了OpenCV輪廓檢測的基本函數、檢測模式和逼近方法。輪廓檢測是計算機視覺中常用的技術之一,可以用於圖像分割、物體識別、運動跟蹤、手勢識別等。通過本文的介紹,讀者可以掌握OpenCV輪廓檢測的基本原理和常用方法,為計算機視覺的研究和應用提供幫助。
原創文章,作者:IZEHL,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/370801.html