【OpenCV学习笔记22】- OpenCV中的轮廓 - 开始了解轮廓

本文是关于OpenCV官方文档中图像处理的学习笔记,介绍了轮廓的概念、findContours()和drawContours()函数的使用,强调了在二值图像上进行轮廓查找的重要性,并展示了如何运用轮廓近似法优化内存。
摘要由CSDN通过智能技术生成

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

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

内容

什么是轮廓?

轮廓可以简单地解释为连接所有连续点(沿着边界)的曲线,具有相同的颜色或强度。轮廓是形状分析以及物体检测和识别的有用工具。

  • 为了获得更高的准确性,请使用二值图像。因此,在找到轮廓之前,请应用阈值或精明的边缘检测。
  • 从 OpenCV 3.2 开始,findContours()不再修改源图像。
  • 在 OpenCV 中,寻找轮廓就像从黑色背景中寻找白色物体。所以请记住,要找到的对象应该是白色的,背景应该是黑色的。

让我们看看如何找到二值图像的轮廓:

示例代码:

# OpenCV中的轮廓
# 轮廓:开始
# 什么是轮廓?
import cv2

im = cv2.imread('')
assert im is not None, "file could not be read, check with os.path.exists()"
imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
contours, hierarchy = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)

我们可以看到 *cv2.findContours()* 函数中有三个参数,第一个是源图像,第二个是轮廓检索模式,第三个是轮廓近似方法。它输出轮廓和层次结构。Contours 是图像中所有轮廓的 Python 列表。每个单独的轮廓都是对象边界点的 (x,y) 坐标的 Numpy 数组。

笔记
稍后我们将详细讨论第二个和第三个参数以及层次结构。在那之前,代码示例中赋予它们的值将适用于所有图像。

如何绘制轮廓?

要绘制轮廓,使用 cv2.drawContours 函数。只要有边界点,它也可用于绘制任何形状。它的第一个参数是源图像,第二个参数是作为 Python 列表传递的轮廓,第三个参数是轮廓索引(在绘制单个轮廓时很有用。要绘制所有轮廓,请传递 -1),其余参数是颜色、厚度ETC。

  • 要绘制图像中的所有轮廓:
cv2.drawContours(img, contours, -1, (0,255,0), 3)
  • 要绘制单个轮廓,请说第四个轮廓:
cv2.drawContours(img, contours, 3, (0,255,0), 3)
  • 但大多数时候,下面的方法会很有用:
cnt = contours[4]
cv2.drawContours(img, [cnt], 0, (0,255,0), 3)

笔记
最后两种方法是相同的,但是当你继续前进时,你会发现最后一种更有用。

轮廓近似法

这是 cv2.findContours 函数中的第三个参数。它实际上代表什么?

上面我们说过,轮廓是具有相同强度的形状的边界。它存储形状边界的 (x,y) 坐标。但它存储了所有坐标吗?这是由该轮廓近似方法指定的。

如果传递 cv2.CHAIN_APPROX_NONE ,则存储所有边界点。但实际上我们需要所有的点吗?例如,您找到了一条直线的轮廓。您需要直线上的所有点来表示该直线吗?不,我们只需要该线的两个端点。这就是 cv2.CHAIN_APPROX_SIMPLE 的作用。它删除所有冗余点并压缩轮廓,从而节省内存。

下面的矩形图像演示了这种技术。只需在轮廓数组中的所有坐标上画一个圆(以蓝色绘制)。第一张图显示了我使用 cv2.CHAIN_APPROX_NONE 得到的点(734 点),第二张图显示了我使用 cv2.CHAIN_APPROX_SIMPLE 得到的点(仅 4 点)。看看,它节省了多少内存!

示例代码:

# OpenCV中的轮廓
# 轮廓:开始
# 轮廓近似法
import cv2

im = cv2.imread('../image/3.9.1.png')
assert im is not None, "file could not be read, check with os.path.exists()"
imgray = cv2.cvtColor(im, cv2.COLOR_BGR2GRAY)
ret, thresh = cv2.threshold(imgray, 127, 255, 0)
contours1, hierarchy1 = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_NONE)
contours2, hierarchy2 = cv2.findContours(thresh, cv2.RETR_TREE, cv2.CHAIN_APPROX_SIMPLE)
im2 = im.copy()
for contour in contours1[0]:
    cv2.circle(im, contour[0], 1, (255, 0, 0), -1)

for contour in contours2[0]:
    cv2.circle(im2, contour[0], 2, (255, 0, 0), -1)

cv2.imshow("im", im)
cv2.waitKey(0)
cv2.imshow("im2", im2)
cv2.waitKey(0)
cv2.destroyAllWindows()

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

夜七天

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

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

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

打赏作者

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

抵扣说明:

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

余额充值