python OpenCV学习笔记(十二):形态转换

官方文档 – https://docs.opencv.org/3.4.0/d9/d61/tutorial_py_morphological_ops.html


理论

形态转换是基于图像形状的一些简单操作。它通常是在二进制图像上执行的。它需要两个输入,一个是我们的原始图像,第二个是结构化元素或内核,它决定了操作的性质。两种基本的形态运算符是侵蚀和扩张。然后它的其他变形形式,如打开,关闭,梯度等也开始发挥作用。
原图:
python OpenCV学习笔记(十二):形态转换_第1张图片

侵蚀

侵蚀的基本思想就像土壤侵蚀一样,它侵蚀了前景物体的边界(总是试图保持白色的前景)。内核在图像中滑动(就像在二维的卷积中)。原始图像中的像素(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)

python OpenCV学习笔记(十二):形态转换_第2张图片

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)

python OpenCV学习笔记(十二):形态转换_第3张图片

cv.dilate(src, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])

cv.morphologyEx

cv.morphologyEx(src, op, kernel[, dst[, anchor[, iterations[, borderType[, borderValue]]]]])
op:形态操作的类型,有如下类型:

  • cv.MORPH_ERODE:效果和cv.erode()一样
  • cv.MORPH_DILATE:效果和cv.dilate()一样
  • cv.MORPH_OPEN:dst=open(src,element)=dilate(erode(src,element))python OpenCV学习笔记(十二):形态转换_第4张图片
  • cv.MORPH_CLOSE:dst=close(src,element)=erode(dilate(src,element))python OpenCV学习笔记(十二):形态转换_第5张图片
  • cv.MORPH_GRADIENT:dst=morph_grad(src,element)=dilate(src,element)−erode(src,element)python OpenCV学习笔记(十二):形态转换_第6张图片
  • cv.MORPH_TOPHAT:dst=tophat(src,element)=src−open(src,element)python OpenCV学习笔记(十二):形态转换_第7张图片
  • cv.MORPH_BLACKHAT:dst=blackhat(src,element)=close(src,element)−srcpython OpenCV学习笔记(十二):形态转换_第8张图片
  • cv.MORPH_HITMISS:仅支持CV_8UC1二进制图片

结构化元素

我们在前面的例子中,用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:元素形状

  • cv.MORPH_RECT(矩形)这里写图片描述
  • cv.MORPH_CROSS(十字)这里写图片描述
  • cv.MORPH_ELLIPSE(椭圆)一个内部有椭圆的矩形

你可能感兴趣的:(OpenCV)