OpenCV库的学习笔记(七)Morphological Transformations 形态变换

本文介绍了形态学操作在图像处理中的应用,包括腐蚀、膨胀、开运算、闭运算等基本概念和函数,如cv2.erode()和cv2.dilate()。这些操作主要用于处理二进制图像,可以去除噪声、分离对象、调整对象大小等。通过实例展示了各种操作的效果,如使用不同内核进行形态变换,并提到了cv2.morphologyEx()函数在实现开闭运算和形态梯度等高级操作中的使用。
摘要由CSDN通过智能技术生成

目标

  • 我们将学习不同的形态学操作,如腐蚀膨胀开运算闭运算等。
  • 我们将看到不同的函数,如:cv.erode()、cv.dilate()、cv.morphologyEx() 等。

理论知识

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

腐蚀

侵蚀的基本思想就像土壤侵蚀一样,它侵蚀掉前景物体的边界(总是尽量让前景保持白色)。那它有什么作用呢?内核在图像中滑动(如在 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)

顶帽运算(Top Hat)

这是输入图像和图像的Opening之间的区别。顶帽运算就是将原图减去开运算后的图像,放大了裂痕或局部低亮度区域,下面的示例是针对 9x9 内核完成的。

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

黑帽运算(Black Hat)

它是输入图像和输入图像的闭运算之间的差异。与顶帽运算相反。

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)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值