【OpenCV学习笔记25】- OpenCV中的轮廓 - 轮廓:更多的功能

这是对于 OpenCV 官方文档中 图像处理 的学习笔记。学习笔记中会记录官方给出的例子,也会给出自己根据官方的例子完成的更改代码,同样彩蛋的实现也会结合多个知识点一起实现一些小功能,来帮助我们对学会的知识点进行结合应用。
如果有喜欢我笔记的请麻烦帮我关注、点赞、评论。谢谢诸位。

学习笔记:
学习笔记目录里面会收录我关于OpenCV系列学习笔记博文,大家如果有什么不懂的可以通过阅读我的学习笔记进行学习。
【OpenCV学习笔记】- 学习笔记目录

内容

  • 凸性缺陷以及如何发现它们。
  • 求点到多边形的最短距离
  • 搭配不同的形状

理论和代码

1.凸包缺陷

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

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

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

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

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

示例代码:

# OpenCV中的轮廓
# 轮廓:更多功能
# 1.凸包缺陷
import cv2 as cv

img = cv.imread('../image/3.9.3.png')
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.imshow('img', img)
    cv.waitKey(0)
    cv.circle(img, far, 5, [0, 0, 255], -1)
    cv.imshow('img', img)
    cv.waitKey(0)

cv.waitKey(0)
cv.destroyAllWindows()

效果图:
在这里插入图片描述

2.点多边形测试

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

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

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

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

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

3.匹配形状

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

示例代码:

# OpenCV中的轮廓
# 轮廓:更多功能
# 3.匹配形状
import cv2 as cv

img1 = cv.imread('../image/3.9.3-1.png', 0)
img2 = cv.imread('../image/3.9.3-2.png', 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]
cnt3 = contours[1]
cnt4 = contours[2]
ret = cv.matchShapes(cnt1, cnt2, 1, 0.0)
print(ret)
ret = cv.matchShapes(cnt1, cnt3, 1, 0.0)
print(ret)
ret = cv.matchShapes(cnt1, cnt4, 1, 0.0)
print(ret)

原图:
在这里插入图片描述
在这里插入图片描述

命令行/控制台输出:

0.2916606851092495
0.006417678155163753
0.0

我得到以下结果:

  • 图像和本身匹配= 0.0
  • 将图像与旋转图匹配= 0.006417678155163753
  • 将图像与其他图像匹配= 0.2916606851092495

即使图像旋转也不会对该比较产生太大影响。

笔记 Hu-矩是对平移、旋转和缩放不变的七个矩。第七个是倾斜不变的。这些值可以使用cv.HuMoments()函数找到。

彩蛋(彩蛋我会在后面进行更新)

  1. 检查 cv.pointPolygonTest() 的文档,您可以找到红色和蓝色的漂亮图像。它表示所有像素到其上白色曲线的距离。曲线内的所有像素都呈蓝色,具体取决于距离。同样,外部点是红色的。轮廓边缘用白色标记。所以问题很简单。编写代码来创建这样的距离表示。
  2. 使用 cv.matchShapes() 比较数字或字母的图像。 (这将是迈向 OCR 的简单一步)
  • 17
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

夜七天

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值