(ง •_•)ง[Python3 OpenCV4]14.輪廓

輪廓與邊緣

輪廓:是一系列相連的點組成的曲線,代表了物體的基本外形
輪廓是連續的,可以用來分析物體的形態,比如物體的周長和麪積等,可以說邊緣包括輪廓。

邊緣並不全都連續

尋找輪廓的操作一般用於二值化圖,所以通常會使用閾值分割或Canny邊緣檢測先得到二值圖。

尋找輪廓是針對白色物體的,一定要保證物體是白色,而背景是黑色,不然很多人在尋找輪廓時會找到圖片最外面的一個框。

輪廓尋找方式

import numpy as np
import cv2

#讀取圖片
img = cv2.imread('doge.jpg')
#二值化,canny檢測
binaryImg = cv2.Canny(img,50,200)

#尋找輪廓
#也可以這麼寫:
#binary,contours, hierarchy = cv2.findContours(binaryImg,cv2.RETR_EXTERNAL,cv2.CHAIN_APPROX_SIMPLE) 
#這樣,可以直接用contours表示
h = cv2.findContours(binaryImg,cv2.RETR_TREE,cv2.CHAIN_APPROX_NONE)
#提取輪廓
contours = h[0]
#打印返回值,這是一個元組
print(type(h))
#打印輪廓類型,這是個列表
print(type(h[1]))
#查看輪廓數量
print (len(contours))

#創建白色幕布
temp = np.ones(binaryImg.shape,np.uint8)*255
#畫出輪廓:temp是白色幕布,contours是輪廓,-1表示全畫,然後是顏色,厚度
cv2.drawContours(temp,contours,-1,(0,255,0),3)

cv2.imshow("contours",temp)
cv2.waitKey(0)
cv2.destroyAllWindows()

RetrievalModes:

  • RETR_LIST:不建立輪廓間的子屬關係,也就是所有輪廓都屬於同一層級

不建立輪廓間的子屬關係,也就是所有輪廓都屬於同一層級

  • RETR_TREE:完整建立輪廓的層級從屬關係
  • RETR_EXTERNAL:只尋找最高層級的輪廓
  • RETR_CCOMP:它把所有的輪廓只分爲2個層級,不是外層的就是裏層的

ContourApproximationModes:

  • cv2.CHAIN_APPROX_NONE

存儲所有輪廓點。

  • cv2.CHAIN_APPROX_SIMPLE

儘可能少的像素點表示輪廓

  • cv2.CHAIN_APPROX_TC89_L1

應用THCH-鏈近似算法的一個特徵

  • cv2.CHAIN_APPROX_TC89_KCOS

應用THCH-鏈近似算法的一個特徵

查找輪廓

import cv2


img = cv2.imread('doge.jpg')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
#ret, binary = cv2.threshold(gray,127,255,cv2.THRESH_BINARY)
ret, thresh = cv2.threshold(img_gray, 0, 255, cv2.THRESH_BINARY_INV + cv2.THRESH_OTSU)

contours, hierarchy = cv2.findContours(thresh,cv2.RETR_TREE,cv2.CHAIN_APPROX_SIMPLE)
cv2.drawContours(img,contours,-1,(0,0,255),3)
 
cv2.imshow("img", img)
cv2.waitKey(0)

在這裏插入圖片描述

輪廓特徵

函數介紹

  • cv2.contourArea()算面積,cv2.arcLength()算周長,cv2.boundingRect()算外接矩。
  • cv2.minAreaRect()算最小外接矩,cv2.minEnclosingCircle()算最小外接圓。
  • cv2.matchShapes()進行形狀匹配。

多邊形逼近

import cv2
import numpy as np

# 1.先找到輪廓
import cv2
import numpy as np

# 1.先找到輪廓
img = cv2.imread('hand.png', 0)
_, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
contours, hierarchy = cv2.findContours(thresh, 3, 2)
cnt = contours[0]

# 2.進行多邊形逼近,得到多邊形的角點
approx = cv2.approxPolyDP(cnt, 3, True)

# 3.畫出多邊形
image = cv2.cvtColor(thresh, cv2.COLOR_GRAY2BGR)
cv2.polylines(image, [approx], True, (0, 255, 0), 2)
cv2.imshow("img",image)
cv2.waitKey(0)

凸包

凸包跟多邊形逼近很像,只不過它是物體最外層的”凸”多邊形:集合A內連接任意兩個點的直線都在A的內部,則稱集合A是凸形的。

# 1.先找到輪廓
img = cv2.imread('convex.jpg', 0)
_, thresh = cv2.threshold(img, 0, 255, cv2.THRESH_BINARY + cv2.THRESH_OTSU)
image, contours, hierarchy = cv2.findContours(thresh, 3, 2)
cnt = contours[0]

# 2.尋找凸包,得到凸包的角點
hull = cv2.convexHull(cnt)

# 3.繪製凸包
image = cv2.cvtColor(image, cv2.COLOR_GRAY2BGR)
cv2.polylines(image, [hull], True, (0, 255, 0), 2)

點到輪廓距離

dist = cv2.pointPolygonTest(cnt, (100, 100), True)  # -3.53
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章