OpenCV-Python教程:21.轮廓:更多函数

理论和代码

1.凸面缺陷

OpenCV提供了现成的函数来做这个,cv2.convexityDefects().

hull=cv2.convexHull(cnt,returnPoints=False)
defects=cv2.convexityDefects(cnt,hull)

注意:
我们要传returnPoints = False来找凸形外壳。

它返回了一个数组,每行包含这些值:[start point, end point, farthest point, approximate distance to farthest point].我们可以用图像来显示他们。我们画根线把start point和end point连起来。然后画一个圆在最远点。记住最前三个返回值是cnt的索引,所以我们我们得从cnt里拿出这些值

import cv2
import numpy as np

img = cv2.imread('star.jpg')
img_gray = cv2.cvtColor(img,cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(img_gray, 127, 255,0)
contours,hierarchy = cv2.findContours(thresh,2,1)
cnt = contours[0]

hull = cv2.convexHull(cnt,returnPoints = False)
defects = cv2.convexityDefects(cnt,hull)

for i in range(defects.shape[0]):
    s,e,f,d = defects[i,0]
    start = tuple(cnt[s][0])
    end = tuple(cnt[e][0])
    far = tuple(cnt[f][0])
    cv2.line(img,start,end,[0,255,0],2)
    cv2.circle(img,far,5,[0,0,255],-1)

cv2.imshow('img',img)
cv2.waitKey(0)
cv2.destroyAllWindows()

结果:

OpenCV-Python教程:21.轮廓:更多函数_第1张图片

2.Point Polygon Test

这个函数找到图像里的点和轮廓之间的最短距离。它返回的距离当点在轮廓外的时候是负值,当点在轮廓内是正值,如果在轮廓上是0

比如,我们可以检查(50, 50)这个点:

dist=cv2.pointPolygonTest(cnt,(50,50),True)

在这个函数里,第三个参数是measureDist, 如果为True,是找带符号的距离。如果为False,会找点是否在内,外,或轮廓上(会相应返回+1, -1, 0)

注意:
如果你不想找距离,确保第三个参数是False,因为,这是个耗时的处理。所以,用False会得到2-3倍的提速

3.匹配形状

OpenCV提供一个函数cv2.matchShapes()来让我们可以比较两个形状,或者两个轮廓来返回一个量表示相似度。结果越低,越相似,它是根据hu矩来计算的。不同的计算方法在文档里有介绍。

import cv2
import numpy as np

img1 = cv2.imread('star.jpg',0)
img2 = cv2.imread('star2.jpg',0)

ret, thresh = cv2.threshold(img1, 127, 255,0)
ret, thresh2 = cv2.threshold(img2, 127, 255,0)
contours,hierarchy = cv2.findContours(thresh,2,1)
cnt1 = contours[0]
contours,hierarchy = cv2.findContours(thresh2,2,1)
cnt2 = contours[0]

ret = cv2.matchShapes(cnt1,cnt2,1,0.0)
print ret

尝试匹配一下图形:

OpenCV-Python教程:21.轮廓:更多函数_第2张图片

得到的结果如下:

·用图形A和自己比较,得到0.0

·用图形A和B匹配,得到0.001946

·用A匹配C = 0.326911

你可能感兴趣的:(OpenCV-Python教程:21.轮廓:更多函数)