OpenCV-Python更多轮廓功能

学习找到凸包缺陷,pointPolygonTest,匹配不同的形状等。

在本章中,我们将学习

  • 凸性缺陷以及如何找到它们。
  • 查找点到多边形的最短距离
  • 匹配不同的形状

理论和代码

凸包缺陷

在第二章中,我们看到了关于轮廓的凸包。物体与该船体的任何偏离都可以视为凸包缺陷。

OpenCV带有一个现成的函数 cv.convexityDefect() 来查找该函数。基本的函数调用如下所示:

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

注意
请记住,在寻找凸包时,我们必须传递returnPoints = False,以便寻找凸缺陷。

它返回一个数组,其中每行包含这些值- [起点,终点,最远点,到最远点的近似距离]。我们可以使用图像对其进行可视化。我们画一条连接起点和终点的线,然后在最远的点画一个圆。请记住,返回的前三个值是cnt的索引。因此,我们必须从cnt带来这些值。

import cv2 as cv
import numpy as np
img = cv.imread('star.jpg')
img_gray = cv.cvtColor(img,cv.COLOR_BGR2GRAY)
ret,thresh = cv.threshold(img_gray, 127, 255,0)
contours,hierarchy = cv.findContours(thresh,2,1)
cnt = contours[0]
hull = cv.convexHull(cnt,returnPoints = False)
defects = cv.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])
    cv.line(img,start,end,[0,255,0],2)
    cv.circle(img,far,5,[0,0,255],-1)
cv.imshow('img',img)
cv.waitKey(0)
cv.destroyAllWindows()

并查看结果:

凸包缺陷

点多边形测试

此功能查找图像中的点与轮廓之间的最短距离。它返回的距离为:当点在轮廓外时为负;当点在轮廓内时为正;如果点在轮廓上,则返回零。

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

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

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

注意
如果您不想查找距离,请确保第三个参数为False,因为这是一个耗时的过程。因此,将其设置为False可使速度提高2-3倍。

匹配形状

OpenCV带有函数 cv.matchShapes(),使我们能够比较两个形状或两个轮廓,并返回显示相似性的度量。结果越低,匹配越好。它是基于 hu-moment 值计算的。文档中介绍了不同的测量方法。

import cv2 as cv
import numpy as np
img1 = cv.imread('star.jpg',0)
img2 = cv.imread('star2.jpg',0)
ret, thresh = cv.threshold(img1, 127, 255,0)
ret, thresh2 = cv.threshold(img2, 127, 255,0)
contours,hierarchy = cv.findContours(thresh,2,1)
cnt1 = contours[0]
contours,hierarchy = cv.findContours(thresh2,2,1)
cnt2 = contours[0]
ret = cv.matchShapes(cnt1,cnt2,1,0.0)
print( ret )

我尝试匹配以下给出的不同形状的形状:

匹配形状

我得到以下结果:

  • 匹配图像A本身= 0.0
  • 将图像A与图像B匹配= 0.001946
  • 将图像A与图像C匹配= 0.326911
    看,即使图像旋转也不会对该比较产生太大影响。

也可以看看
Hu-Moments是平移,旋转和缩放不变的七个矩。第七个是偏斜不变的。这些值可以使用 cv.HuMoments() 函数找到。

Camera课程

Python教程

Java教程

Web教程

数据库教程

图形图像教程

办公软件教程

Linux教程

计算机教程

大数据教程

开发工具教程