双边滤波是一种用于平滑图像和降低噪声的技术,同时它能够保持边缘清晰。我们在这里介绍过使用均值滤波的方法,而在这里探讨了中值滤波的应用。然而,这些卷积操作往往会丢失重要的边缘信息,因为它们不加区分地模糊了所有内容——无论是噪声还是边缘。为了解决这个问题,非线性双边滤波应运而生。
高斯模糊
高斯模糊的数学表达如下:
在这里, GA[I]p 是像素 p 处的结果,而等式右边本质上是所有像素 q 的加权和,权重由高斯函数决定。 Iq 是像素 q 处的强度值。
双边滤波:增加边缘项
双边滤波的数学表达如下:
在这里,归一化因子和范围权重是加入到前一个方程中的新项。 \sigmas 表示核的空间范围,即邻域的大小; \sigmar 表示边缘的最小幅度。它确保了在模糊处理时,只考虑那些强度值与中心像素相似的像素,从而保持剧烈的强度变化(即边缘)不变。 \sigmar 的值越小,边缘就越清晰。随着 \sigmar 趋向于无穷大,该方程就趋向于高斯模糊。
OpenCV 提供了一个名为 bilateralFilter() 的函数,其参数如下:
- d: 每个像素邻域的直径。
- sigmaColor: 颜色空间中的 \sigma 值。该值越大,颜色相差较远的像素也会开始混合。
- sigmaSpace: 坐标空间中的 \sigma 值。该值越大,只要颜色在 sigmaColor 范围内,距离较远的像素也会相互混合。
代码:
输入: 带有噪声的图像。
代码:实现双边滤波
import cv2
# 读取图像
img = cv2.imread(‘taj.jpg‘)
# 应用双边滤波,设置 d = 15,
# sigmaColor = sigmaSpace = 75.
bilateral = cv2.bilateralFilter(img, 15, 75, 75)
# 保存输出结果
cv2.imwrite(‘taj_bilateral.jpg‘, bilateral)
双边滤波的输出结果
与均值滤波和中值滤波的对比
以下是均值滤波 (cv2.blur(img, (5, 5))) 的输出结果。
以下是中值滤波 (cv2.medianBlur(img, 5)) 的输出结果。
以下是高斯滤波 (cv2.GaussianBlur(img, (5, 5), 0)) 的输出结果。
我们可以很容易地发现,所有这些去噪滤波器都会导致边缘模糊(涂抹),而双边滤波则能很好地保留它们。