4. 空域降噪算法:均值滤波、高斯滤波、中值滤波的原理与实现
说到夜景降噪,空域滤波是最基础、最直观的一类方法。说白了,就是直接在像素点上做运算,用周围邻居的信息来“修复”当前像素。我刚开始接触图像处理时,就是从这三个滤波器入手的。别看它们简单,在夜景流水线上,它们依然是很多预处理环节的基石。
4.1 均值滤波:最简单的平滑器
均值滤波的思路非常朴素——用一个窗口扫过图像,把窗口内所有像素的平均值赋给中心点。
公式长这样:
g(x, y) = (1 / (m × n)) × Σ f(i, j) (i,j ∈ 窗口)
其中 m×n 是窗口大小,比如 3×3、5×5。
我个人的习惯是:在调试初期,先用均值滤波快速验证降噪流程是否跑得通。因为它计算量最小,出bug的概率也低。
核心特点:
- 所有像素权重相同,一视同仁
- 对高斯噪声有一定抑制效果
- 会模糊边缘,细节损失严重
但说实话,夜景图像里最头疼的不是高斯噪声,而是椒盐噪声(那些黑白点)。均值滤波遇到椒盐噪声,会把噪声点“扩散”到整个窗口,结果就是整块区域都脏了。嗯,这里要注意——均值滤波不适合处理椒盐噪声。
4.2 高斯滤波:给邻居排个队
高斯滤波和均值滤波的区别在哪?说白了,就是权重不同。高斯滤波认为:离中心越近的像素,贡献应该越大;离得越远的,贡献小一些。这个权重由高斯函数决定。
二维高斯函数:
G(x, y) = (1 / (2πσ²)) × exp(-(x² + y²) / (2σ²))
σ(标准差)控制着权重的分布。σ越大,权重分布越平坦,平滑效果越强;σ越小,中心权重越突出,保留细节越多。
我在项目中遇到过一个问题:夜景图像中暗部区域的信噪比极低,用高斯滤波时如果σ选得太大,暗部细节全糊成一团;选得太小,噪声又去不掉。后来我总结了一个经验——σ取窗口大小的 1/6 左右,比如 5×5 窗口,σ≈0.8,效果比较均衡。
| 窗口大小 | 推荐 σ | 适用场景 |
|---|---|---|
| 3×3 | 0.5 ~ 0.6 | 轻度噪声,细节保留优先 |
| 5×5 | 0.8 ~ 1.0 | 中等噪声,夜景常用 |
| 7×7 | 1.2 ~ 1.5 | 强噪声,但边缘会明显模糊 |
小技巧:高斯滤波的核可以预先计算好,存成固定模板。运行时直接查表,不用每次都算 exp,能省不少计算量。我在手机端做实时预览时就是这么干的。
4.3 中值滤波:椒盐噪声的克星
中值滤波的思路完全不同——它不求和,也不加权,而是排序取中间值。把窗口内所有像素按灰度值排序,取中间那个值作为输出。
举个例子,3×3 窗口内有 9 个像素值:
[12, 15, 18, 20, 22, 25, 28, 30, 255] ← 255是椒盐噪声点
排序后:12, 15, 18, 20, 22, 25, 28, 30, 255
中值 = 22
你看,255 这个异常值直接被排除了。这就是中值滤波对付椒盐噪声的绝招。
我曾经踩过一个坑:在夜景图像中,中值滤波对高斯噪声的效果其实一般。因为高斯噪声是均匀分布的,排序后中值并不能有效滤除。所以别指望中值滤波能包治百病。
避坑指南:中值滤波的窗口不宜过大。7×7 以上的中值滤波会严重破坏图像纹理,而且计算量暴增(排序算法的时间复杂度是 O(n²))。我一般控制在 3×3 或 5×5。
4.4 三种滤波器的对比
你想想看,这三种滤波器各有各的脾气。我整理了一张对比表,方便你快速决策:
| 滤波器 | 核心思想 | 噪声类型 | 边缘保留 | 计算速度 |
|---|---|---|---|---|
| 均值滤波 | 平均 | 高斯噪声 | 差 | 最快 |
| 高斯滤波 | 加权平均 | 高斯噪声 | 中等 | 快 |
| 中值滤波 | 排序取中 | 椒盐噪声 | 好 | 较慢 |
4.5 代码实现示例
下面我用 Python 和 OpenCV 演示一下三种滤波器的调用方式。实际项目中,你可能会用 C++ 或汇编优化,但原理是一样的。
import cv2
import numpy as np
# 读取夜景图像
img = cv2.imread('night_scene.jpg', cv2.IMREAD_GRAYSCALE)
# 均值滤波
mean_blur = cv2.blur(img, (5, 5))
# 高斯滤波
gaussian_blur = cv2.GaussianBlur(img, (5, 5), 0.8)
# 中值滤波
median_blur = cv2.medianBlur(img, 5)
# 保存结果
cv2.imwrite('mean_result.jpg', mean_blur)
cv2.imwrite('gaussian_result.jpg', gaussian_blur)
cv2.imwrite('median_result.jpg', median_blur)
代码很简单,但参数调起来有讲究。我个人习惯是先固定窗口大小,然后调 σ 或迭代次数,观察效果变化。
4.6 本章知识体系
下面这张图帮你理清三种滤波器的关系和应用场景:
三种滤波器各有千秋。均值滤波最简单,高斯滤波最常用,中值滤波最擅长处理椒盐噪声。在夜景降噪的实际流程中,我通常会把它们组合使用——先用中值滤波去掉明显的椒盐噪声,再用高斯滤波平滑高斯噪声。当然,这只是基础,后面还有更高级的算法等着我们。