程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式師世界 >> 編程語言 >  >> 更多編程語言 >> Python

OpenCV-Python教程:查找輪廓、繪制輪廓

編輯:Python

原文鏈接:http://www.juzicode.com/opencv-python-findcontours-drawcontours

返回Opencv-Python教程

圖像輪廓用來描述圖像中連續的點,它們有同樣的顏色和灰度級。為了更精確地進行檢測,在查找輪廓前需要先將圖像做二值化處理或者使用canny邊沿檢測。在OpenCV中輪廓檢測只查找白色目標,黑色背景會被忽略。

1、查找輪廓 findContours()

contours,hierarchy=cv2.findContours(image,mode,method[,contours[,hierarchy[,offset]]])
  • 參數含義:
  • image:輸入圖像,8bit單通道;圖像元素的值為0表示背景,非0值表示前景,為了精確查找輪廓,最好對原始圖像做二值化處理。如果mode參數為RETR_CCOMP或RETR_FLOODFILL輸入圖像也可以是32bit單通道圖像(CV_32SC1)。但是floodfill不支持cv-8u類型
  • mode:輪廓提取模式。
  • method:輪廓近似方法。
  • contours:找到的輪廓。
  • hierarchy:找到輪廓層次結構。
  • offset:偏移值,使用ROI時用來計算原始位置。

mode的名稱和含義:

mode含義 cv2.RETR_EXTERNAL只提取外部輪廓,設置hierarchy[i][2]=hierarchy[i][3]=-1 cv2.RETR_LIST提取所有輪廓,不包含輪廓間的層次關系 cv2.RETR_CCOMP提取所有輪廓,包含2層層次關系,頂層是外圍邊界,底層是內部hole。如果有多層嵌套,仍然按照2層組織。 cv2.RETR_TREE按照完整的層次關系組織 cv2.RETR_FLOODFILL

method 的名稱和含義:

method含義cv2.CHAIN_APPROX_NONE存儲所有的邊間點,不管是垂直方向、水平方向或者對角線方向cv2.CHAIN_APPROX_SIMPLE垂直方向、水平方向或對角線方向只保留終點,比如一個長方形就只包含4個頂點cv2.CHAIN_APPROX_TC89_L1使用teh-Chini近似算法cv2.CHAIN_APPROX_TC89_KCOS使用teh-Chini近似算法

下面是一個查找輪廓的例子,讀入圖像,灰度化後再進行二值化,然後調用findContours()查找輪廓:

import numpy as np
import cv2
print('VX公眾號: 桔子code / juzicode.com')
#讀入圖像、灰度、二值化
img_src = cv2.imread('..\\samples\\picture\\contours1.bmp')
img_gray = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY)
val, img_bin = cv2.threshold(img_gray,127,255, cv2.THRESH_BINARY)
#cv2.imwrite('contours-bin.bmp',img_bin)
#查找輪廓
contours, hierarchy=cv2.findContours(img_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE )
print('contours:',contours)
print('type(contours):',type(contours))
print('len(contours):',len(contours))
print('type(contours[0]):',type(contours[0]))
print('contours[0].shape:',contours[0].shape)
print('hierarchy:',hierarchy)
print('type(hierarchy):',type(hierarchy))
print('len(hierarchy):',len(hierarchy))
print('hierarchy.shape:',hierarchy.shape)

運行結果:

VX公眾號: 桔子code / juzicode.com
contours: [array([[[159, 150]],
[[159, 241]],
[[307, 241]],
[[307, 150]]], dtype=int32), array([[[330, 28]],
[[330, 100]],
[[434, 100]],
[[434, 28]]], dtype=int32), array([[[ 23, 20]],
[[ 23, 114]],
[[172, 114]],
[[172, 20]]], dtype=int32)]
type(contours): <class 'list'>
len(contours): 3
type(contours[0]): <class 'numpy.ndarray'>
contours[0].shape: (4, 1, 2)
hierarchy: [[[ 1 -1 -1 -1]
[ 2 0 -1 -1]
[-1 1 -1 -1]]]
type(hierarchy): <class 'numpy.ndarray'>
len(hierarchy): 1
hierarchy.shape: (1, 3, 4)

contours是找到的輪廓列表,是由n個輪廓組成的list,每個輪廓是一個numpy數組,它的shape為(m,1,2),m為輪廓構成的像素的個數,每個點有2個數值,分別為x和y坐標。

hierarchy的shape為(1,n,4),n對應contours的個數n,所以要訪問第i個輪廓的hierarchy時用hierarchy[0][i]表示。每個hierarchy的元素有4個值組成,依次為next,previous,first child和parent,表示下一個節點,上一個節點,第一個子節點,父節點。

2、繪制輪廓 drawContours

drawContours(image,contours,contourIdx,color[,thickness[,lineType[,hierarchy[,maxLevel[,offset]]]]])->image
  • 參數含義:
  • image:要繪制邊框的圖像,調用後會修改該圖像。
  • contours:輪廓列表,一般傳入findContours()找到的邊框。
  • contourIdx:contours的索引,也就是要表示的第幾個邊框,如果要繪制所有的邊框,設置為負數即可。
  • color:顏色,bgr三個參數構成的tuple。
  • thickness:邊框的寬度。
  • lineType:邊界連線類型。
  • hierarchy:依賴maxLevel使用,如果maxLevel設置為1和2時用到該參數,
  • maxLevel:
  • offset:邊框偏移位置

下面這個例子查找輪廓後依次繪制輪廓:

import numpy as np
import cv2
print('VX公眾號: 桔子code / juzicode.com')
#讀入圖像、灰度、二值化
img_src = cv2.imread('..\\samples\\picture\\contours1.bmp')
cv2.imshow('img_src',img_src)
img_gray = cv2.cvtColor(img_src, cv2.COLOR_BGR2GRAY)
val, img_bin = cv2.threshold(img_gray,127,255,cv2.THRESH_BINARY)
#查找輪廓
contours, hierarchy=cv2.findContours(img_bin, cv2.RETR_EXTERNAL, cv2.CHAIN_APPROX_SIMPLE )
print('len(contours):',len(contours))
#繪制輪廓
for ind in range(len(contours)):
cv2.drawContours(img_src, contours, ind, (0,0,255), 3)
cv2.imshow('con',img_src)
cv2.waitKey()

運行結果:

還可以將contourIdx設置為-1,一次性繪制所有輪廓:

#設置為-1,繪制所有輪廓
cv2.drawContours(img_src, contours, -1, (0,0,255), 3)
cv2.imshow('con',img_src)
cv2.waitKey()

設置offset參數:

cv2.drawContours(img_src, contours, -1, (0,0,255), 3, offset=(10,10))

繪制的邊框整體偏移了offset個像素:

擴展閱讀:

  1. OpenCV-Python教程

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式師世界 All Rights Reserved