3、降噪算法基础理论:双边滤波、非局部均值、小波阈值去噪、BM3D原理简介

各位好,我是负责ISP图像质量调优的工程师。今天咱们聊聊降噪算法的四大金刚:双边滤波、非局部均值、小波阈值去噪和BM3D。

说实话,刚入行那会儿,我总觉得算法原理是算法工程师的事。直到有一次,我在调试高通平台的夜景模式时,发现某个场景的噪声死活压不下去,换了好几个参数都不行。后来一查,原来是算法选型出了问题——双边滤波对那种高频细节丰富的区域根本不适合。从那以后,我就老老实实把每个算法的脾气摸了个透。

这四种算法,说白了就是四种不同的「去噪哲学」。咱们一个一个来看。

3.1 双边滤波:保边去噪的入门选手

双边滤波(Bilateral Filter)是我最早接触的空间域降噪算法。它的核心思想很简单:既要看空间距离,也要看像素值差异。

传统的均值滤波或高斯滤波,只考虑像素之间的空间距离。离中心越近,权重越大。但这样会带来一个问题——边缘处的像素也被平均了,边缘就糊了。

双边滤波加了一个「值域核」。如果两个像素的亮度差太大,就算离得近,权重也会很小。这样一来,平坦区域的噪声被平滑了,边缘却被保留了下来。

双边滤波公式(简化版)

输出像素 = (1/W) * Σ [ 空间权重(i) × 值域权重(i) × 输入像素(i) ]

空间权重 = exp(-(距离²) / (2 * σ_s²))
值域权重 = exp(-(像素差²) / (2 * σ_r²))

这里有两个关键参数:σ_s(空间标准差)和 σ_r(值域标准差)。

参数 作用 调大后的效果 调小后的效果
σ_s 控制空间邻域范围 平滑更强,但细节丢失 保留细节,但降噪不足
σ_r 控制像素值敏感度 边缘保留变弱,容易模糊 边缘保留强,但噪声残留

我的调优经验

在高通平台上调双边滤波时,我习惯先固定 σ_s 为图像尺寸的 2%-3%,然后慢慢调 σ_r。σ_r 太小,噪声压不住;σ_r 太大,边缘就糊了。我一般从 0.1 开始,每次加 0.05,直到噪声和细节达到平衡。

双边滤波的缺点也很明显:计算量大。每个像素都要计算邻域内所有像素的权重,复杂度是 O(N·r²)。而且它对椒盐噪声效果不好——因为椒盐噪声的像素值差异太大,值域核直接把它当成边缘给保留了。

3.2 非局部均值:找相似块来去噪

非局部均值(Non-Local Means, NLM)是我个人比较喜欢的一种算法。它的思路很有意思:图像中总有很多相似的局部块。

你想想看,一片天空区域,虽然像素位置不同,但它们的纹理结构是相似的。NLM 就是利用这种「非局部」的自相似性来做降噪。

具体做法是:对于当前像素点,在图像中搜索所有与它周围小块相似的块,然后把这些块的中心像素加权平均。权重由块之间的相似度决定。

NLM 核心思想

输出像素(p) = Σ [ w(p,q) × 输入像素(q) ]

w(p,q) = exp(-||块(p) - 块(q)||² / h²) / Z(p)

这里的 h 是滤波强度参数,控制权重的衰减速度。块大小一般取 5×5 或 7×7,搜索窗口取 21×21 或 31×31。

我在项目中遇到过一个问题:NLM 对纹理丰富的区域效果很好,但对平坦区域反而容易产生「伪纹理」——因为搜索到的相似块不够多,权重分布不均匀。后来我加了一个预处理步骤,先对平坦区域做一次高斯滤波,再跑 NLM,效果就好多了。

注意:NLM 的计算量非常大

搜索窗口 21×21,块大小 7×7,每个像素要计算 441 个块的相似度。在 1080p 图像上,纯软件实现基本跑不动。高通平台一般会用硬件加速或降采样搜索策略。我在调试时,会把搜索窗口缩小到 11×11,牺牲一点效果换取实时性。

3.3 小波阈值去噪:频域里的「砍小留大」

小波阈值去噪(Wavelet Thresholding)是频域方法的代表。它的原理我可以用一句话概括:噪声在小波域里是高频小系数,信号是低频大系数。

具体步骤分三步:

  1. 小波分解:把图像分解成不同尺度和方向的小波系数(LL、LH、HL、HH)。
  2. 阈值处理:对高频子带(LH、HL、HH)的系数做阈值处理,小于阈值的置零或收缩。
  3. 小波重构:用处理后的系数重建图像。

阈值的选择是关键。常用的有硬阈值和软阈值两种:

类型 公式 特点
硬阈值 if |x| > T then x else 0 保留边缘锐利,但可能产生振铃
软阈值 sign(x) × max(|x|-T, 0) 图像更平滑,但边缘会变模糊

阈值 T 一般用 T = σ × √(2 × log(N)) 来估计,其中 σ 是噪声标准差,N 是像素数。这个公式来自 Donoho 的通用阈值法,我在实际项目中用它做初始值,然后手动微调。

我曾经踩过的坑

有一次我用小波阈值去噪处理一张星空照片,结果星星全被当成噪声去掉了。后来才发现,星星在图像中也是高频成分,阈值设得太高,把信号也砍了。解决办法是:对不同的子带用不同的阈值,或者先做一次边缘检测,保护高频信号区域。

3.4 BM3D:目前最强的空间-频域混合算法

BM3D(Block-Matching and 3D Filtering)是目前公认的降噪效果最好的算法之一。它结合了 NLM 的块匹配思想和小波变换的频域处理能力。

BM3D 的工作流程分两大步:

第一步:基础估计

  • 对图像做块匹配,找到相似块组成三维数组。
  • 对三维数组做 3D 变换(通常是 DCT + 小波)。
  • 用硬阈值滤波去除噪声。
  • 逆变换得到基础估计图像。

第二步:最终估计

  • 在基础估计图像上重新做块匹配。
  • 对原始图像和基础估计图像分别做 3D 变换。
  • 用维纳滤波(Wiener Filter)做联合滤波。
  • 逆变换得到最终结果。

BM3D 为什么效果好?

因为它同时利用了空间域的自相似性和频域的稀疏性。块匹配找到了冗余信息,3D 变换把信号和噪声在频域里分得更开,维纳滤波又做了最优估计。三个环节环环相扣。

BM3D 的缺点是计算量巨大。在手机上做实时 BM3D 基本不可能。高通平台一般用简化版或只在后处理阶段用。我调试时,会把块大小设为 8×8,搜索步长设为 3,这样能在效果和速度之间找到平衡。

3.5 四种算法对比总结

咱们用一张表来对比这四种算法:

算法 域 核心思想 保边能力 计算量 适用场景
双边滤波 空间域 空间+值域双权重 中 低 实时预处理、轻度噪声
NLM 空间域 非局部块匹配 高 高 纹理丰富场景、中等噪声
小波阈值 频域 小波系数阈值处理 中高 中 高斯噪声、可控场景
BM3D 混合域 块匹配+3D变换+维纳滤波 极高 极高 高质量后处理、离线处理

下面这张图展示了四种算法的核心逻辑关系:

四种降噪算法核心逻辑对比 双边滤波 空间 + 值域双权重 非局部均值 块匹配 + 加权平均 小波阈值去噪 频域系数阈值处理 BM3D 块匹配 + 3D变换 + 维纳 空间域 空间域 频域 混合域 性能对比(从低到高) 计算量: 双边滤波 < 小波阈值 < NLM < BM3D 降噪效果: 双边滤波 < 小波阈值 < NLM < BM3D 保边能力: 双边滤波 ≈ 小波阈值 < NLM < BM3D 选择建议:实时场景用双边滤波或小波阈值,高质量后处理用 BM3D,NLM 适合中等需求

在实际的高通 ISP 调优中,我一般这样选:

  • 实时预览:用双边滤波或它的加速变体,参数调好后效果够用。
  • 拍照后处理:用 BM3D 或 NLM,效果最好,但要注意功耗。
  • 视频降噪:用小波阈值去噪,计算量适中,帧率能稳住。

嗯,这四种算法是降噪领域的基础。理解了它们,后面再学更复杂的深度学习降噪方法时,你会发现很多思路都是相通的。