OpenCV 中值滤波器

Salman Mehmood 2024年2月15日
OpenCV 中值滤波器

在这个演示中,我们将了解什么是中值滤波器,并讨论 OpenCV 中的两种中值滤波器。然后我们还将学习如何在这些中值滤波器的帮助下从图像中去除椒盐噪声。

借助 OpenCV 中的中值滤波器从图像中去除椒盐噪声

让我们看看中值滤波器,它非常适合去噪,尤其是椒盐噪声。在快速学习中位数之前,我们都知道均值只不过是所有数字的平均值以及人们使用的典型示例。

例如,你住在一个社区,你的房子在 350 000、425 000 之间,等等。你可能有几个富人住在你的社区,在山上的某个地方,他们的房子价值 220 万、320 万,等等

假设你查看所有这些的平均值并看到 931 500,这让你感到惊讶。你可能会认为 931 500 是平均房价;这就是为什么你总是看房价中位数的原因。

查看这些值的中位数;它达到 512 500,代表价差好于平均值。这些是你可能在五年级或六年级时学到的统计数据,我们之所以提到这一点是因为我们将在这张图片中展示它们。

opencv 中值滤波器示例 1

下图是人工添加了大量椒盐噪声,我们可以看到很多暗像素和亮像素。如果我们放大,我们可以看到这个应该是均匀灰色的区域。

为什么会出现这些椒盐噪声?由于许多原因,椒盐噪声的主要来源就在那里,尤其是在你用来捕捉图像的旧电子设备中,其中模数转换存在一些问题。

opencv 中值滤波器示例 2

高斯模糊还可以,但不能很好地清除这种类型的噪声,从技术上讲,中值滤波器应该做得更好。如果你仔细观察,所有这些都是均匀的灰色,除了这个显示为明亮像素的像素。

如果我们应用 3x3 内核并查看中间值,我们正在查看该中心像素周围的所有内容。这个红色框内所有这些数字的中位数是 140。

如果我们将 255 替换为 140,我们会得到一个非常均匀且均匀的图像。

opencv 中值滤波器示例 3

这是一个快速的图形化表示,所以让我们跳入 Python 代码。我们将首先从 skimage.filters 导入 cv2median 来演示在两个包中使用中值。

我们正在导入两张图像,一张用于椒盐图像并用于调整其大小。我们需要使用 medianBlur() 方法,将图像传递给它并将内核大小设置为 3。

import cv2
from skimage.filters import median

SP_IMG = cv2.imread("inp.tif", 0)
IMG = cv2.resize(SP_IMG, (720, 600))

IMG = IMG

Opencv_Median = cv2.medianBlur(IMG, 3)

现在,我们使用相同的术语。skimage 非常相似,只是它定义了你的内核并使用了我们称为磁盘的东西。

我们需要调用 skimage 包中的 median() 方法并传递一个图像。我们正在创建磁盘大小,而不是内核大小。

当我们打印磁盘时,它会创建一个矩阵,其中零像素乘以零,当它在图像顶部移动时,这些像素乘以 1。

opencv 中值滤波器示例 4

现在,我们传递 mode 参数。没什么,但是当这个内核到达图像的末尾时,你如何处理结束像素?

因为它的右边没有任何东西,它会添加一些具有恒定值的像素。

示例代码:

from skimage.morphology import disk
import cv2
from skimage.filters import median

SP_IMG = cv2.imread("inp.tif", 0)
IMG = cv2.resize(SP_IMG, (720, 600))

IMG = IMG

Opencv_Median = cv2.medianBlur(IMG, 3)


print(disk(3))

SK_Median = median(IMG, disk(3), mode="constant", cval=0.0)

cv2.imshow("Original", IMG)
cv2.imshow("cv2 median", Opencv_Median)
cv2.imshow("Using skimage median", SK_Median)

cv2.waitKey(0)
cv2.destroyAllWindows()

我们有三个输出,一个是带有一些高斯噪声的原始图像。

opencv 中值滤波器输出 1

第二个输出是使用 OpenCV 的中值图像。在此输出中,结果优于原始图像。

opencv 中值滤波器输出 2

如果我们使用 skimage 中值查看下一个输出,它看起来非常干净,背景中没有任何内容。

opencv 中值滤波器输出 3

我们可以观察到 skimage 中位数看起来甚至比 OpenCV 中位数更好,因为这个中位数的内核大小有点小,并且与原始图像相比不是很干净。为什么 skimage 和 OpenCV 中值输出图像看起来不一样?

skimage 中值中,我们定义了磁盘大小,在 OpenCV 中值中,我们定义了内核大小。

内核大小不同;因此,输出看起来略有不同。如果你获得相同的内核大小,数学将是相同的。

作者: Salman Mehmood
Salman Mehmood avatar Salman Mehmood avatar

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

相关文章 - Python OpenCV