降噪基础方法:均值滤波、高斯滤波、中值滤波的原理与实现

各位好,欢迎来到降噪基础这一章。HDR 图像处理中,降噪是个绕不开的坎。你想想看,多帧合成虽然能提升动态范围,但暗部区域的噪声往往也被放大了。我个人习惯把降噪比作「给图像做美容」——既要去掉瑕疵,又不能把五官磨没了。

这一章我们只聊三种最基础的滤波方法:均值滤波、高斯滤波、中值滤波。别看它们简单,实际项目中 80% 的降噪场景都能用它们搞定。嗯,咱们一个一个来。

4.1 均值滤波:最朴素的平滑器

均值滤波的原理,说白了就是「取平均」。用一个固定大小的窗口(比如 3×3),在图像上滑动,把窗口内所有像素的亮度值加起来除以像素个数,用这个平均值替换中心像素的值。

公式很简单:

g(x, y) = (1 / (m × n)) × Σ f(i, j)

其中 m×n 是窗口大小,f(i, j) 是窗口内各像素值。

实现要点:

  • 窗口大小通常选奇数:3×3、5×5、7×7
  • 窗口越大,平滑效果越强,但图像越模糊
  • 边界处理:我一般用「补零」或「镜像扩展」

核心特点:均值滤波计算量小,实现简单,但会破坏边缘信息。说白了,它把噪声和细节一起抹平了。

我在项目中遇到过这样一个坑:用均值滤波处理星空 HDR 图像,结果星星全变成了模糊的光斑。为什么?因为星星本身是高频细节,均值滤波不分青红皂白全给平均了。

4.2 高斯滤波:带权重的平滑

高斯滤波是均值滤波的升级版。它不再简单取平均,而是根据高斯分布给窗口内的像素分配权重——离中心越近的像素权重越大,越远的权重越小。

二维高斯函数长这样:

G(x, y) = (1 / (2πσ²)) × exp(-(x² + y²) / (2σ²))

其中 σ(标准差)控制权重的衰减速度。σ 越大,权重分布越平坦,平滑效果越强。

实现步骤:

  1. 根据 σ 和窗口大小生成高斯核(权重矩阵)
  2. 归一化高斯核,使所有权重之和为 1
  3. 用高斯核与图像做卷积

我的经验:σ 取 0.8~1.2 时效果最自然。σ 太小(如 0.3)几乎没效果,σ 太大(如 3.0)图像会严重模糊。我曾经在夜景 HDR 合成中用过 σ=2.5,结果建筑边缘像涂了一层黄油。

高斯滤波比均值滤波好在哪里?它保留了更多边缘信息。因为离中心远的像素贡献小,边缘两侧的像素不会互相「污染」得太厉害。

4.3 中值滤波:边缘保护专家

中值滤波的思路完全不同。它不计算平均值,而是取窗口内所有像素的中位数作为输出值。

举个例子:一个 3×3 窗口内的像素值为 [12, 15, 18, 20, 22, 25, 28, 30, 255],排序后中位数是 22。那个 255 的椒盐噪声就被完美去掉了。

实现流程:

  1. 滑动窗口遍历每个像素
  2. 提取窗口内所有像素值
  3. 排序,取中位数
  4. 替换中心像素

注意:中值滤波对椒盐噪声(黑白点噪声)效果极好,但对高斯噪声效果一般。而且排序操作比均值计算慢得多,窗口越大性能开销越大。

我记得有一次处理工业相机拍摄的 HDR 图像,传感器坏点导致大量白点噪声。均值滤波和高斯滤波都试了,效果很差——白点虽然变暗了,但扩散成一片灰斑。换成中值滤波后,坏点直接消失,边缘还保持得干干净净。

4.4 三种滤波对比

特性 均值滤波 高斯滤波 中值滤波
计算复杂度 低 中 高(需排序)
边缘保持 差 中 好
椒盐噪声 一般 一般 优秀
高斯噪声 一般 好 一般
实现难度 简单 中等 简单
适用场景 快速预览、低要求平滑 自然平滑、HDR 暗部降噪 椒盐噪声、边缘保护

4.5 代码实现示例

下面我用 Python 和 OpenCV 演示三种滤波的实现。你可以在自己的项目中直接套用。

import cv2
import numpy as np

# 读取图像(假设是 HDR 亮度图)
img = cv2.imread('hdr_luminance.png', cv2.IMREAD_GRAYSCALE)

# 均值滤波
mean_blur = cv2.blur(img, (3, 3))

# 高斯滤波
gaussian_blur = cv2.GaussianBlur(img, (3, 3), sigmaX=1.0)

# 中值滤波
median_blur = cv2.medianBlur(img, 3)

# 保存结果
cv2.imwrite('mean_result.png', mean_blur)
cv2.imwrite('gaussian_result.png', gaussian_blur)
cv2.imwrite('median_result.png', median_blur)

避坑指南:我曾经在 HDR 合成流程中直接用均值滤波处理 16bit 浮点亮度图,结果因为像素值范围太大(0~65535),均值计算时出现了整数溢出。后来我先把数据归一化到 0~1 再滤波,问题就解决了。

4.6 知识体系结构图

下面这张 SVG 图展示了三种滤波方法的核心逻辑和适用场景,方便你快速回顾。

降噪基础方法知识体系 图像降噪 均值滤波 高斯滤波 中值滤波 特性 计算快,边缘模糊 适合快速预览 特性 权重平滑,边缘较好 适合自然降噪 特性 边缘保持最好 适合椒盐噪声 选择建议 高斯噪声 → 高斯滤波 | 椒盐噪声 → 中值滤波 | 快速测试 → 均值滤波

4.7 实际项目中的选择策略

说了这么多理论,到底怎么选?我分享几个实战经验:

  • HDR 暗部区域:暗部噪声通常是高斯型,优先用高斯滤波,σ 取 1.0~1.5,窗口 5×5
  • 传感器坏点:这是典型的椒盐噪声,中值滤波 3×3 窗口一次搞定
  • 实时预览:均值滤波最快,但我会配合边缘检测做条件滤波——平坦区域用均值,边缘区域保持原样
  • 多帧合成前:我建议先对每帧做轻度高斯滤波(σ=0.5),再合成,能减少帧间噪声累积

重要提醒:滤波窗口大小不要超过图像尺寸的 5%。我曾经在 4K 图像上用 101×101 的高斯滤波,结果程序直接卡死——不是算法问题,是内存爆了。大窗口一定要考虑性能优化。