OpenCV  4.10.0
开源计算机视觉
加载...
搜索...
未找到匹配项
形态转换

目标

在本章中,

理论

形态学转换是基于图像形状的一些简单操作。它通常在二值图像上执行。它需要两个输入,一个是我们的原始图像,另一个称为结构元素内核,决定操作的性质。两个基本形态学算子是侵蚀和膨胀。然后,它的变体形式如开启、闭合、梯度等也会发挥作用。我们将借助以下图像逐一查看它们

图像

1. 侵蚀

侵蚀的基本思想就像土壤侵蚀一样,它侵蚀前景色对象的边界(总是尝试将前景色保持为白色)。那么它做了些什么?内核滑动通过图像(与 2D 卷积一样)。只有内核下方的所有像素都为 1,原始图像中的像素(1 或 0)才被认为是 1,否则它被侵蚀(变为 0)。

因此,发生的事情是,根据内核的大小,所有边界附近的像素都将被丢弃。因此,前景色对象的厚度或大小减小,或者图像中的白色区域减小。它可用于移除小的白色噪声(如我们在色彩空间章节中看到的),分离两个连接的对象等。

在此,作为一个示例,我将使用一个充满 1 的 5x5 内核。让我们看看它是如何工作的

import cv2 as cv
import numpy as np
img = cv.imread('j.png', cv.IMREAD_GRAYSCALE)
assert img is not None, "file could not be read, check with os.path.exists()"
kernel = np.ones((5,5),np.uint8)
erosion = cv.erode(img,kernel,iterations = 1)
CV_EXPORTS_W Mat imread(const String &filename, int flags=IMREAD_COLOR)
从文件中加载图像。
void erode(InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar &borderValue=morphologyDefaultBorderValue())
使用特定结构元素腐蚀图像。

结果

图像

2. 膨胀

它是腐蚀的反面。这里,如果内核下的至少一个像素为“1”,则像素元素为“1”。因此,它会增加图像中的白色区域或前景对象的大小。通常,在像去除噪声等情况下,膨胀后接腐蚀。因为,腐蚀会去除白色噪声,但它也会使我们的物体缩小。因此我们对它进行膨胀。由于噪声已经消失,因此它们不会回来,但我们的对象区域会增加。它还可用于连接对象的断开部分。

dilation = cv.dilate(img,kernel,iterations = 1)
void dilate(InputArray src, OutputArray dst, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar &borderValue=morphologyDefaultBorderValue())
使用特定结构元素膨胀图像。

结果

图像

3. 开运算

开运算只是“腐蚀后再膨胀”的另一种说法。它可用于去除噪声,如上所述。这里我们使用函数,cv.morphologyEx()

opening = cv.morphologyEx(img, cv.MORPH_OPEN, kernel)
void morphologyEx(InputArray src, OutputArray dst, int op, InputArray kernel, Point anchor=Point(-1,-1), int iterations=1, int borderType=BORDER_CONSTANT, const Scalar &borderValue=morphologyDefaultBorderValue())
执行高级形态学变换。

结果

图像

4. 闭运算

闭运算是开运算的逆运算,先膨胀后腐蚀。它可用于闭合前景对象内部的小孔或对象上的小黑点。

closing = cv.morphologyEx(img, cv.MORPH_CLOSE, kernel)

结果

图像

5. 形态学梯度

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

结果将看起来像对象的轮廓。

gradient = cv.morphologyEx(img, cv.MORPH_GRADIENT, kernel)

结果

图像

6. 顶帽

它是输入图像与其开运算之间的差异。以下示例针对 9x9 内核完成。

tophat = cv.morphologyEx(img, cv.MORPH_TOPHAT, kernel)

结果

图像

7. 黑帽算法

它是在输入图像和闭合输入图像之间的差。

blackhat = cv.morphologyEx(img, cv.MORPH_BLACKHAT, kernel)

结果

图像

形态学结构元素

在之前的示例中,我们使用 Numpy 手动创建了结构元素。它是矩形形状。但在某些情况下,你可能需要椭圆形/圆形内核。为此,OpenCV 有一个函数cv.getStructuringElement()。你只需要传递内核的形状和大小,便可得到所需的内核。

# 矩形内核
>>> cv.getStructuringElement(cv.MORPH_RECT,(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]]
# 椭圆内核
>>> cv.getStructuringElement(cv.MORPH_ELLIPSE,(5,5))
[[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]]
# 十字形内核
>>> cv.getStructuringElement(cv.MORPH_CROSS,(5,5))
[[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]]
Mat getStructuringElement(int shape, Size ksize, Point anchor=Point(-1,-1))
返回指定大小和形状的结构元素,用于形态学运算。

附加资源

  1. 形态学运算 in HIPR2

练习