4、RAW域去噪:传统去噪方法(BM3D、NLM)、基于CNN的RAW域去噪(CBDNet、RIDNet)、噪声模型与合成
各位同学,欢迎来到第四章。
RAW域去噪,说白了就是跟传感器上的物理噪声硬碰硬。我做了这么多年ISP,最深的体会就是:去噪做不好,后面所有算法都是白搭。你想想看,一张满是噪点的RAW图,你调白平衡、做demosaic,那都是把噪声放大再放大。
这一章,咱们把传统方法和深度学习的方法放在一起对比。我会结合自己踩过的坑,把噪声模型、BM3D、NLM、CBDNet、RIDNet这些核心内容讲透。
4.1 噪声模型与合成:你得先知道敌人长什么样
去噪的第一步,不是调算法,而是建模噪声。我刚开始做ISP时,直接拿高斯白噪声去训练网络,结果到了真实场景一塌糊涂。为什么?因为真实传感器的噪声根本不是纯高斯分布。
4.1.1 真实噪声的构成
RAW域的噪声,主要来自两个源头:
- 散粒噪声(Shot Noise):光子到达的随机性,服从泊松分布。信号越强,噪声方差越大。
- 读出噪声(Read Noise):电路读取时的热噪声、量化噪声,近似高斯分布,与信号强度无关。
所以,一个更贴近实际的噪声模型是:
I_observed = I_clean + n_shot(I_clean) + n_read
其中:
- n_shot ~ Poisson(I_clean) → 近似为 Gaussian(0, σ_shot²)
- σ_shot² = α * I_clean
- n_read ~ Gaussian(0, σ_read²)
- 总噪声方差:σ_total² = α * I_clean + σ_read²
这个模型,业内叫异方差高斯模型。我在项目中用过,效果比纯高斯好太多。
4.1.2 噪声合成流程
训练CNN去噪网络,需要大量成对的干净/噪声RAW图。真实采集太费劲,我建议用合成数据。流程如下:
- 获取干净RAW:用低ISO、长曝光拍静态场景,或者用多帧平均。
- 标定噪声参数:拍灰卡,计算不同亮度下的噪声方差,拟合 α 和 σ_read。
- 合成噪声:对每个像素,根据其亮度值计算 σ_total²,然后加高斯噪声。
- 数据增强:翻转、裁剪、调整ISO参数。
4.2 传统去噪方法:BM3D与NLM
在深度学习火起来之前,BM3D和NLM是去噪领域的两座大山。虽然现在CNN更强,但这些传统方法的思想依然值得学习。
4.2.1 NLM(Non-Local Means)
NLM的核心思想很简单:图像中相似的块,噪声模式应该是独立的。所以,用相似块的加权平均来去噪。
具体步骤:
- 对每个像素块,在全图或搜索窗口内找相似块。
- 相似度用块之间的欧氏距离衡量。
- 加权平均,权重与相似度成正比。
我当年用NLM做RAW域去噪,效果还行,但有两个痛点:
- 速度慢:全图搜索,计算量太大。
- 纹理模糊:在纹理丰富的区域,相似块不好找,容易把细节抹掉。
4.2.2 BM3D(Block-Matching and 3D Filtering)
BM3D是NLM的升级版。它把相似块堆叠成一个3D矩阵,然后在3D域做协同滤波。
流程分两步:
- 基础估计:用硬阈值滤波,得到初步去噪结果。
- 最终估计:用维纳滤波,进一步去除残留噪声。
BM3D的效果,在传统方法里是天花板级别的。但它的缺点也很明显:
- 计算量巨大:处理一张1200万像素的RAW图,可能要几十秒。
- 参数敏感:搜索窗口大小、块大小、阈值,都需要调参。
4.3 基于CNN的RAW域去噪:CBDNet与RIDNet
深度学习来了之后,去噪效果又上了一个台阶。这里我重点讲两个经典网络:CBDNet和RIDNet。
4.3.1 CBDNet(Convolutional Blind Denoising Network)
CBDNet的核心贡献是:盲去噪。它不需要知道噪声水平,网络自己估计。
网络结构分为两个子网络:
- 噪声估计子网络:输入噪声图,输出噪声水平图(每个像素的噪声方差)。
- 去噪子网络:输入噪声图和噪声水平图,输出干净图。
训练时,CBDNet用了非对称损失:对噪声水平估计,低估比高估惩罚更重。为什么?因为低估噪声会导致去噪不彻底,而高估噪声最多就是稍微模糊一点。
4.3.2 RIDNet(Real Image Denoising Network)
RIDNet是CBDNet之后的一个改进版本。它主要解决了两个问题:
- 感受野不够大:CBDNet的噪声估计子网络感受野有限,对大块噪声估计不准。
- 特征复用不足:去噪子网络没有充分利用多尺度特征。
RIDNet的解决方案:
- 引入扩张卷积,扩大感受野。
- 使用注意力机制,让网络关注噪声严重的区域。
- 采用残差连接,让梯度更容易传播。
我个人觉得,RIDNet在RAW域的效果比CBDNet更稳定。尤其是在低光场景下,RIDNet能保留更多纹理细节。
4.4 知识结构总览
下面这张图,把本章的核心知识点串起来了。你可以看到从噪声模型到传统方法,再到CNN方法的完整脉络。
4.5 方法对比与选型建议
我把这几种方法放在一起对比,方便你根据实际场景选型。
| 方法 | 速度 | 效果 | 适用场景 | 我的建议 |
|---|---|---|---|---|
| NLM | 慢 | 中等 | 低噪声、纹理简单 | 不推荐,已被BM3D取代 |
| BM3D | 很慢 | 好 | 离线处理、生成训练数据 | 适合做伪GT,不适合实时 |
| CBDNet | 中等 | 很好 | 盲去噪、未知噪声水平 | 需要调噪声估计子网络 |
| RIDNet | 中等 | 优秀 | 低光、纹理丰富场景 | 我目前的首选 |
4.6 实战经验:从模型到落地
最后,分享几个我在项目中踩过的坑和总结的经验。
- 数据合成是关键:我花了两周时间标定传感器噪声参数,才把合成数据做好。这一步省不了。
- RAW域 vs sRGB域:在RAW域做去噪,效果比sRGB域好30%以上。因为RAW域是线性的,噪声模型更干净。
- 模型轻量化:RIDNet虽然效果好,但参数量大。我后来用知识蒸馏,把RIDNet压缩到1/10大小,在手机上也能跑实时。
- 后处理不要过度:去噪之后,不要马上做锐化。我建议先做demosaic,再做锐化,顺序很重要。