cv.findContours()
參數:
① 要尋找輪廓的圖像 只能傳入二值圖像,不是灰度圖像
② 輪廓的檢索模式,有四種:
cv2.RETR_EXTERNAL表示只檢測外輪廓
cv2.RETR_LIST檢測的輪廓不建立等級關系
cv2.RETR_CCOMP建立兩個等級的輪廓,上面的一層為外邊界,里面的一層為內孔的邊界信息。如果內孔內還有一個連通物體,這個物體的邊界也在頂層
cv2.RETR_TREE建立一個等級樹結構的輪廓
③ 輪廓的近似辦法
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],分別表示后一個輪廓、前一個輪廓、父輪廓、內嵌輪廓的索引編號,如果沒有對應項,則該值為負數
坑點!!!:
出現如下錯誤
ValueError: need more than 2 values to unpack
在Opencv4.0中 cv.findContours()的返回值以從三個變為二個,見如下官方文檔

查找邊框及對圓形、矩形進行畫框的程序如下:
import cv2 import numpy as np # 讀入圖像 img = cv2.imread(r"D:\360MoveData\Users\KID\Desktop\1.jpg", cv2.IMREAD_UNCHANGED) # 二值化 ret, thresh = cv2.threshold( cv2.cvtColor(img.copy(), cv2.COLOR_BGR2GRAY), # 轉換為灰度圖像, 130, 255, # 大於130的改為255 否則改為0 cv2.THRESH_BINARY) # 黑白二值化 # 搜索輪廓 contours, hierarchy = cv2.findContours( thresh, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE) for c in contours: x, y, w, h = cv2.boundingRect(c) """ 傳入一個輪廓圖像,返回 x y 是左上角的點, w和h是矩形邊框的寬度和高度 """ cv2.rectangle(img, (x, y), (x+w, y+h), (0, 255, 0), 2) """ 畫出矩形 img 是要畫出輪廓的原圖 (x, y) 是左上角點的坐標 (x+w, y+h) 是右下角的坐標 0,255,0)是畫線對應的rgb顏色 2 是畫出線的寬度 """ # 獲得最小的矩形輪廓 可能帶旋轉角度 rect = cv2.minAreaRect(c) # 計算最小區域的坐標 box = cv2.boxPoints(rect) # 坐標規范化為整數 box = np.int0(box) # 畫出輪廓 cv2.drawContours(img, [box], 0, (0, 0, 255), 3) # 計算最小封閉圓形的中心和半徑 (x, y), radius = cv2.minEnclosingCircle(c) # 轉換成整數 center = (int(x), int(y)) radius = int(radius) # 畫出圓形 img = cv2.circle(img, center, radius, (0, 255, 0), 2) # 畫出輪廓 cv2.drawContours(img, contours, -1, (255, 0, 0), 1) cv2.imshow("contours", img) cv2.waitKey() cv2.destroyAllWindows()
