OpenCV 扩张
本文将解释像侵蚀和扩张这样的形态变换概念,我们使用它们在 OpenCV 中的图像中从给定对象的边界添加和删除像素。
在 OpenCV 中使用侵蚀和扩张对图像应用形态变换
形态变换是在二值图像上执行的基于图像的操作。它需要两个输入,一个是原始图像,第二个是内核。
内核决定操作的性质。两个基本的形态学算子是侵蚀和扩张,我们也有它的一些变体,例如开闭等。
让我们通过一个例子来理解侵蚀和扩张。
侵蚀就像土壤侵蚀一样;它侵蚀了前景物体的边界。考虑这张 L
的图像,其中白色部分是数字 1,从 OpenCV 标准的角度来看,它也可以视为数字 255。
侵蚀会移除给定图像中对象边界处的像素。在图像中移除该对象 L
的边界后,在应用侵蚀后它会变薄。
从技术上讲,内核在图像中滑动,就像在 2D 卷积中一样。原始图像中的一个像素,无论是 1 还是 0,只有在内核下的所有像素都为 1 时才会被认为是 1;否则,它会被侵蚀或归零,因此根据内核的大小丢弃边界。
扩张与侵蚀相反;它将像素添加到给定图像中对象的边界。我们可以看到图像中 L
或物体 L
的边界在膨胀后变得更厚。
从技术上讲,如果内核下至少有一个像素为 1,则一个像素元素为 1,其结果将增加图像中的白色区域或前景对象的大小。
因此,如果你有一张想要去除噪声的图像,你可以先应用侵蚀操作,然后再进行膨胀,因为侵蚀会去除白噪声,但也会缩小我们的对象;这就是我们进行膨胀的原因,从而保留原始图像。它也可用于连接对象的破损部分。
形态变换有开、关等变化;打开是一个我们先应用侵蚀然后再膨胀的过程。关闭正好相反,我们应用膨胀然后侵蚀。
让我们使用 OpenCV 实现几个操作。我们需要导入所需的库。
在这一行中,我们使用 imread()
函数读取我们的图像,并将图像的路径作为参数提供,并将其存储在名为 imagedata_original
的变量中。
imagedata_original= cv2.imread('input.png')
在这段代码中,我们使用 numpy``ones()
函数定义 5x5
像素的内核,内核的数据类型是无符号 int
。
kernel=np.ones((5,5),np.uint8)
我们使用 erode()
函数在下一行应用侵蚀。它需要几个参数,如原始图像、内核和迭代。
iterations
建议你要运行侵蚀过程的次数。如果你增加这个数字,你正在增加侵蚀的影响。
erosion_op=cv2.erode(imagedata_original,kernel,iterations=1)
我们将使用 dilate()
函数将膨胀应用于图像对象。参数类似于 erode()
函数中定义的参数。
dilation_op= cv2.dilate(imagedata_original,kernel,iterations=1)
现在我们将使用 morphologyEx()
函数来应用开运算。这个函数接受像输入图像 MORPH_OPEN
这样的参数,它表示要应用的打开操作,以及我们上面定义的内核。
opening_op= cv2.morphologyEx(imagedata_original,cv2.MORPH_OPEN,kernel)
我们给出下一条指令,将关闭操作应用于 morphologyEx()
函数。
closing_op= cv2.morphologyEx(imagedata_original,cv2.MORPH_CLOSE,kernel)
完整的源代码:
import cv2
import numpy as np
import matplotlib.pyplot as plot
FIG=plot.figure(figsize=(6,5))
imagedata_original= cv2.imread('input.png')
FIG.add_subplot(2,3,1)
plot.imshow(imagedata_original)
plot.axis('off')
plot.title('original imagge')
kernel=np.ones((5,5),np.uint8)
erosion_op=cv2.erode(imagedata_original,kernel,iterations=1)
FIG.add_subplot(2,3,2)
plot.imshow(erosion_op)
plot.axis('off')
plot.title('Erossion operatiopn')
dilation_op= cv2.dilate(imagedata_original,kernel,iterations=1)
FIG.add_subplot(2,3,3)
plot.imshow(dilation_op)
plot.axis('off')
plot.title('Dilation operatiopn')
opening_op= cv2.morphologyEx(imagedata_original,cv2.MORPH_OPEN,kernel)
FIG.add_subplot(2,3,4)
plot.imshow(opening_op)
plot.axis('off')
plot.title('Opening operatiopn')
closing_op= cv2.morphologyEx(imagedata_original,cv2.MORPH_CLOSE,kernel)
FIG.add_subplot(2,3,5)
plot.imshow(closing_op)
plot.axis('off')
plot.title('Clossing operatiopn')
plot.tight_layout()
plot.show()
让我们使用 matplotlib
在图像中运行并查看具有不同操作的不同输出。
大多数人可能会感到困惑,为什么当从边界移除像素时,侵蚀图像中的文本显得很粗?为什么膨胀图像的文本在向对象的边界添加像素时显得很薄。
这是因为 OpenCV 将白色部分视为对象本身,而不是将黑色文本视为图像中的对象。因此,当我们应用侵蚀操作时,它会从黑色边界中移除白色像素,这就是黑色文本边界变粗的原因。
膨胀操作将白色像素添加到黑色文本的边界;这就是黑色文本变薄的原因。
Hello! I am Salman Bin Mehmood(Baum), a software developer and I help organizations, address complex problems. My expertise lies within back-end, data science and machine learning. I am a lifelong learner, currently working on metaverse, and enrolled in a course building an AI application with python. I love solving problems and developing bug-free software for people. I write content related to python and hot Technologies.
LinkedIn