2021-10-25 opencv形态学变换

腐蚀膨胀

腐蚀的基本概念就像土壤侵蚀一样,只侵蚀前景对象的边界(总是尽量保持前景为白色)。那它有什么作用呢?内核在图像中滑动(如二维卷积)。只有当内核下的所有像素都为 1 时,原始图像中的像素(1 或 0)才会被视为 1,否则会被侵蚀(变为零)。所以根据内核的大小,边界附近的所有像素都将被丢弃。因此,前景对象的厚度或大小在图像中减少或只是白色区域减少。它有助于消除小的白色噪音(如我们在“颜色空间”一章中所看到的),分离两个连接的对象等。
膨胀与腐蚀正好相反。这里,如果内核下至少有一个像素为“1”,则像素元素为“1”。所以它会增加图像中的白色区域,或者增加前景对象的大小。通常情况下,在去除噪音的情况下,腐蚀后会膨胀。因为,腐蚀消除了白噪声,但它也缩小了我们的对象。所以我们扩大它。由于噪音消失了,它们不会再回来,但我们的目标区域会增加到腐蚀之前的状态。它还可用于连接对象的断开部分。

代码:

import cv2
import numpy as np
from matplotlib import pyplot as plt

img = cv2.imread('1.png', cv2.IMREAD_UNCHANGED)
Erode = cv2.erode(img, np.ones((5,5), dtype=int))
Dilate = cv2.dilate(img, np.ones((5, 5), dtype=int))

plt.subplot(131), plt.imshow(img), plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(132), plt.imshow(Erode), plt.title('Erode')
plt.xticks([]), plt.yticks([])
plt.subplot(133), plt.imshow(Dilate), plt.title('Dilate')
plt.xticks([]), plt.yticks([])
plt.show()

结果:
在这里插入图片描述
可见腐蚀将白色线条变细,膨胀将白色线条变粗。

开运算

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

代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('2.png', cv2.IMREAD_UNCHANGED)
open = cv2.morphologyEx(img, cv2.MORPH_OPEN, np.ones((5, 5)))
plt.subplot(121)
plt.title('Origin')
plt.imshow(img)
plt.subplot(122)
plt.title('Open')
plt.imshow(open)
plt.show()

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

可见开运算消除了周围的白点噪声。

闭运算

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

代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('3.png', cv2.IMREAD_UNCHANGED)
close = cv2.morphologyEx(img, cv2.MORPH_CLOSE, np.ones((5, 5)))
plt.subplot(121)
plt.title('Origin')
plt.imshow(img)
plt.subplot(122)
plt.title('Close')
plt.imshow(close)
plt.show()

结果:
在这里插入图片描述
可见图中黑色噪声点已被消除。

形态梯度

它是图像的膨胀和腐蚀之间的差值,结果将类似于对象的轮廓。

顶帽

它是原图像和原图像开运算结果的差值。

黑帽

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

形态梯度,顶帽,黑帽的代码:

import cv2
import numpy as np
import matplotlib.pyplot as plt

img = cv2.imread('1.png', cv2.IMREAD_UNCHANGED)
gradient = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, np.ones((5, 5)))
tophat = cv2.morphologyEx(img, cv2.MORPH_TOPHAT, np.ones((2, 2)))
blackhat = cv2.morphologyEx(img, cv2.MORPH_BLACKHAT, np.ones((2, 2)))
plt.subplot(221)
plt.title('Origin')
plt.xticks([]), plt.yticks([])
plt.imshow(img)
plt.subplot(222)
plt.title('Gradient')
plt.xticks([]), plt.yticks([])
plt.imshow(gradient)
plt.subplot(223)
plt.title('Tophat')
plt.xticks([]), plt.yticks([])
plt.imshow(tophat)
plt.subplot(224)
plt.title('Blackhat')
plt.xticks([]), plt.yticks([])
plt.imshow(blackhat)

plt.show()

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

结构元素

在前面的例子中,我们在 numpy 的帮助下手工创建了一个结构参量。它是长方形的。但在某些情况下,您可能需要椭圆/圆形的内核。因此,opencv 有一个函数,cv2.getStructuringElement()

代码:

import cv2

rect = cv2.getStructuringElement(cv2.MORPH_RECT, (5, 5))
ellipse = cv2.getStructuringElement(cv2.MORPH_ELLIPSE, (5, 5))
cross = cv2.getStructuringElement(cv2.MORPH_CROSS, (5, 5))
print('rect = \n', rect, '\n')
print('ellipse = \n', ellipse, '\n')
print('cross = \n', cross)

结果:
在这里插入图片描述
可见只要传递内核的形状和大小,就可以得到所需的内核。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

giegie界清流

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

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

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

打赏作者

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

抵扣说明:

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

余额充值