4. 镜头阴影校正(LSC)

镜头阴影,说白了就是拍出来的照片四角发暗、中间亮。你拿手机对着白墙拍一张,如果四角明显比中心暗,那就是镜头阴影。这问题在广角镜头上尤其明显,我见过不少项目,前期没处理好阴影,后期算法怎么调都救不回来。

4.1 镜头阴影现象

镜头阴影分两种:一种是亮度阴影(Luminance Shading),另一种是颜色阴影(Color Shading)。

  • 亮度阴影:画面从中心到边缘,亮度逐渐下降。原因是镜头的光学设计——边缘光线到达传感器的角度更大,光通量自然就少了。
  • 颜色阴影:不同颜色通道的衰减不一致。比如红色通道在边缘掉得比蓝色快,结果就是四角偏色。

为什么会这样?我简单解释一下。镜头相当于一个凸透镜,中心区域光线几乎是垂直入射,边缘光线则是斜着进来的。斜入射的光线在传感器像素上有效面积变小,响应就弱了。再加上镜头本身的渐晕效应(Vignetting),边缘亮度可能只有中心的40%-60%。

关键指标:阴影程度通常用中心亮度与边缘亮度的比值表示。比如中心亮度100,边缘只有60,那阴影比就是1.67:1。一般要求校正后边缘亮度达到中心的95%以上。

我在项目中遇到过一款手机摄像头,边缘亮度只有中心的35%。当时硬件工程师说镜头模组已经定了,改不了。没办法,只能靠LSC硬扛。嗯,那次确实费了不少功夫。

4.2 LSC校正原理

LSC校正的原理其实很直接:给每个像素乘一个增益系数。边缘暗,就多乘一点;中心亮,就少乘一点。说白了就是做一张增益图,按像素位置查表乘上去。

数学表达很简单:

I_corrected(x, y) = I_raw(x, y) × Gain(x, y)

其中 Gain(x, y) 就是每个像素对应的增益值。但实际实现时,不会给每个像素都存一个增益——那样太占内存了。通常的做法是存一个稀疏的增益网格,然后插值。

我习惯用 双线性插值 来做。比如网格是 16×16 的,每个格子覆盖 100×100 个像素。计算某个像素的增益时,找到它所在的网格单元,用四个角点的增益值做双线性插值。

我的经验:网格密度不是越密越好。太密了,校准数据量大,存储也大;太疏了,插值误差大。一般 16×16 到 32×32 的网格,配合双线性插值,效果就很好了。

颜色阴影的校正要单独处理。因为不同通道的衰减曲线不一样,需要为 R、Gr、Gb、B 四个通道分别生成增益网格。有些传感器 Gr 和 Gb 通道的阴影还不一样,那就得分开校。

4.3 增益网格校准方法

增益网格怎么来的?不是算出来的,是拍出来的。校准流程大概是这样:

  1. 准备均匀光源:用积分球或者均匀面光源,保证整个画面亮度一致。
  2. 拍摄灰卡:在标准色温下(比如 D65),拍一张灰卡图像。
  3. 计算增益:以图像中心区域的平均值为基准,计算每个网格点的增益值。
  4. 平滑处理:增益网格可能有噪声,需要做平滑滤波。
  5. 存储:把增益网格写入传感器驱动或ISP的寄存器。

具体计算增益的公式:

Gain(i, j) = Center_Mean / Block_Mean(i, j)

其中 Center_Mean 是中心区域的平均像素值,Block_Mean(i, j) 是第 (i, j) 个网格块的平均像素值。

我曾经踩过一个坑:积分球的光源不均匀。当时校准出来的增益网格,用在实拍场景里反而出现了条纹。排查了两天才发现,是积分球本身有暗区。从那以后,我每次校准前都会先拍一张白场图,检查光源均匀性。

注意:校准时的色温要和实际使用场景一致。不同色温下,镜头阴影曲线会变。如果只校了D65,在A光源下用,颜色阴影可能会反弹。建议至少校三个色温:D65、A光源、TL84。

4.4 LSC校正的工程实现

在ISP pipeline里,LSC通常放在黑电平校正之后、去马赛克之前。因为LSC是乘性校正,放在前面可以避免放大噪声。

硬件实现上,LSC模块一般包含:

  • 增益网格存储:通常用SRAM或寄存器存储网格数据
  • 地址生成器:根据像素坐标计算网格索引
  • 插值器:做双线性或双三次插值
  • 乘法器:将增益与像素值相乘

下面是一个简化的LSC校正流程图:

LSC校正流程图 原始RAW图像 黑电平校正 镜头阴影校正(LSC) 增益网格查表 + 双线性插值 R/Gr/Gb/B 四通道独立校正 校正后RAW图像 注意 增益网格需在 多个色温下校准 避免颜色阴影反弹

4.5 增益网格的存储与加载

增益网格怎么存?不同平台不一样。我见过几种常见格式:

格式 精度 存储大小(16×16网格) 适用场景
8位定点 1/256 256字节 低端摄像头
10位定点 1/1024 320字节 中端手机
12位定点 1/4096 384字节 高端相机
16位浮点 高精度 512字节 专业设备

我个人习惯用12位定点。精度够用,存储也不大。16位浮点虽然精度高,但硬件乘法器成本高,一般不用在消费级产品里。

小技巧:增益网格可以压缩存储。比如只存对角线上的值,或者用多项式拟合。我做过一个项目,用二阶多项式拟合增益曲线,存储从512字节降到了32字节,效果还能接受。

4.6 常见问题与避坑

做LSC校正这么多年,踩过的坑不少。挑几个典型的说说:

  • 光源不均匀:校准用的光源本身不均匀,导致增益网格不准。解决办法:用积分球,或者拍多张图取平均。
  • 色温漂移:只校了一个色温,换场景就偏色。解决办法:至少校三个色温,运行时根据色温插值切换增益网格。
  • 噪声放大:边缘增益太大,把噪声也放大了。解决办法:限制最大增益值,或者配合降噪算法一起用。
  • 网格边界不连续:相邻网格块的增益跳变太大,出现块状效应。解决办法:做平滑处理,或者用更高阶的插值算法。

我曾经遇到一个特别头疼的问题:校准完的增益网格,在低温环境下失效了。后来发现是传感器温度特性导致的——低温下暗电流变化,影响了阴影曲线。从那以后,我建议在多个温度点下做校准,至少覆盖-10°C到50°C的范围。

重要提醒:LSC校正不是万能的。如果镜头本身的阴影超过2:1,强行校正会带来严重的噪声和动态范围损失。这时候应该先找硬件原因,而不是全靠算法补。

嗯,关于镜头阴影校正,核心就是这些。记住三点:增益网格要准、插值要平滑、多色温多温度校准。做到这三点,LSC基本不会出大问题。