官方文档 – https://docs.opencv.org/3.4.0/d9/d61/tutorial_py_morphological_ops.html
形态转换是基于图像形状的一些简单操作。它通常是在二进制图像上执行的。它需要两个输入,一个是我们的原始图像,第二个是结构化元素或内核,它决定了操作的性质。两种基本的形态运算符是侵蚀和扩张。然后它的其他变形形式,如打开,关闭,梯度等也开始发挥作用。
原图:
侵蚀的基本思想就像土壤侵蚀一样,它侵蚀了前景物体的边界(总是试图保持白色的前景)。内核在图像中滑动(就像在二维的卷积中)。原始图像中的像素(1或0)只有当内核下的所有像素都是1时才会被认为是1,否则就会被侵蚀(变成0)。
所有接近边界的像素都将被丢弃,这取决于内核的大小。因此,前景物体的厚度或大小会减少或仅仅是白色区域在图像中减少。它对于去除细小的白色噪音(如我们在彩色空间的章节所见),分离两个连接的物体等是很有用的。
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)
cv.erode(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
kernel:内核,用于侵蚀的结构元素。如果element=Mat()
,则使用一个3 x 3的矩形结构元素。内核可以使用cv.getStructuringElement()
来创建。
iterations:侵蚀的次数
与侵蚀相反,它增加了图像中的白色区域或者前景物体的大小增加了。通常情况下,在像噪音去除这样的情况下,侵蚀会伴随着扩张。因为,侵蚀消除了白噪音,但也会使我们的物体收缩。所以我们扩张。由于噪音消失了,它们不会再回来,但我们的目标区域却在增加。它在连接一个对象的破碎部分时也很有用。
dilation = cv.dilate(img, kernel, iterations=1)
cv.dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
cv.morphologyEx(src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
op:形态操作的类型,有如下类型:
cv.erode()
一样cv.dilate()
一样dst=open(src,element)=dilate(erode(src,element))
dst=close(src,element)=erode(dilate(src,element))
dst=morph_grad(src,element)=dilate(src,element)−erode(src,element)
dst=tophat(src,element)=src−open(src,element)
dst=blackhat(src,element)=close(src,element)−src
我们在前面的例子中,用Numpy手动创建了一个矩形的结构化的元素。但在某些情况下,您可能需要椭圆/圆形的内核。因此,OpenCV有一个函数,cv.getStructuringElement()
。只需传递内核的形状和大小,就可以得到所需的内核。
import cv2 as cv
#矩形内核
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)
# 椭圆内核
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)
# 十字形内核
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)
cv.getStructuringElement(shape, ksize[, anchor])
shape:元素形状