前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >opencv(4.5.3)-python(二十一)--轮廓更多功能

opencv(4.5.3)-python(二十一)--轮廓更多功能

作者头像
用户9875047
发布2022-12-07 10:19:21
2740
发布2022-12-07 10:19:21
举报
文章被收录于专栏:机器视觉全栈er机器视觉全栈er

翻译及二次校对:cvtutorials.com

目标

在本章中,我们将了解到:

  1. 1. 凸性缺陷以及如何找到它们。
  2. 2. 寻找从一个点到一个多边形的最短距离
  3. 3. 匹配不同的形状

理论和代码

  1. 1. 凸性缺陷

我们在关于轮廓的内容中看到了什么是凸面体。任何偏离这个凸包的物体都可以被认为是凸性缺陷。

OpenCV提供了一个现成的函数来寻找这个缺陷,即cv.convexityDefects()。一个基本的函数调用看起来如下。

代码语言:javascript
复制
hull = cv.convexHull(cnt,returnPoints = False)
defects = cv.convexityDefects(cnt,hull)

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

它返回一个数组,每一行都包含这些值 - [ 起始点,终点,最远点,到最远点的大致距离 ]。我们可以用一个图像将其可视化。我们画一条连接起点和终点的线,然后在最远点画一个圆。请记住,前三个返回值是cnt的索引。所以我们必须从cnt中获取这些值。

代码语言:javascript
复制
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()

然后看看结果:

  1. 1. 点多边形测试

这个函数找出图像中的一个点和一个轮廓线之间的最短距离。它返回的距离是:当点在轮廓线外时为负数,当点在轮廓线内时为正数,如果点在轮廓线上则为零。

例如,我们可以检查点(50,50),如下所示。

代码语言:javascript
复制
dist = cv.pointPolygonTest(cnt,(50,50),True)

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

注意:如果你不想找距离,确保第三个参数是False,因为这是一个耗时的过程。所以,把它设为假值可以使速度提高2-3倍。

  1. 1. 匹配形状

OpenCV有一个函数cv.matchShapes(),它使我们能够比较两个形状,或两个轮廓,并返回一个显示相似度的指标。结果越低,说明它的匹配度越高。它是根据hu-moment值来计算的。文档中解释了不同的测量方法。

代码语言:javascript
复制
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()函数找到。

练习

  1. 1. 查看cv.pointPolygonTest()的文档,你可以找到一个红蓝相间的漂亮图像。它代表了所有像素到上面的白色曲线的距离。曲线内的所有像素都是蓝色的,这取决于距离。同样地,外面的点是红色的。轮廓线的边缘用白色标记。所以问题很简单。写一段代码来创建这样的距离表示。
  2. 2. 用cv.matchShapes()比较数字或字母的图像。( 这将是走向OCR的一个简单步骤)
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-11-24,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 机器视觉全栈er 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档