什么是輪廓蹂空?
輪廓可以被簡(jiǎn)單解釋為一個(gè)連接所有連續(xù)點(diǎn)的曲線(xiàn)(沿邊界)舰始,有同樣的顏色和亮度。輪廓在做形狀分析和目標(biāo)檢測(cè)與識(shí)別都很有用峻堰。
·為了更好地額準(zhǔn)確率讹开,使用二進(jìn)制圖像,所以在找輪廓前捐名,使用閾值或者canny邊緣檢測(cè)旦万。
·findContours函數(shù)修改原圖。所以如果你想在找輪廓后還需要原圖镶蹋,把它存到別的變量里成艘。
·在OpenCV里赏半,找輪廓和在黑色背景里找白色目標(biāo)一樣,所以記住淆两,目標(biāo)應(yīng)該是白的而背景是黑色的断箫。
如何找到一個(gè)二進(jìn)制圖像的輪廓:
import numpy as np
import cv2im = cv2.imread('test.jpg')
imgray = cv2.cvtColor(im,cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray,127,255,0)
image, contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cv2.findContours()函數(shù)的三個(gè)參數(shù),第一個(gè)是原圖琼腔,第二個(gè)是輪廓獲取方式瑰枫,第三個(gè)是輪廓近似方法踱葛。它會(huì)輸出圖片丹莲,輪廓和層級(jí)。輪廓是Python的列表尸诽,包括了圖片里的所有輪廓甥材,每個(gè)輪廓是一個(gè)Numpy的數(shù)組,包含對(duì)象的邊界點(diǎn)的坐標(biāo)(x,y)
如何繪制輪廓
要繪制輪廓性含,可以用cv2.drawContours函數(shù)洲赵。如果你有圖形的邊界點(diǎn),也可以用來(lái)繪制任何形狀商蕴。它的第一個(gè)參數(shù)是原圖叠萍,第二個(gè)參數(shù)是圖形的輪廓,應(yīng)該傳一個(gè)Python列表绪商,第三個(gè)參數(shù)是輪廓索引(在繪制特定的輪廓的時(shí)候有用苛谷,要畫(huà)所有的就傳-1)剩下的參數(shù)是顏色,厚度等格郁。
要畫(huà)一個(gè)圖像的所有輪廓:
img=cv2.drawContours(img,contours,-1,(0,255,0),3)
要畫(huà)第四級(jí)輪廓:
img=cv2.drawContours(img,contours,3,(0,255,0),3)
但大多數(shù)時(shí)候腹殿,下面的更有用:
cnt=contours[4]img=cv2.drawContours(img,[cnt],0,(0,255,0),3)
Contour 近似方法
這是cv2.findContours函數(shù)的參數(shù),它實(shí)際是指什么呢例书?
輪廓是圖形的邊界锣尉。它存了邊界坐標(biāo)(x,y),但是它存了所有坐標(biāo)么决采?這個(gè)就是輪廓近似方法指定的自沧。
如果你傳cv2.CHAIN_APPROX_NONE,所有的邊界點(diǎn)都會(huì)存下來(lái)树瞭。但是實(shí)際上我們需要所有的點(diǎn)么拇厢?比如說(shuō),你發(fā)現(xiàn)一個(gè)直線(xiàn)的輪廓移迫,你需要這線(xiàn)上的所有點(diǎn)來(lái)表示這個(gè)線(xiàn)么旺嬉?不需要,我們只需要兩個(gè)端點(diǎn)就夠了厨埋。這就是cv2.CHAIN_APPROX_SIMPLE要做的邪媳。它會(huì)去掉所有冗余點(diǎn)來(lái)壓縮輪廓,節(jié)省內(nèi)存。
下面矩形圖像展示了這個(gè)技術(shù)雨效,把輪廓里所有的點(diǎn)繪制出來(lái)迅涮。第一個(gè)圖像顯示了cv2.CHAIN_APPROX_NONE的情況(734個(gè)點(diǎn)),第二個(gè)圖像顯示了cv2.CHAIN_APPROX_SIMPLE的(4個(gè)點(diǎn))徽龟。