(ง •_•)ง[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)

(ง •_•)ง[Python3 OpenCV4]14.轮廓_第1张图片

轮廓特征

函数介绍

  • 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

你可能感兴趣的:(#,[,python3-opencv4,])