基于OpenCV實(shí)戰(zhàn):繪制圖像輪廓(附代碼)
點(diǎn)擊上方“小白學(xué)視覺”,選擇加"星標(biāo)"或“置頂”
重磅干貨,第一時(shí)間送達(dá)
山區(qū)和地形圖中海拔高的區(qū)域劃出的線稱為地形輪廓,它們提供了地形的高程圖。這些線條可以手動(dòng)繪制,也可以由計(jì)算機(jī)生成。在本文中,我們將看到如何使用OpenCV在簡單圖像上繪制輪廓線。

OpenCV為我們提供了“ findContours”功能,該功能可在二進(jìn)制圖像中查找輪廓并將其存儲(chǔ)為坐標(biāo)點(diǎn)的小數(shù)數(shù)組。功能定義如下。
cv.findContours(image,mode,method[,contours[,hierarchy[,offset]]]) ->contours, hierarchy
image-源,一個(gè)8位單通道圖像。非零像素被視為1。零像素保持為0,因此圖像被視為二進(jìn)制。
模式-輪廓檢索模式。
方法-等高線近似方法。
第二個(gè)參數(shù),即輪廓檢索模式,用于檢索圖像中輪廓之間的關(guān)系。例如,在圖
像中,輪廓內(nèi)可能有輪廓,就像嵌套輪廓一樣。在這種情況下,我們將外部輪廓稱為父級(jí),將內(nèi)部輪廓稱為子級(jí)。使用findContours函數(shù)時(shí),應(yīng)該檢索輪廓之間的這些關(guān)系并將其存儲(chǔ)在變量中。如果需要,將來也可以使用它們。OpenCV中有四種檢索模式,分別是cv.RETR_LIST,cv.RETR_TREE,cv.RETR_CCOMP,cv.RETR_EXTERNAL。為了清楚了解檢索模式,強(qiáng)烈建議參考OpenCV的輪廓輪廓官方教程。
OpenCv中有兩種輪廓逼近方法。它們是cv.CHAIN_APPROX_NONE和cv.CHAIN_APPROX_SIMPLE。如果通過cv.CHAIN_APPROX_NONE,則將存儲(chǔ)輪廓的所有邊界點(diǎn)。但是實(shí)際上,我們是否需要所有這些要點(diǎn)?例如,找到了一條直線的輪廓,是否需要線上的所有點(diǎn)來表示該線?事實(shí)并非如此,我們只需要該行的兩個(gè)端點(diǎn)即可。這就是cv.CHAIN_APPROX_SIMPLE所做的。它刪除所有冗余點(diǎn)并壓縮輪廓,從而節(jié)省內(nèi)存。
找到輪廓并將輪廓線的坐標(biāo)點(diǎn)(x,y)存儲(chǔ)在數(shù)組中后,我們可以使用這些點(diǎn)在圖像上繪制輪廓線。我們使用OpenCV的drawContours函數(shù)執(zhí)行相同的操作。
cv.drawContours(image,contours,contourIdx,color[,thickness[,lineType[,hierarchy[,maxLevel[,offset]]]]]) ->image
圖像-目標(biāo)圖像。
輪廓-所有輸入輪廓。每個(gè)輪廓都存儲(chǔ)為點(diǎn)向量。
outlineIdx-指示要繪制的輪廓的參數(shù)。如果為負(fù),則繪制所有輪廓。
顏色-顏色的輪廓。
粗細(xì)-繪制等高線的粗細(xì)。如果為負(fù)(例如,thickness = FILLED),則繪制輪廓內(nèi)部。
原始圖像:

import cv2 as cv#read the imageimg = cv.imread("D://medium_blogs//pattern1.jpg")#convert the image to grayscalegray = cv.cvtColor(img, cv.COLOR_BGR2GRAY)#blur image to reduce the noise in the image while thresholdingblur = cv.blur(gray, (10,10))#Apply thresholding to the imageret, thresh = cv.threshold(blur, 1, 255, cv.THRESH_OTSU)#find the contours in the imagecontours, heirarchy = cv.findContours(thresh, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)#draw the obtained contour lines(or the set of coordinates forming a line) on the original imagecv.drawContours(img, contours, -1, (0,255,0), 20)#show the imagecv.namedWindow('Contours',cv.WINDOW_NORMAL)cv.namedWindow('Thresh',cv.WINDOW_NORMAL)cv.imshow('Contours', img)cv.imshow('Thresh', thresh)if cv.waitKey(0):cv.destroyAllWindows()
閾值圖像和在其上繪制輪廓的原始圖像如下:

交流群
歡迎加入公眾號(hào)讀者群一起和同行交流,目前有SLAM、三維視覺、傳感器、自動(dòng)駕駛、計(jì)算攝影、檢測、分割、識(shí)別、醫(yī)學(xué)影像、GAN、算法競賽等微信群(以后會(huì)逐漸細(xì)分),請掃描下面微信號(hào)加群,備注:”昵稱+學(xué)校/公司+研究方向“,例如:”張三 + 上海交大 + 視覺SLAM“。請按照格式備注,否則不予通過。添加成功后會(huì)根據(jù)研究方向邀請進(jìn)入相關(guān)微信群。請勿在群內(nèi)發(fā)送廣告,否則會(huì)請出群,謝謝理解~

