1.目的
在本教程中将学习:
- 用各种低通滤波器模糊图像。
- 对图像应用自定义过滤器(二维卷积)。
在图像处理中,平滑图像是一种去噪和模糊技术,用于减少图像中的噪声和细节,使得图像看起来更加平滑。平滑处理可以用于预处理步骤,以改善后续图像分析或识别任务的效果。
以下是一些常用的图像平滑技术:
- 均值滤波器(Mean filter):
均值滤波器是最简单的平滑技术之一。它通过用像素周围的平均值替换每个像素的值来减少噪声。这种滤波器会降低图像的锐度和细节。
- 中值滤波器(Median filter):
中值滤波器是一种非线性的平滑技术,它用像素周围的中值替换每个像素的值。中值滤波器特别有效于去除椒盐噪声,同时比均值滤波器更好地保留边缘信息。
- 高斯滤波器(Gaussian filter):
高斯滤波器使用高斯函数作为权重,对像素及其周围的像素进行加权平均。这种滤波器可以有效地去除高斯噪声,同时保留更多的图像细节。
- 双边滤波器(Bilateral filter):
双边滤波器是一种非线性的、边缘保持的平滑技术。它考虑了像素之间的空间邻近性和像素值的相似性,因此在平滑图像的同时能够较好地保持边缘。
- 同态滤波(Homomorphic filtering):
同态滤波是一种增强图像对比度的方法,它通过对图像进行对数变换和频率域滤波,然后再进行指数逆变换,来实现图像的平滑和亮度调整。
这些平滑技术可以根据具体的应用场景和需求来选择。例如,如果图像中存在大量的椒盐噪声,中值滤波器可能是最佳选择。如果需要去除高斯噪声同时保持图像的清晰度,高斯滤波器或双边滤波器可能更合适。在实际应用中,可能需要尝试不同的平滑方法,以找到最适合特定图像的平滑技术。
2.二维卷积(图像滤波)
与一维信号一样,图像也可以通过各种低通滤波器(LPF)、高通滤波器(HPF)等进行过滤。LPF 有助于消除噪音、模糊图像等。HPF 滤波器有助于在图像中找到边缘。
opencv 提供了函数 **cv.filter2D()**,用于将内核与图像卷积起来。作为一个例子,我们将尝试对图像进行均值滤波操作。5x5 均值滤波卷积核如下:
操作如下:将该内核中心与一个像素对齐,然后将该内核下面的所有 25 个像素相加,取其平均值,并用新的平均值替换这个25x25窗口的中心像素。它继续对图像中的所有像素执行此操作。试试下面这段代码并观察结果:
import numpy as np
import cv2 as cv
from matplotlib import pyplot as plt
img = cv.imread('opencv_logo.png')
kernel = np.ones((5,5),np.float32)/25
dst = cv.filter2D(img,-1,kernel)
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(dst),plt.title('Averaging')
plt.xticks([]), plt.yticks([])
plt.show()
2.1 均值模糊
这是通过用一个归一化的滤波器内核与图像卷积来完成的。它只需取内核区域下所有像素的平均值并替换中心元素 。这是通过函数 **cv.blur()**或 **cv.boxFilter()**完成的。有关内核的更多详细信息,请查看文档。我们应该指定滤波器内核的宽度和高度。
3x3 标准化框滤波器如下所示:
5x5 核的简单应用如下所示:
mport cv2 as cv
import numpy as np
from matplotlib import pyplot as plt
img = cv.imread('opencv-logo-white.png')
blur = cv.blur(img,(5,5))
plt.subplot(121),plt.imshow(img),plt.title('Original')
plt.xticks([]), plt.yticks([])
plt.subplot(122),plt.imshow(blur),plt.title('Blurred')
plt.xticks([]), plt.yticks([])
plt.show()
2.2 高斯模糊
在这种情况下,使用高斯核代替了核滤波器 。它是通过函数 **cv.GaussianBlur()**完成的。我们应该指定内核的宽度和高度,它应该是正数并且是奇数(奇数才有一个中位数)。我们还应该分别指定 x 和 y 方向的标准偏差、sigmax 和 sigmay。如果只指定 sigmax,则 sigmay 与 sigmax 相同。如果这两个值都是 0,那么它们是根据内核大小计算出来的。高斯模糊是消除图像高斯噪声的有效方法。
如果需要,可以使用函数 **cv.getGaussianKernel()**创建高斯内核。
上述代码可以修改为高斯模糊:
blur = cv.GaussianBlur(img,(5,5),0)
结果:
2.3 中值滤波
在这里,函数 **cv.medianBlur()**取内核区域下所有像素的中值,将中央元素替换为该中值 。这对图像中的椒盐噪声非常有效。有趣的是,在上面的过滤器中,中心元素是一个新计算的值,它可能是图像中的像素值,也可能是一个新值。但在中值模糊中,中心元素总是被图像中的一些像素值所取代,可以有效降低噪音。它的内核大小应该是一个正的奇数整数。
在这个演示中,我在原始图像中添加了 50%的噪声,并应用了中间模糊。结果如下:
median = cv.medianBlur(img,5)
结果:
2.4 双边滤波
**cv.bilateralFilter()**在保持边缘锐利的同时,对噪声去除非常有效。但与其他过滤器相比,操作速度较慢。我们已经看到高斯滤波器取像素周围的邻域并找到其高斯加权平均值。该高斯滤波器是一个空间函数,即在滤波时考虑相邻像素。但是它不考虑像素是否具有几乎相同的强度,也不考虑像素是否是边缘像素。所以它也会模糊边缘,这是我们不想做的。
双边滤波器在空间上也采用高斯滤波器,而另一个高斯滤波器则是像素差的函数。空间的高斯函数确保模糊只考虑邻近像素,而强度差的高斯函数确保模糊只考虑与中心像素强度相似的像素。所以它保留了边缘,因为边缘的像素会有很大的强度变化。
下面的示例显示使用双边滤波(有关参数的详细信息,请访问文档)。
blur = cv.bilateralFilter(img,9,75,75)
结果: