輪廓發現是基於圖像邊緣提取的基礎尋找對象輪廓的方法,所以邊緣提取的閾值選定會影響最終輪廓發現結果。
python實現
import cv2 import numpy as np __author__ = "boboa" def contours_demo(image): dst = cv2.GaussianBlur(image, (3, 3), 0) gray = cv2.cvtColor(dst, cv2.COLOR_BGR2GRAY) ret, thresh = cv2.threshold(gray, 0, 255, cv2.THRESH_BINARY | cv2.THRESH_OTSU) cv2.imshow("binary image", thresh) # 得到修改后的圖像,輪廓,輪廓的層次 cloneimage, contours, hierarchy = cv2.findContours(thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) """ cv2.findContours(image, mode, method, contours, hierarchy, offset) 參數: 1 要尋找輪廓的圖像 只能傳入二值圖像,不是灰度圖像 2 輪廓的檢索模式,有四種: cv2.RETR_EXTERNAL表示只檢測外輪廓 cv2.RETR_LIST檢測的輪廓不建立等級關系 cv2.RETR_CCOMP建立兩個等級的輪廓,上面的一層為外邊界,里面的一層為內孔的邊界信息。如果內孔內還有一個連通物體,這個物體的邊界也在頂層 cv2.RETR_TREE建立一個等級樹結構的輪廓 3 輪廓的近似辦法 cv2.CHAIN_APPROX_NONE存儲所有的輪廓點,相鄰的兩個點的像素位置差不超過1,即max(abs(x1-x2),abs(y2-y1))==1 cv2.CHAIN_APPROX_SIMPLE壓縮水平方向,垂直方向,對角線方向的元素,只保留該方向的終點坐標,例如一個矩形輪廓只需4個點來保存輪廓信息 返回值: contours:一個列表,每一項都是一個輪廓,不會存儲輪廓所有的點,只存儲能描述輪廓的點 hierarchy:一個ndarray, 元素數量和輪廓數量一樣, 每個輪廓contours[i]對應4個hierarchy元素hierarchy[i][0] ~hierarchy[i][3], 分別表示后一個輪廓、前一個輪廓、父輪廓、內嵌輪廓的索引編號,如果沒有對應項,則該值為負數 """ for i, contour in enumerate(contours): # 繪制輪廓 cv2.drawContours(image, contours, i, (0, 0, 255), 2) """ # 函數cv2.drawContours(image, contours, contourIdx, color, thickness, lineType, hierarchy, maxLevel, offset) # 第一個參數是一張圖片,可以是原圖或者其他。 # 第二個參數是輪廓,也可以說是cv2.findContours()找出來的點集,一個列表。 # 第三個參數是對輪廓(第二個參數)的索引,當需要繪制獨立輪廓時很有用,若要全部繪制可設為-1。 # 接下來的參數是輪廓的顏色和厚度 """ print(i) cv2.imshow("detect contours", image) if __name__ == "__main__": img = cv2.imread("image/circles.jpg") cv2.namedWindow("input image", cv2.WINDOW_AUTOSIZE) cv2.imshow("input image", img) contours_demo(img) cv2.waitKey(0) cv2.destroyAllWindows()
二值化圖像和檢測到的輪廓如下圖