4、数字增益(Digital Gain):数字域乘法器的实现,以及量化噪声的放大效应

数字增益,说白了就是在数字域里把像素值乘上一个系数。听起来很简单对吧?但这里面的坑,比你想的要多得多。

我刚开始做ISP芯片时,觉得数字增益不就是个乘法器嘛,几行代码搞定。直到第一次看到输出图像上那些密密麻麻的噪点,我才意识到——数字增益是把双刃剑。

4.1 数字增益的本质

模拟增益是在ADC之前放大电压信号,数字增益则是在ADC量化之后,对数字码值做乘法。举个例子:

// 原始像素值(12-bit ADC输出)
pixel_in = 2048;  // 对应50%满阱

// 数字增益 2.0x
pixel_out = pixel_in * 2.0;  // 4096

// 数字增益 4.0x
pixel_out = pixel_in * 4.0;  // 8192,但14-bit输出只能到16383

嗯,这里要注意:数字增益不会改变信噪比。为什么?因为信号和噪声都被放大了同样的倍数。

4.2 数字域乘法器的硬件实现

实际芯片里,我不会直接用浮点乘法器——那太奢侈了。常用的方案有几种:

实现方式 面积 精度 延迟 我推荐场景
定点乘法器(整数×定点小数) 小 中 1-2周期 低功耗IoT
查找表(LUT) 极小 低 1周期 固定增益场景
浮点乘法器 大 高 3-5周期 高端相机
移位+加法 最小 受限 多周期 2的幂次增益

我个人习惯用定点乘法器。举个例子,增益1.5x可以表示为定点数1.1000(二进制),也就是1 + 0.5。硬件实现就是:

// 定点乘法:pixel_out = pixel_in * 1.5
// 1.5 = 1 + 0.5 = 左移0位 + 右移1位
pixel_out = pixel_in + (pixel_in >> 1);

你看,连乘法器都不需要,一个加法器加一个移位器就搞定了。

我的经验: 如果增益值是2的幂次(2x、4x、8x),直接用左移实现。面积几乎为零,延迟也最小。我在一个4K@60fps的项目里,就是用移位器替代了4个乘法器,省了将近3000门。

4.3 量化噪声的放大效应

这才是数字增益最要命的地方。你想想看,ADC量化时已经引入了量化噪声。数字增益放大信号的同时,也放大了这个噪声。

举个例子:12-bit ADC,量化步长是1 LSB。假设某个像素的真实值是100.3,ADC量化后是100。量化误差是0.3 LSB。

现在做4x数字增益:

  • 理想情况: 100.3 × 4 = 401.2
  • 实际情况: 100 × 4 = 400
  • 量化误差放大: 0.3 × 4 = 1.2 LSB

看到了吗?量化误差从0.3 LSB变成了1.2 LSB。这就是量化噪声的放大效应。

我曾经踩过的坑: 在一个安防摄像头项目里,客户要求低光照下能看清人脸。我把模拟增益调到最大后,又加了6dB数字增益。结果图像上出现了明显的带状噪声——就是量化噪声被放大后,在暗区形成了伪轮廓。后来我不得不把数字增益限制在3dB以内,改用多帧融合来解决。

4.4 量化噪声放大的数学本质

我们来算一笔账。假设ADC是N位,量化步长q = Vref / 2N。量化噪声的方差是q²/12。

经过数字增益G后:

  • 信号功率: 放大G²倍
  • 量化噪声功率: 也放大G²倍
  • 信噪比: 不变!

这就是为什么我说数字增益不改善SNR。它只是把信号和噪声一起放大。

但问题在于——量化噪声不是白噪声。它有特定的频谱分布,尤其是在低光照下,量化步长相对于信号来说太大了,放大后会出现明显的量化伪影。

4.5 如何减轻量化噪声放大

我在实际项目中用过几种方法,效果还不错:

  1. 高位宽ADC + 低位宽输出
    • ADC做14-bit,输出只取12-bit
    • 多出来的2-bit相当于给数字增益留了余量
    • 代价:ADC面积增加约30%
  2. 数字抖动(Dithering)
    • 在量化前加一个小幅度的随机噪声
    • 把量化噪声变成白噪声,视觉上更平滑
    • 我习惯加0.5~1 LSB的均匀分布抖动
  3. 分段增益
    • 模拟增益做粗调,数字增益做细调
    • 数字增益不超过6dB(2x)
    • 超过的部分交给模拟增益或后端处理
  4. 非线性映射
    • 暗区用较小的数字增益
    • 亮区用较大的数字增益
    • 本质上是一种自适应增益控制
核心结论: 数字增益是"无中生有"的放大器。它不能创造信息,只能放大已有的信号和噪声。设计时一定要考虑量化噪声的放大效应,否则图像质量会断崖式下降。

4.6 数字增益与模拟增益的配合策略

你想想看,模拟增益和数字增益怎么搭配最合理?我的经验是:

光照条件 模拟增益 数字增益 理由
充足光照(>100 lux) 0 dB 0 dB 不需要额外增益
室内光照(10-100 lux) 6-12 dB 0-3 dB 模拟增益优先,数字增益微调
低光照(1-10 lux) 12-24 dB 3-6 dB 模拟增益为主,数字增益辅助
极低光照(<1 lux) 24-36 dB 6-12 dB 两者都用,但数字增益不超过12dB

我一般把数字增益的上限设在12dB(4x)。超过这个值,量化噪声就太明显了。这时候我会建议客户换更大光圈的镜头,或者用多帧降噪。

4.7 数字增益的流水线设计

在高速ISP芯片里,数字增益通常放在流水线的什么位置?我习惯这样安排:

// 典型的ISP数字增益流水线
// 阶段1: 黑电平校正 (BLC)
// 阶段2: 数字增益 (DG)
// 阶段3: 白平衡 (AWB)
// 阶段4: 去马赛克 (Demosaic)
// 阶段5: 色彩校正 (CCM)
// 阶段6: Gamma校正

// 为什么数字增益放在BLC之后?
// 因为BLC减去了暗电流,这时候做增益不会放大暗电流噪声

// 为什么放在AWB之前?
// 因为AWB是通道独立的增益,数字增益是全局增益
// 先做全局增益,再做通道增益,逻辑更清晰
我的设计习惯: 数字增益模块一定要有饱和保护。如果pixel_in × gain > max_value,直接钳位到max_value。否则会出现溢出环绕,图像上会出现诡异的暗条纹。我曾经在一个项目里忘了加饱和保护,结果调试了整整两天才找到原因。

4.8 数字增益的SVG流程图

下面这张图展示了数字增益在ISP流水线中的位置,以及量化噪声放大的过程:

数字增益在ISP流水线中的位置与量化噪声放大 图像传感器 ADC量化 黑电平校正 数字增益 后续ISP处理 量化噪声放大效应 • ADC量化引入噪声:q²/12 • 数字增益G倍放大信号和噪声 • SNR不变,但量化伪影更明显 • 暗区容易出现带状噪声 减轻措施 • 高位宽ADC + 低位宽输出 • 数字抖动(Dithering) • 分段增益(模拟+数字配合) • 非线性映射(暗区低增益) 数字增益不能创造信息,只能放大已有的信号和噪声 设计时务必考虑量化噪声放大效应,合理分配模拟/数字增益

4.9 实战中的避坑指南

最后,分享几个我亲身踩过的坑:

  • 坑1:数字增益溢出
    • 现象:高亮区域出现暗条纹
    • 原因:乘法结果超过位宽,高位被截断
    • 解决:加饱和保护,或者用更大的位宽做中间计算
  • 坑2:量化噪声放大导致伪轮廓
    • 现象:平滑区域出现阶梯状色带
    • 原因:数字增益放大了量化步长
    • 解决:加数字抖动,或者限制数字增益上限
  • 坑3:增益切换时的跳变
    • 现象:画面亮度突然变化
    • 原因:模拟增益和数字增益切换不同步
    • 解决:用渐变增益过渡,或者帧同步切换
我曾经犯过的错: 在一个监控摄像头项目里,为了追求低光照性能,我把数字增益开到了18dB。结果晚上画面全是噪点,客户直接拒收。后来我花了两个月重新设计增益策略,把数字增益限制在6dB以内,配合3帧降噪,才勉强通过验收。从那以后,我对数字增益就特别谨慎。

数字增益是个好东西,但用不好就是灾难。记住:模拟增益是"雪中送炭",数字增益只是"锦上添花"。别指望用数字增益来弥补模拟前端的不足,那只会让问题更明显。