⚠️这个系列是自己瞎翻的,文法很丑,主要靠意会,跳着跳着捡重要的部分翻,翻错了不负责,就这样哈。
⚠️基于3.4.3,Morphological Transformations,附原文。
在这一章节,
形态变换是基于图像形状的一些简单操作。 它通常在二进制图像上执行。 它需要两个输入,一个是我们的原始图像,第二个是称为结构元素或内核,它决定了操作的性质。 两个基本的形态学运算符是侵蚀和膨胀。 然后它的变体形式如开放,闭合,梯度等等也发挥作用。 我们将在以下图片的帮助下逐一看到它们:
侵蚀的基本思想就像土壤侵蚀一样,它会侵蚀前景物体的边界(总是试图保持前景为白色)。它具体做了什么? 内核在图像中滑动(如在上节提到的2D卷积中那样)。只有当内核下的所有像素都是1时,原始图像中的像素(1或0)才会被认为是1,否则它会被侵蚀(变为零)。
所以那到底发生了啥,边界附近的取决于内核大小的所有像素都将被丢弃。 因此,前景对象的厚度或大小减小,或者图像中的白色区域减小。 它有助于消除小的白噪声(正如我们在色彩空间章节中看到的那样),分离两个连接的对象等。
这里,作为一个例子,我用一个完整的 5x5 内核。让我们看看它是如何工作的:
import cv2 as cv
import numpy as np
img = cv.imread('j.png',0)
kernel = np.ones((5,5),np.uint8)
erosion = cv.erode(img,kernel,iterations = 1)
结果:
它刚好于侵蚀相反。这里,如果内核下至少有一个像素元素是 '1' ,那我们就认为这个像素点为 '1' 。因此它令到图像上的白色区域或者前景的大小增加了。通常,在如去除噪声这样的情景下,侵蚀之后要用一次膨胀算法。因为,侵蚀虽然能去掉白噪声,但也会让我们的物体缩小。因此我们要(用膨胀算法把它再展开)。自从噪声(从侵蚀算法中)消失之后,它们就不会再(因为膨胀算法而)出现了。但我们的物体区域会增加,它也有助于连接物体的破碎部分。
dilation = cv.dilate(img,kernel,iterations = 1)
结果:
开放就是腐蚀之后接膨胀的另一种叫法。它有助于消除噪声,就像我们在上面解释的那样,这里我们使用 cv.morphologyEx() 方法。
opening = cv.morphologyEx(img, cv.MORPH_OPEN, kernel)
结果:
闭合与开放相反,膨胀之后接侵蚀。它有助于关闭掉前景对象上的小洞,或者对象上的小黑点。
closing = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)
结果:
梯度是一张图像膨胀和侵蚀的差。
这个结果看起来像是物体的外边线。
gradient = cv.morphologyEx(img, cv.MORPH_GRADIENT, kernel)
结果:
它是原图与运行过开放算法的原图之差,以下是示例是按一个9x9内核来进行的运算。
tophat = cv.morphologyEx(img, cv.MORPH_TOPHAT, kernel)
结果:
它是原图经过闭合运算之后的结果与原图之差。
blackhat = cv.morphologyEx(img, cv.MORPH_BLACKHAT, kernel)
结果:
在之前的示例中,我们在Numpy的帮助下手动创建了一个结构化的元素。它是长方形的,但在某些情况下,你可能需要圆形或者椭圆形的内核。所以为了达到这个目的,OpenCV 有个方法,cv.getStructuringElement() 。你只需要传入内核的形状以及大小,你就能得到你需要的内核。
# Rectangular Kernel
>>> cv.getStructuringElement(cv.MORPH_RECT,(5,5))
array([[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]], dtype=uint8)
# Elliptical Kernel
>>> cv.getStructuringElement(cv.MORPH_ELLIPSE,(5,5))
array([[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]], dtype=uint8)
# Cross-shaped Kernel
>>> cv.getStructuringElement(cv.MORPH_CROSS,(5,5))
array([[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]], dtype=uint8)
上篇:【翻译:OpenCV-Python教程】图像平滑
下篇:【翻译:OpenCV-Python教程】图像梯度