openCV:详解形态学操作(腐蚀、膨胀、开运算,闭运算等)

定义

形态学操作,例如腐蚀,膨胀,开运算,闭运算等

形态学操作是根据图像形状进行的简单操作 一般情况下对二值化图像进行的操作。

需要输入两个参数: 一个是原始图像, 一个被称为结构化元素或核,它是用来决定操作的性质的

原理

形态变换是基于图像形状的一些简单操作。它通常在二进制图像上执行。它需要两个输入,一个是原始图像,第二个是结构元素或核structuring element or kernel ,它决定我们操作的性质。两个基本的形态操作运算符是侵蚀和扩张。然后,是它们的变体形式,如开放,关闭,梯度等。我们将看到他们一个接一个的帮助以下这张图片,“j”,进行形态变换:

 

腐蚀 Erosion

正如这个名字表面上的意思,侵蚀的基本思想就像土壤侵蚀一样,它侵蚀了前景物体foreground object 的边界(在这,我们会让前景保持为白色)。那么侵蚀的作用是什么呢?这样内核可以在图像中滑动(在二维卷积中)。只有当内核下的所有像素都为1时,原始图像中的像素(要么为1,要么为0)才会被认为是1,否则会被侵蚀(变成0)。

这样的结果就是,取决于内核的大小,边界附近的所有像素都会被丢弃。因此,前景对象的厚度或大小会减少,或者只是简单地让图像中的白色区域减少。它对于去除小的白色噪音(正如我们在颜色空间colorspace 疑问中看到的那样),分离两个连接的物体等都很有用。

腐蚀作用:可以用来消除小且无意义的物体。在这里,作为一个例子,我将使用一个包含内部全都是1的5x5内核。让我们看看它是如何工作的:

import cv2
import numpy as np

img = cv2.imread('j.jpg', 0)
kernel = np.ones((5, 5), np.uint8)
erosion = cv2.erode(img, kernel, iterations=1)

cv2.imshow('j',erosion)

cv2.waitKey(0)
cv2.destroyAllWindows()


 

膨胀 Dilation

膨胀操作正好与腐蚀相反。这里,如果内核下至少有一个像素是“1”,那么该像素元素就是“1”。因此,它增加了图像中的白色区域,或则说增加了前景目标对象的尺寸大小。通常情况下,在去除噪声以后,在腐蚀操作之后就是膨胀。因为,腐蚀消除了白色的噪音,但它也缩小了我们的前景物体,所以我们需要扩大回它。因为当噪音消失了,原本应该存在的白色面积也不会自主回来。而且膨胀在连接物体的破碎部分时也很有用。

import cv2
import numpy as np

img = cv2.imread('j.jpg', 0)
kernel = np.ones((5, 5), np.uint8)
erosion = cv2.dilate(img, kernel, iterations=1)

cv2.imshow('j',erosion)

cv2.waitKey(0)
cv2.destroyAllWindows()

 

开运算

先进行腐蚀,再进行膨胀就叫做开运算。 通常情况下,含有噪声的图像二值化后,得到的边界是不平滑的,物体区域具有一些错判的孔洞,背景区域散布着一些小的噪声物体。对一个图像先进行腐蚀运算然后再膨胀的操作过程称为开运算,它可以消除细小的物体、在纤细点处分离物体、平滑较大物体的边界时不明显的改变其面积。

opening = cv2.morphologyEx(img, cv2.MORPH_OPEN, kernel)

结果:

闭运算

先膨胀再腐蚀。它经常被用来填充前景物体中的小洞,或者前景物体上面的小黑点。

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

结果:

形态学梯度

其实就是一幅图像膨胀和腐蚀的差别。

结果看上去就像前景物体的轮廓。

import cv2
import numpy as np

img = cv2.imread('j.jpg', 0)
kernel = np.ones((5, 5), np.uint8)
erosion = cv2.morphologyEx(img, cv2.MORPH_GRADIENT, kernel)


cv2.imshow('j',erosion)

cv2.waitKey(0)
cv2.destroyAllWindows()

运行结果: 

礼帽 Top Hat

原始图像与开运算之后得到的图像的差。下面的例子是用一个 9x9 的核进行礼帽操作的结果。

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

结果:

黑帽 Black Hat

进行闭运算之后得到的图像与原始图像的差。

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

结构化元素 Structuring Element

在Numpy 的帮助下,我们可以手动创建一个结构化元素。它是矩形的形状。但是在某些情况下,我们可能需要椭圆/圆形形状的内核。所以为此,OpenCV 专门有一个函数,cv2.getStructuringElement ()。我们只需要确定内核的形状和大小,就可以得到所需的内核。

如果要得到长方形的核,我们导入想要的形状和大小,代码如下:

import cv2
import numpy as np

# 矩形/长方形
kernel = cv2.getStructuringElement(cv2.MORPH_RECT,(5,5))

print(kernel)

# 得到结果如下
[[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]]


# 椭圆
kernel = cv2.getStructuringElement(cv2.MORPH_ELLIPSE,(5,5))

print(kernel)

# 得到结果如下
[[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]]


# 十字形 Cross-shaped Kernel
kernel = cv2.getStructuringElement(cv2.MORPH_CROSS,(5,5))

print(kernel)

# 得到结果如下
[[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]]

 

 

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值