OpenCV---輪廓發現


推文:OpenCV-Python教程(11、輪廓檢測)

輪廓發現

是基於圖像邊緣提取的基礎,尋找對象輪廓的方法,所以邊緣提取的閾值選定會影響最終輪廓的發現

相關API

findContours 發現輪廓

drawContours繪制輪廓

操作步驟

1.轉換圖像為二值化圖像:threshold方法或者canny邊緣提取獲取的都是二值化圖像
2.通過二值化圖像尋找輪廓:findContours
3.描繪輪廓:drawContours

一:使用直接使用閾值方法threshold方法獲取二值化圖像來選擇輪廓

def contours_demo(image):
    dst = cv.GaussianBlur(image,(9,9),15)  #高斯模糊,消除噪聲
    gray = cv.cvtColor(dst,cv.COLOR_BGR2GRAY) #先變灰度圖像
    ret, binary = cv.threshold(gray,0,255,cv.THRESH_BINARY|cv.THRESH_OTSU)  #獲取二值圖像
    cv.imshow("binary image",binary)

    # cloneImage,contours,heriachy = cv.findContours(binary,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)    #RETR_TREE包含檢測內部
    cloneImage,contours,heriachy = cv.findContours(binary,cv.RETR_EXTERNAL,cv.CHAIN_APPROX_SIMPLE)  #RETR_EXTERNAL檢測外部輪廓
    for i, contour in enumerate(contours):
        # cv.drawContours(image,contours,i,(0,0,255),2)  #繪制輪廓
        cv.drawContours(image,contours,i,(0,0,255),-1)  #填充輪廓
        print(i)
    cv.imshow("detect contours",image)


src = cv.imread("./lk.png")  #讀取圖片
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)    #創建GUI窗口,形式為自適應
cv.imshow("input image",src)    #通過名字將圖像和窗口聯系

contours_demo(src)

cv.waitKey(0)   #等待用戶操作,里面等待參數是毫秒,我們填寫0,代表是永遠,等待用戶操作
cv.destroyAllWindows()  #銷毀所有窗口

二:使用canny邊緣檢測獲取二值化圖像

def contours_demo(image):
    binary = edge_demo(image)

    cloneImage,contours,heriachy = cv.findContours(binary,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)    #RETR_TREE包含檢測內部
    for i, contour in enumerate(contours):
        # cv.drawContours(image,contours,i,(0,0,255),2)
        cv.drawContours(image,contours,i,(0,0,255),-1)
        print(i)
    cv.imshow("detect contours",image)

def edge_demo(image):
    dst = cv.GaussianBlur(image,(3,3),0)
    gray = cv.cvtColor(dst,cv.COLOR_BGR2GRAY) #先變灰度圖像

    edge_output = cv.Canny(gray,50,108)

    cv.imshow("detect contours",edge_output)
    return edge_output

src = cv.imread("./lk.png")  #讀取圖片
cv.namedWindow("input image",cv.WINDOW_AUTOSIZE)    #創建GUI窗口,形式為自適應
cv.imshow("input image",src)    #通過名字將圖像和窗口聯系

contours_demo(src)

cv.waitKey(0)   #等待用戶操作,里面等待參數是毫秒,我們填寫0,代表是永遠,等待用戶操作
cv.destroyAllWindows()  #銷毀所有窗口

相關知識補充

(一)findContours尋找輪廓

cv.findContours(binary,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE) 
def findContours(image, mode, method, contours=None, hierarchy=None, offset=None): # real signature unknown; restored from __doc__
1.image:輸入圖像,圖像必須為8-bit單通道圖像,圖像中的非零像素將被視為1,0像素保留其像素值,故加載圖像后會自動轉換為二值圖像。可以通過threshold和canny獲取
2.mode:輪廓檢索模式

RETR_EXTERNAL:表示只檢測最外層輪廓,對所有輪廓設置hierarchy[i][2]=hierarchy[i][3]=-1 
RETR_LIST:提取所有輪廓,並放置在list中,檢測的輪廓不建立等級關系 
RETR_CCOMP:提取所有輪廓,並將輪廓組織成雙層結構(two-level hierarchy),頂層為連通域的外圍邊界,次層位內層邊界 
RETR_TREE:提取所有輪廓並重新建立網狀輪廓結構 
RETR_FLOODFILL:官網沒有介紹,應該是洪水填充法 
3.method:輪廓近似方法

CHAIN_APPROX_NONE:獲取每個輪廓的每個像素,相鄰的兩個點的像素位置差不超過1 
CHAIN_APPROX_SIMPLE:壓縮水平方向,垂直方向,對角線方向的元素,值保留該方向的重點坐標,如果一個矩形輪廓只需4個點來保存輪廓信息 
CHAIN_APPROX_TC89_L1和CHAIN_APPROX_TC89_KCOS使用Teh-Chinl鏈逼近算法中的一種 

返回值:

ret = cv.findContours(binary, cv.RETR_TREE, cv.CHAIN_APPROX_SIMPLE)
cloneImage,contours,heriachy = cv.findContours(binary,cv.RETR_TREE,cv.CHAIN_APPROX_SIMPLE)    #RETR_TREE包含檢測內部
返回一個元組,內部有三個元素
<class 'numpy.ndarray'>
<class 'list'>
<class 'numpy.ndarray'>
第一個返回值:cloneImage是我們傳入的二值化圖像
第二個返回值:contours是一個列表,是輪廓本身,含有輪廓上面的各個點的位置信息
第三個返回值:heriachy是每條輪廓對應的屬性

(二)drawContours繪制輪廓

cv.drawContours(image,contours,i,(0,0,255),2)
cv.drawContours(image,contours,i,(0,0,255),-1)
def drawContours(image, contours, contourIdx, color, thickness=None, lineType=None, hierarchy=None, maxLevel=None, offset=None): # real signature unknown; restored from __doc__
1.image:輸入輸出圖像,Mat類型即可 
2.contours:使用findContours檢測到的輪廓數據,每個輪廓以點向量的形式存儲
3.contourIdx:繪制輪廓的只是變量,如果為負值則繪制所有輸入輪廓 
4.color:輪廓顏色 
5.thickness:繪制輪廓所用線條粗細度,如果值為負值,則在輪廓內部繪制 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM