Opencv中cvFindContours函數使用


如上圖,一共有6個contour(編號爲0-5的橢圓)存放在contours中,對應的hierarchy與contour數目相同。contours中存放則每個contour的點。輪廓點的具體存放方式根據method變量的取值不同而不同。

根據len(contours),知道一共有多少個contour

len(contours[index]),知道第index個contour中一共有多少個點。

hierarchy是一個大小爲 1 *  len(contour)* 4 的python array,裏面存放的是各個contours的關係,等級、從屬關係。hierarchy[0][i][0], hierarchy[0][i][1], hierarchy[0][i][2], hierarchy[0][i][3]分別表示第i個contour的next contour, previous contour, first child contour, parent contour。

上圖爲例:

1、當mode值對應爲CV_RETR_TREE,其對應的值見下圖


在Tree的等級分層情況下,上圖被分爲三個等級,分別以不同顏色表示,其中最上層爲黑色,然後紅、綠。其中3、4爲1的chlid,3爲1的first child,即1爲3的parent。5又爲3的first child等等,其next,和previous僅指向同一層的contour。以此類推。其樹形結構爲:


2、當mode值爲CV_RETR_CCOMP時,只有兩個等級,即連通域的外圍邊界(external boundaries of the components)爲上層,次層爲洞的內層邊界(boundaries of the holes),如果holes中仍然有聯通域,則認爲此聯通域邊界爲上層的外圍邊界。

在Ccomp的分層下,所有的next和previous指向同一層次的contour,即只有兩層,理論上next中只有兩個值爲 -1,但實際情況並非如此,在上圖中,0,1,2,5爲top level,而3,4爲second level,如果5中還有一個contour,則又是一個新的level,由於opencv只考慮了兩層contour嵌套的情況,及1中嵌套3,3中嵌套5這種情況,而5中繼續嵌套contour的情況,似乎沒有考慮進去。由於沒有考慮這種情況,所以嵌套較多時,仍會出現不止兩個level。

3、當mode值爲CV_RETR_LIST 時,存放所有輪廓,hierarchy沒有任何作用,first child 和 parent 的值都爲 -1。

4、當mode值爲CV_CV_RETR_EXTERNAL 時,hierarchy也沒有任何作用。其只存放最外層輪廓,若爲上圖,及爲輪廓1,2,3.


對於參數method:

1、CV_CHAIN_APPROX_NONE 時,存放所有邊界點,及內存中的任意相鄰的兩點,在圖像上也是水平、垂直或斜對角相鄰。

2、CV_CHAIN_APPROX_SIMPLE 時,壓縮水平方向、垂直和斜對角方向的線段,僅存放endpoint。例如一個水平放置的矩形,其只存放四個頂點。 

import numpy as np
import cv2

img = cv2.imread('testcontours1.bmp')
imgray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,thresh = cv2.threshold(imgray, 127, 255, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE ,cv2.CHAIN_APPROX_SIMPLE)

print len(contours)
print len(contours[0])
print contours,'--------'
print hierarchy,'********'
output = np.zeros(img.shape,dtype = np.uint8)
cv2.drawContours(output, contours,-1,(0,255,0),2)
cv2.imshow('whole',output)
cv2.waitKey(0)
output[:] = 0

flag = [1,]*len(contours)
for i in range(len(contours)):
    contour = contours[i].copy()
    index = i
    while flag[index] == 1:
        cv2.drawContours(output, [contour],-1,(0,255,0),2) #contours is a list
        flag[index] = 0
        print index
        index = hierarchy[0][index][0]  # dimension array
        cv2.imshow('stepbystep',output)
        cv2.waitKey(0)
        if index == -1:
            print index
            break
        else:
            contour = contours[index]

測試圖片:




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章