OpenCV 中的模糊滤镜

Salman Mehmood 2024年2月15日
OpenCV 中的模糊滤镜

本演示将介绍如何在 OpenCV 中平滑或模糊图像。我们将在本文末尾讨论不同类型的模糊滤镜以及如何使用它们。

在 OpenCV 中使用不同类型的模糊滤镜

平滑,也称为模糊,是图像处理中最常用的操作之一。它通常用于去除图像中的噪声。

我们可以使用多种线性滤波器,因为线性滤波器很容易实现并且相对较快。OpenCV 中有多种滤波器可用,例如,齐次滤波器、高斯滤波器、中值滤波器或双边滤波器,我们将逐一介绍。

首先,我们将看到同质滤波器。齐次滤波器很简单,每个输出像素是齐次滤波器中其核邻居的平均值。

所有像素都具有相同的权重,这就是它们被称为同质滤波器的原因。换句话说,内核是我们可以在图像上应用或卷积的形状。

numpy 创建了这种平方内核。所以在同质滤波器中,内核看起来像这个图像。

Opencv 模糊示例 1

在同质滤波器中,内核 K 等于 1 除以内核的宽度乘以内核的高度。如果我们想使用这个公式使用 5 x 5 的内核,那么我们将有 K 等于 1 除以 25,我们将有一个 1 的 5 x 5 内核矩阵。

Opencv 模糊示例 2

现在,我们需要使用 filter2D() 或同质过滤器为图像过滤创建这个内核。首先,我们将使用 imread() 方法读取图像。

IMG = cv2.imread("opencv-logo.jpg")

我们需要将图像从 BGR 转换为 RGB,因为 matplotlib 读取 RGB 格式的图像,而 OpenCV 读取 BGR 格式的图像。

IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

我们需要使用带有 float32 数据类型的 ones() 方法定义一个 5x5 内核,然后将其除以 25。

K = np.ones((5, 5), np.float32) / 25

现在,我们可以通过辅助定义的内核来定义我们的目标图像。一种称为 filter2D() 的方法用于同质过滤器。

第一个参数将是源图像,第二个是目标图像的所需深度,第三个是内核。

HMG = cv2.filter2D(IMG, -1, K)

在下一行中,我们正在迭代一个 for 循环,我们将通过此循环以 1 x 2 格式在 matplotlib 上显示图像。

for j in range(2):
    plot.subplot(1, 2, j + 1), plot.imshow(IMGS[j], "gray")

完整示例源代码:

import numpy as np
import matplotlib.pyplot as plot

IMG = cv2.imread("opencv-logo.jpg")
IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

K = np.ones((5, 5), np.float32) / 25
HMG = cv2.filter2D(IMG, -1, K)


T = ["Original IMG", "2D Convolution"]
IMGS = [IMG, HMG]

for j in range(2):
    plot.subplot(1, 2, j + 1), plot.imshow(IMGS[j], "gray")
    plot.title(T[j])
    plot.xticks([]), plot.yticks([])

plot.show()

我们可以看到角落里有一点噪点,在这张图片上应用 2D 卷积后,角落稍微平滑或模糊。这种模糊可以消除或抑制噪声,因此这是使用 filter2D() 方法模糊图像的一种方法。

Opencv 模糊输出 1

模糊滤镜

一维图像可以用低通滤波器或高通滤波器进行滤波。低通滤波器有助于去除图像的噪声或模糊等,高通滤波器有助于发现图像中的边缘。

要获得模糊的图像,你需要使用低通滤波器对图像进行转换。OpenCV 中提供了各种算法;第一个算法是 blur() 方法。

blur() 方法也称为平均方法,我们将使用它来应用平均算法来制作模糊图像。该方法有两个参数:第一个是图像,第二个是内核,即 (5,5)。

import cv2
import numpy as np
import matplotlib.pyplot as plot

IMG = cv2.imread("opencv-logo.jpg")
IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

K = np.ones((5, 5), np.float32) / 25
HMG = cv2.filter2D(IMG, -1, K)
BL = cv2.blur(IMG, (5, 5))

T = ["Original IMG", "2D Convolution", "Blur"]
IMGS = [IMG, HMG, BL]

for j in range(3):
    plot.subplot(1, 3, j + 1), plot.imshow(IMGS[j], "gray")
    plot.title(T[j])
    plot.xticks([]), plot.yticks([])

plot.show()

结果在 2D 卷积和模糊之间看起来或多或少是相同的,因为我们对这两个函数应用了相同类型的内核。

Opencv 模糊输出 2

高斯滤波器

我们来看下一个算法,就是高斯滤波算法。高斯滤波器只不过是在 x 和 y 方向上使用不同的权重内核。

在输出中,像素位于内核的中间,具有更高或更大的权重。权重随着与邻域中心的距离而减小。

较小权重的像素位于侧面,较高权重的像素位于中央。

当我们采用 5x5 内核时,其结果将类似于图像中显示的结果。

Opencv 模糊示例 3

让我们看看如何在 OpenCV 中使用 GaussianBlur() 方法。参数和 blur() 方法一样,所以第一个参数是输入图像,第二个是我们的内核,第三个是 Sigma X 值。

import cv2
import numpy as np
import matplotlib.pyplot as plot

IMG = cv2.imread("eye.jpg")
IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

K = np.ones((5, 5), np.float32) / 25
HMG = cv2.filter2D(IMG, -1, K)
BL = cv2.blur(IMG, (5, 5))
GB = cv2.GaussianBlur(IMG, (5, 5), 0)

T = ["Original IMG", "2D Convolution", "Blur", "GaussianBlur"]
IMGS = [IMG, HMG, BL, GB]

for j in range(4):
    plot.subplot(2, 2, j + 1), plot.imshow(IMGS[j], "gray")
    plot.title(T[j])
    plot.xticks([]), plot.yticks([])

plot.show()

我们可以观察到 GaussianBlur() 方法的结果优于其他模糊方法。

看看原始图像,它有太多的噪点。应用 GaussianBlur() 方法后,所有噪声都将被移除。

所以 GaussianBlur() 方法是专门为去除图像中的高频噪声而设计的。

Opencv 模糊输出 3

中值滤波器

中值滤波器是将每个像素值替换为其相邻像素的中值的东西。medianBlur() 方法在处理带有椒盐噪声的图像时非常有用。

如果你想了解更多关于椒盐噪声的信息,请点击此链接

我们这里有一个图像;有些像素失真,有些是白点或白噪声,有些是可以看到黑噪声的地方。因为像素像盐一样扭曲,黑色像素看起来像胡椒,所以称为椒盐噪声。

样本水图像

让我们将此图像用作 medianBlur() 方法中的源。源图像将是第一个参数,第二个参数是内核大小。

我们必须注意,内核大小必须是奇数,如 3、5、7 等,除了 1。如果使用 1,它将显示原始图像。

import cv2
import numpy as np
import matplotlib.pyplot as plot

IMG = cv2.imread("water.jpg")
IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

K = np.ones((5, 5), np.float32) / 25
HMG = cv2.filter2D(IMG, -1, K)
BL = cv2.blur(IMG, (5, 5))
GB = cv2.GaussianBlur(IMG, (5, 5), 0)
MB = cv2.medianBlur(IMG, 5)

T = ["Original IMG", "2D Convolution", "Blur", "GaussianBlur", "medianBlur"]
IMGS = [IMG, HMG, BL, GB, MB]

for j in range(5):
    plot.subplot(2, 3, j + 1), plot.imshow(IMGS[j], "gray")
    plot.title(T[j])
    plot.xticks([]), plot.yticks([])

plot.show()

我们在下面看到使用 medianBlur() 方法获得的最佳结果。

Opencv 模糊输出 4

双边过滤器

让我们看看最后一个过滤器,称为双边过滤器。因此,通过使用其他过滤器,我们不仅消除了噪声,还平滑了边缘。

有时我们需要保留边缘,这意味着即使图像模糊,所有边缘仍保持清晰。

bilateralFilter() 方法将图像作为第一个参数。第二个参数是过滤时使用的每个像素的直径,第三个参数是 Sigma 颜色,第四个是 Sigma 空间。

Sigma 颜色是颜色空间中的滤波器 Sigma,Sigma 空间是坐标空间中的滤波器 Sigma。

import cv2
import numpy as np
import matplotlib.pyplot as plot

IMG = cv2.imread("lena-1.jpg")
IMG = cv2.cvtColor(IMG, cv2.COLOR_BGR2RGB)

K = np.ones((5, 5), np.float32) / 25
HMG = cv2.filter2D(IMG, -1, K)
BL = cv2.blur(IMG, (5, 5))
GB = cv2.GaussianBlur(IMG, (5, 5), 0)
MB = cv2.medianBlur(IMG, 5)
BF = cv2.bilateralFilter(IMG, 9, 75, 75)

T = [
    "Original IMG",
    "2D Convolution",
    "Blur",
    "GaussianBlur",
    "medianBlur",
    "bilateralFilter",
]
IMGS = [IMG, HMG, BL, GB, MB, BF]
plot.figure(figsize=(8, 6))
for j in range(6):
    plot.subplot(2, 3, j + 1), plot.imshow(IMGS[j], "gray")
    plot.title(T[j])
    plot.xticks([]), plot.yticks([])

plot.show()

看看在应用 bilateralFilter() 方法的地方如何更好地保留边缘。双边滤波器在去除噪声方面非常有效,同时保持边缘锐利。

Opencv 模糊输出 5

作者: 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