OpenCV轮廓:更多功能

目标

在本章中,我们将了解

  • 凸性缺陷及其查找方法。
  • 求点到多边形的最短距离
  • 匹配不同形状

理论与代码

1.凸性缺陷

物体与船体的任何偏差都可视为凸性缺陷。

OpenCV附带了一个现成的功能,cv2.convexityDefects()。基本函数调用如下所示:

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

它返回一个数组,其中每一行包含这些值-[起点、终点、最远点、离最远点的近似距离]。我们可以用图像来可视化它。我们画一条线连接起点和终点,然后在最远的点画一个圆。记住,返回的前三个值是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()

并看到结果:

Convexity Defects

2.点多边形检验

该函数求出图像中的点与轮廓之间的最短距离。当点在等高线外时,返回负距离;当点在内时,返回正距离;如果点在等高线上,则返回零距离。

例如,我们可以检查点(50,50)如下:

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

在函数中,第三个参数是measureDist。如果是True的话,找到符号距离。如果是False,它将查找该点是在等高线内还是外部还是在等高线上(分别返回+1、-1、0)。

3.匹配形状

OpenCV附带了一个函数cv2.mediaShapes()这使得我们能够比较两种形状,或者两种等高线,并返回一个显示相似性的度量。结果越低,匹配越好。 

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

我试着用以下不同的形状来匹配形状:

Match Shapes

我得到了以下结果:

  • Matching Image A with itself = 0.0
  • Matching Image A with Image B = 0.001946
  • Matching Image A with Image C = 0.326911

看,即使是图像旋转对这个比较也没有太大的影响。

猜你喜欢

转载自blog.csdn.net/rongpeisheng666/article/details/81632097