OpenCV—Python 輪廓檢測 繪出矩形框(findContours\ boundingRect\rectangle


千萬注意opencv的輪廓檢測和邊緣檢測是兩碼事

本文鏈接:https://blog.csdn.net/wsp_1138886114/article/details/82945328

1 獲取輪廓

OpenCV2獲取輪廓主要是用 cv2.findContours()

import cv2

img = cv2.imread('wujiaoxing.png')
gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)
ret,binary = cv2.threshold(gray, 127, 255, cv2.THRESH_BINARY)

_,contours, hierarchy = cv2.findContours(binary, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

draw_img0 = cv2.drawContours(img.copy(),contours,0,(0,255,255),3)
draw_img1 = cv2.drawContours(img.copy(),contours,1,(255,0,255),3)
draw_img2 = cv2.drawContours(img.copy(),contours,2,(255,255,0),3)
draw_img3 = cv2.drawContours(img.copy(), contours, -1, (0, 0, 255), 3)


print ("contours:類型:",type(contours))
print ("第0 個contours:",type(contours[0]))
print ("contours 數量:",len(contours))

print ("contours[0]點的個數:",len(contours[0]))
print ("contours[1]點的個數:",len(contours[1]))

cv2.imshow("img", img)
cv2.imshow("draw_img0", draw_img0)
cv2.imshow("draw_img1", draw_img1)
cv2.imshow("draw_img2", draw_img2)
cv2.imshow("draw_img3", draw_img3)

cv2.waitKey(0)
cv2.destroyAllWindows()

輸出:
contours:類型: <class 'list'>
第0 個contours: <class 'numpy.ndarray'>
contours 數量: 3
contours[0]點的個數: 6
contours[1]點的個數: 74

  

其中,cv2.findContours() 的第二個參數主要有

cv2.RETR_LIST:檢測的輪廓不建立等級關系
cv2.RETR_TREE:L建立一個等級樹結構的輪廓。
cv2.RETR_CCOMP:建立兩個等級的輪廓,上面的一層為外邊界,里面的一層為內孔的邊界信息。
cv2.RETR_EXTERNAL:表示只檢測外輪廓
cv2.findContours() 的第三個參數 method為輪廓的近似辦法

cv2.CHAIN_APPROX_NONE存儲所有的輪廓點,相鄰的兩個點的像素位置差不超過1,即max(abs(x1-x2),abs(y2-y1))==1
cv2.CHAIN_APPROX_SIMPLE壓縮水平方向,垂直方向,對角線方向的元素,只保留該方向的終點坐標,例如一個矩形輪廓只需4個點來保存輪廓信息
cv2.CHAIN_APPROX_TC89_L1,CV_CHAIN_APPROX_TC89_KCOS使用teh-Chinl chain 近似算法
1.1 返回值:image, contours, hierarchy
contour返回值
cv2.findContours()函數首先返回一個list,list中每個元素都是圖像中的一個輪廓,用numpy中的ndarray表示。
hierarchy返回值
該函數還可返回一個可選的hiararchy結果,這是一個ndarray,其中的元素個數和輪廓個數相同,每個輪廓contours[i]對應4個hierarchy元素hierarchy[i][0] ~hierarchy[i][3],分別表示后一個輪廓、前一個輪廓、父輪廓、內嵌輪廓的索引編號,如果沒有對應項,則該值為負數。
2 繪出輪廓
cv2.drawContours()函數
cv2.drawContours(image, contours, contourIdx, color[, thickness[, lineType[, hierarchy[, maxLevel[, offset ]]]]])

第一個參數是指明在哪幅圖像上繪制輪廓;
第二個參數是輪廓本身,在Python中是一個list。
第三個參數指定繪制輪廓list中的哪條輪廓,如果是-1,則繪制其中的所有輪廓。后面的參數很簡單。其中thickness表明輪廓線的寬度,如果是-1(cv2.FILLED),則為填充模式。繪制參數將在以后獨立詳細介紹。
為了看到自己畫了哪些輪廓,可以使用 cv2.boundingRect()函數獲取輪廓的范圍,即左上角原點,以及他的高和寬。然后用cv2.rectangle()方法畫出矩形輪廓

"""
x, y, w, h = cv2.boundingRect(img)   
    參數:
    img  是一個二值圖
    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:         線寬
"""
for i in range(0,len(contours)):  
    x, y, w, h = cv2.boundingRect(contours[i])   
    cv2.rectangle(image, (x,y), (x+w,y+h), (153,153,0), 5) 

3 獲取輪廓區域

new_image=image[y+2:y+h-2,x+2:x+w-2]    # 先用y確定高,再用x確定寬
input_dir=("E:/cut_image/")
if not os.path.isdir(input_dir):
    os.makedirs(input_dir)
cv2.imwrite( nrootdir+str(i)+".jpg",newimage) 
print (i)

4 獲取物體最小外界矩陣
使用 cv2.minAreaRect(cnt) ,返回點集cnt的最小外接矩形,cnt是所要求最小外接矩形的點集數組或向量,這個點集不定個數。
其中:cnt = np.array([[x1,y1],[x2,y2],[x3,y3],[x4,y4]]) # 必須是array數組的形式

rect = cv2.minAreaRect(cnt) # 得到最小外接矩形的(中心(x,y), (寬,高), 旋轉角度)
box = np.int0(cv2.boxPoints(rect)) #通過box會出矩形框


免責聲明!

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



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