OpenCV 中的模糊滤镜
本演示将介绍如何在 OpenCV 中平滑或模糊图像。我们将在本文末尾讨论不同类型的模糊滤镜以及如何使用它们。
在 OpenCV 中使用不同类型的模糊滤镜
平滑,也称为模糊,是图像处理中最常用的操作之一。它通常用于去除图像中的噪声。
我们可以使用多种线性滤波器,因为线性滤波器很容易实现并且相对较快。OpenCV 中有多种滤波器可用,例如,齐次滤波器、高斯滤波器、中值滤波器或双边滤波器,我们将逐一介绍。
首先,我们将看到同质滤波器。齐次滤波器很简单,每个输出像素是齐次滤波器中其核邻居的平均值。
所有像素都具有相同的权重,这就是它们被称为同质滤波器的原因。换句话说,内核是我们可以在图像上应用或卷积的形状。
numpy 创建了这种平方内核。所以在同质滤波器中,内核看起来像这个图像。
在同质滤波器中,内核 K 等于 1 除以内核的宽度乘以内核的高度。如果我们想使用这个公式使用 5 x 5 的内核,那么我们将有 K 等于 1 除以 25,我们将有一个 1 的 5 x 5 内核矩阵。
现在,我们需要使用 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 中提供了各种算法;第一个算法是 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 卷积和模糊之间看起来或多或少是相同的,因为我们对这两个函数应用了相同类型的内核。
高斯滤波器
我们来看下一个算法,就是高斯滤波算法。高斯滤波器只不过是在 x 和 y 方向上使用不同的权重内核。
在输出中,像素位于内核的中间,具有更高或更大的权重。权重随着与邻域中心的距离而减小。
较小权重的像素位于侧面,较高权重的像素位于中央。
当我们采用 5x5 内核时,其结果将类似于图像中显示的结果。
让我们看看如何在 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()
方法是专门为去除图像中的高频噪声而设计的。
中值滤波器
中值滤波器是将每个像素值替换为其相邻像素的中值的东西。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()
方法获得的最佳结果。
双边过滤器
让我们看看最后一个过滤器,称为双边过滤器。因此,通过使用其他过滤器,我们不仅消除了噪声,还平滑了边缘。
有时我们需要保留边缘,这意味着即使图像模糊,所有边缘仍保持清晰。
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()
方法的地方如何更好地保留边缘。双边滤波器在去除噪声方面非常有效,同时保持边缘锐利。
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