4. 边缘保护降噪:双边滤波原理、参数影响、快速实现技巧
降噪这件事,最怕什么?
怕把边缘也抹掉了。一张图降完噪,噪点没了,但人脸轮廓糊了,文字边缘虚了——这在 ISP 里是致命的。我早期做手机摄像头调试时就踩过这个坑,降噪力度一上去,解析力直接崩盘。
双边滤波,就是来解决这个矛盾的。它能在降噪的同时,尽量保住边缘。
4.1 双边滤波的核心思想
普通的高斯滤波,只考虑像素之间的空间距离。离中心近的权重大,离得远的权重小。这会导致一个问题:边缘两侧的像素,明明属于不同物体,却因为空间距离近,被强行平均在一起。
双边滤波多了一个维度——像素值的相似度。它不光看距离,还看亮度差。亮度差太大的像素,就算挨着,权重也会被压低。
双边滤波的权重 = 空间权重 × 值域权重
空间权重:高斯函数,距离越近权重越大。
值域权重:高斯函数,亮度差越小权重越大。
说白了,双边滤波在做两件事:
- 空间域:只跟附近的像素玩。
- 值域:只跟亮度差不多的像素玩。
边缘处的像素,亮度差大,值域权重接近 0,所以不会被拉进来平均。边缘就保住了。
4.2 两个关键参数:σs 和 σr
调双边滤波,其实就是调两个 sigma。我习惯叫它们:
- σs(空间 sigma):控制空间距离的衰减速度。
- σr(值域 sigma):控制亮度差的容忍度。
| 参数 | 物理含义 | 调大后果 | 调小后果 |
|---|---|---|---|
| σs | 空间滤波半径 | 平滑更强,边缘可能变糊 | 降噪不足,保留细节 |
| σr | 亮度差容忍度 | 边缘保护变弱,容易产生光晕 | 边缘锐利,但降噪效果差 |
我的经验值:
σs 一般取 3~5,σr 取 10~30(8bit 图像)。
如果图像噪声大,我会先稍微提高 σs,再微调 σr 来平衡边缘。
4.3 双边滤波的数学形式
公式其实不复杂,但理解它有助于调参。
BF[I](p) = (1 / W_p) * Σ_{q ∈ S} G_s(||p - q||) * G_r(|I(p) - I(q)|) * I(q)
其中:
- p:当前像素位置。
- q:邻域内的像素位置。
- Gs:空间高斯核。
- Gr:值域高斯核。
- Wp:归一化因子,所有权重之和。
嗯,这里要注意:值域权重依赖于中心像素的亮度值 I(p)。所以双边滤波是非线性的,没法像普通高斯滤波那样用卷积加速。
4.4 快速实现技巧
双边滤波慢,是出了名的。我当年在嵌入式平台上做实时降噪,双边滤波直接跑不动。后来摸索出几个加速方法,分享给你。
4.4.1 分离式双边滤波
把二维滤波拆成水平和垂直两个一维滤波。速度能快 2~3 倍,但边缘保护效果会略有下降。适合对实时性要求高的场景。
4.4.2 下采样 + 上采样
先把图像缩小到 1/2 或 1/4,在低分辨率上做双边滤波,再放大回原尺寸。我做过测试,1/2 下采样,速度提升 4 倍,画质损失肉眼几乎不可见。
4.4.3 查表法(LUT)
值域权重 Gr 只依赖于亮度差。8bit 图像亮度差范围 0~255,可以提前算好一张表,运行时直接查表,避免重复计算 exp 函数。
// 预计算值域权重 LUT
float lut[256];
for (int i = 0; i < 256; i++) {
lut[i] = exp(-0.5 * (i * i) / (sigma_r * sigma_r));
}
// 运行时直接查表
float weight_r = lut[abs(I(p) - I(q))];
我曾经踩过的坑:
查表法在 σr 很小时,亮度差大的权重几乎为 0,但浮点精度问题可能导致权重不为 0。建议在查表后加一个阈值判断,小于 1e-6 的直接置 0。
4.4.4 引导滤波替代
如果双边滤波还是太慢,可以考虑用引导滤波(Guided Filter)替代。引导滤波的效果跟双边滤波很像,但速度更快,而且不会出现梯度反转伪影。我在一些低端芯片上就用引导滤波代替双边滤波。
4.5 双边滤波的局限性
双边滤波不是万能的。我总结几个常见问题:
- 梯度反转伪影:在边缘附近,可能会出现不自然的明暗条纹。这是因为值域权重在边缘处变化太剧烈。
- 光晕效应:σr 设得太大,边缘两侧的像素被错误地平均,产生类似 HDR 的光晕。
- 噪声残留:σr 设得太小,噪声跟边缘一样被保留下来。
我的调试习惯:
先固定 σs = 3,然后从 σr = 10 开始往上调。每调一次,看两个地方:一是平坦区域是否干净,二是边缘是否锐利。找到一个平衡点后,再微调 σs。
4.6 双边滤波在 ISP 中的位置
在 ISP 流水线里,双边滤波通常放在去马赛克之后、色调映射之前。为什么?
- 去马赛克之后,图像已经是 RGB 全彩,噪声分布相对稳定。
- 色调映射之前降噪,可以避免噪声被映射放大。
下面这张图展示了双边滤波在 ISP 降噪模块中的典型位置:
4.7 实战建议
最后,给你几个实战中可以直接用的建议:
- 先降噪再调映射:双边滤波的参数,最好在色调映射之前确定。否则映射后的噪声形态变了,很难调。
- 分通道处理:在 YUV 域,只对 Y 通道做双边滤波,UV 通道用简单的高斯滤波。速度能快不少,而且人眼对色度噪声不敏感。
- 边缘检测辅助:先算一个边缘图,在边缘区域降低双边滤波的强度,平坦区域加大强度。这样能进一步保护边缘。
- 迭代次数:双边滤波一般做 1~2 次就够了。做多了图像会变得像油画一样,失去真实感。
一句话总结:
双边滤波的核心是 σs 和 σr 的平衡。σs 控制范围,σr 控制边缘。调参时,先定 σs,再微调 σr,最后用查表法或下采样加速。