【OpenCV学习笔记17】- 形态转换

发布时间:2024年01月19日

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

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

内容

  • 我们将学习不同的形态操作,如腐蚀、膨胀、开、闭等。
  • 我们将看到不同的函数,如: cv.erode()、 cv.dilate()、 cv.morphologyEx() 等。

理论

形态学变换是基于图像形状的一些简单操作。它通常在二值图像上执行。
它需要两个输入,一个是我们的原始图像,第二个是决定操作性质的结构元素或内核。
两个基本的形态学操作是腐蚀和膨胀。接下来如开,闭,梯度等也会介绍。在下图的帮助下,我们将逐一看到它们:
在这里插入图片描述

1、腐蚀

腐蚀的基本概念就像土壤侵蚀一样,只侵蚀前景对象的边界(总是尽量保持前景为白色)。那它有什么作用呢?内核在图像中滑动(如二维卷积)。只有当内核下的所有像素都为 1 时,原始图像中的像素(1 或 0)才会被视为 1,否则会被侵蚀(变为零)。

所以根据内核的大小,边界附近的所有像素都将被丢弃。因此,前景对象的厚度或大小在图像中减少或只是白色区域减少。它有助于消除小的白色噪音(如我们在“颜色空间”一章中所看到的),分离两个连接的对象等。

作为一个例子,我将使用一个 5x5 内核,内核元素均为1。让我们看看它是如何工作的:

示例代码:

# 形态转换
# 理论
# 1.腐蚀
import cv2
from matplotlib import pyplot as plt

img = cv2.imread('../image/3.5.1.png')
blur = cv2.blur(img, (5, 5))
plt.subplot(121), plt.imshow(img), plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(blur), plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()

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

2、膨胀

它与腐蚀正好相反。这里,如果内核下至少有一个像素为“1”,则像素元素为“1”。所以它会增加图像中的白色区域,或者增加前景对象的大小。通常情况下,在去除噪音的情况下,腐蚀后会膨胀。因为,腐蚀消除了白噪声,但它也缩小了我们的对象。所以我们扩大它。由于噪音消失了,它们不会再回来,但我们的目标区域会增加到腐蚀之前的状态。它还可用于连接对象的断开部分。

示例代码:

# 形态转换
# 理论
# 2.膨胀
import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('../image/3.5.1.png')
kernel = np.ones((5, 5), np.float32)
dilation = cv2.dilate(img, kernel, iterations=1)
plt.subplot(121), plt.imshow(img), plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(dilation), plt.title('Dilation')
plt.xticks([]), plt.yticks([])
plt.show()

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

3、开运算

开只是腐蚀的另一个名称,随后是膨胀。正如我们上面所解释的,它对消除噪音很有用。在这里,我们使用 cv2.morphologyEx()

示例代码:

# 形态转换
# 理论
# 3.开运算
import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('../image/3.5.2.png')
kernel = np.ones((5, 5), np.float32)
opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)
plt.subplot(121), plt.imshow(img), plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(opening), plt.title('Opening')
plt.xticks([]), plt.yticks([])
plt.show()

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

4、闭运算

关闭与打开相反,膨胀后腐蚀。它在填充前景对象内的小孔或对象上的小黑点时很有用。

示例代码:

# 形态转换
# 理论
# 4.闭运算
import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('../image/3.5.3.png')
kernel = np.ones((5, 5), np.float32)
closing = cv2.morphologyEx(img, cv2.MORPH_CLOSE, kernel)
plt.subplot(121), plt.imshow(img), plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(closing), plt.title('Closing')
plt.xticks([]), plt.yticks([])
plt.show()

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

5、形态梯度

它是图像的膨胀和腐蚀之间的差值。

结果将类似于对象的轮廓。

示例代码:

# 形态转换
# 理论
# 5.形态梯度
import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('../image/3.5.1.png')
kernel = np.ones((5, 5), np.float32)
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)
plt.subplot(121), plt.imshow(img), plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(gradient), plt.title('Gradient')
plt.xticks([]), plt.yticks([])
plt.show()

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

6、顶帽

它是原图像和原图像开运算结果的差值。下面是 9x9 核的例子。

示例代码:

# 形态转换
# 理论
# 6.顶帽
import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('../image/3.5.1.png')
kernel = np.ones((9, 9), np.float32)
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, kernel)
plt.subplot(121), plt.imshow(img), plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(tophat), plt.title('Tophat')
plt.xticks([]), plt.yticks([])
plt.show()

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

7、黑帽

它是原图像和原图像的闭的差值。

示例代码:

# 形态转换
# 理论
# 7.黑帽
import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('../image/3.5.1.png')
kernel = np.ones((9, 9), np.float32)
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, kernel)
plt.subplot(121), plt.imshow(img), plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122), plt.imshow(blackhat), plt.title('Blackhat')
plt.xticks([]), plt.yticks([])
plt.show()

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

结构元素

在前面的例子中,我们在 numpy 的帮助下手工创建了一个结构参量。它是长方形的。但在某些情况下,您可能需要椭圆/圆形的内核。因此,opencv 有一个函数,cv.getStructuringElement() 。只要传递内核的形状和大小,就可以得到所需的内核。
示例代码:

# 形态转换
# 结构元素
import cv2

print(cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5)))
print(cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5)))
print(cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5)))

控制台/命令行输出:

[[1 1 1 1 1]
 [1 1 1 1 1]
 [1 1 1 1 1]
 [1 1 1 1 1]
 [1 1 1 1 1]]
 
[[0 0 1 0 0]
 [1 1 1 1 1]
 [1 1 1 1 1]
 [1 1 1 1 1]
 [0 0 1 0 0]]
 
[[0 0 1 0 0]
 [0 0 1 0 0]
 [1 1 1 1 1]
 [0 0 1 0 0]
 [0 0 1 0 0]]

其他信息

在 HIPR2 的 形态学操作

文章来源:https://blog.csdn.net/q664243624/article/details/135693461
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。