4. 镜头阴影校正(LSC):从原理到实战

镜头阴影校正,圈里人常叫 LSC。说白了,就是解决照片四周发暗、发偏色的问题。你拿手机拍一张纯白墙壁,如果四角比中心暗,或者带着一圈紫边、绿边,那就是镜头阴影在作怪。

我刚开始接触 ISP 时,觉得 LSC 不就是乘个增益嘛,有什么难的?后来在项目里被过校正坑过一次,才老老实实把原理吃透。今天咱们就把 LSC 的来龙去脉聊清楚。

4.1 光晕与色偏:阴影是怎么来的?

镜头阴影分两种:亮度阴影(Luma Shading)和颜色阴影(Color Shading)。

  • 亮度阴影:镜头中心进光多,边缘进光少。物理上叫余弦四次方定律,说白了就是边缘光线要走更远的路,还要被镜头遮挡一部分。结果就是四角变暗。
  • 颜色阴影:不同波长的光穿过镜头时折射角度不同。红光偏得少,蓝光偏得多。于是边缘的 RGB 比例失衡,出现紫边、绿边或红边。

关键认知:亮度阴影是增益问题,颜色阴影是平衡问题。两个必须一起校正,否则只拉亮度不拉颜色,边缘色偏会更明显。

我在一个安防项目里遇到过极端情况:广角镜头在边缘处蓝通道比中心掉了 15%,红通道只掉了 5%。单纯提亮后,画面边缘一片蓝紫色。嗯,这就是典型的 Color Shading 没处理好。

4.2 Gain Map:校正的核心武器

LSC 的本质就是给每个像素乘一个增益系数。这个系数存在一张表里,叫 Gain Map。

Gain Map 长什么样?

  • 它是一个二维数组,尺寸通常比 sensor 分辨率小很多(比如 17×13 或 33×25)。
  • 每个格点存一个增益值,中心区域接近 1.0,边缘区域大于 1.0。
  • 硬件用双线性插值把稀疏的格点插成每个像素的增益。
参数 典型值 说明
Grid Size 17×13 水平 17 格,垂直 13 格
Center Gain 1.0 中心不补偿
Corner Gain 1.2 ~ 2.0 视镜头而定
Channel R, Gr, Gb, B 四通道独立

我的习惯:Gain Map 的格点密度不要贪多。17×13 对大部分 8M sensor 已经够用。格点太多反而容易引入网格噪声,调试时很难看。

4.3 Gain Map 的生成与校准

生成 Gain Map 需要一张均匀光源下的灰卡图。流程如下:

  1. 拍图:用积分球或均匀光源拍一张 18% 灰卡,确保画面亮度均匀。
  2. 分通道统计:把 R、Gr、Gb、B 四个通道分别提取出来。
  3. 计算增益:以图像中心区域的平均值为基准,每个格点的增益 = 中心均值 / 该格点均值。
  4. 平滑与裁剪:对增益做低通滤波,防止突变。同时设定最大增益上限(比如 2.5),避免噪声被过度放大。
  5. 写入寄存器:把平滑后的 Gain Map 转成硬件需要的格式(通常是 Q8.8 定点数)。
// 伪代码:Gain Map 计算核心
for each grid point (x, y):
    r_gain = center_r / grid_r[x][y]
    gr_gain = center_gr / grid_gr[x][y]
    gb_gain = center_gb / grid_gb[x][y]
    b_gain = center_b / grid_b[x][y]
    
    // 限制最大增益
    r_gain = min(r_gain, MAX_GAIN)
    // 平滑处理(略)

我曾经踩过的坑:用普通灯箱拍灰卡,结果灯箱本身亮度就不均匀。生成的 Gain Map 把灯箱的不均匀也补偿进去了,导致实拍时画面反而出现明暗条纹。后来我改用积分球,或者至少用均匀性 < 2% 的光源。

4.4 硬件实现 vs 软件模拟

硬件 LSC 模块通常放在 ISP Pipeline 的 RAW 域,BLC 之后、Demosaic 之前。为什么?因为 RAW 域数据还没被插值污染,校正最干净。

硬件实现的核心是:

  • 一个双线性插值器,实时计算每个像素的增益。
  • 四通道独立乘法器,R/Gr/Gb/B 各走各的。
  • 增益值用定点数表示,避免浮点运算。

软件模拟则用于调试阶段:

  • 在 PC 上用 Python 或 C++ 加载 RAW 图,逐像素乘增益。
  • 可以灵活调整 Gain Map,观察效果。
  • 但速度慢,一帧 8M RAW 图可能要几秒钟。
LSC 在 ISP Pipeline 中的位置 RAW Sensor BLC LSC Demosaic 硬件 LSC 模块内部结构 • 双线性插值器:根据像素坐标计算增益 • 四通道独立乘法器:R/Gr/Gb/B 各一个 • 定点数运算:Q8.8 格式,精度 1/256 • 行缓冲:缓存相邻两行格点数据

4.5 调试技巧:过校正与欠校正

LSC 调试最怕两个极端:过校正和欠校正。

  • 欠校正:四角还是暗,或者色偏没拉回来。原因通常是 Gain Map 增益不够,或者格点太稀疏没覆盖到最边缘。
  • 过校正:四角比中心还亮,或者边缘出现奇怪的色块。原因往往是增益太大,或者平滑不够导致网格噪声。

我的调试流程:先用软件模拟跑一遍,肉眼确认校正效果。然后截取边缘区域的 ROI,看 R/Gr/Gb/B 四个通道的均值是否接近中心。如果偏差 < 2%,硬件烧录基本没问题。

几个实用技巧:

  1. 分区域验证:不要只看中心和一个角。左上、右上、左下、右下、中心,五个点都要测。
  2. 用色温不同的光源:D65(6500K)和 A 光(2856K)下,Color Shading 表现可能完全不同。我建议至少测两种色温。
  3. 注意 Gr 和 Gb 的差异:很多 sensor 的 Gr 和 Gb 通道增益不同,必须分开校准。偷懒共用的话,会出现棋盘格状的亮度条纹。
  4. 最大增益设限:我一般设 2.0~2.5 为上限。超过这个值,暗部噪声会被放大到不可接受。

我曾经翻过车:在一个手机项目里,为了追求四角亮度完全一致,我把边缘增益拉到 2.8。结果夜景模式下,边缘全是彩色噪点,被客户打回来重调。后来我学乖了:LSC 不是要把四角拉到和中心一模一样,而是让肉眼看起来均匀就行。留一点自然的亮度衰减,反而更真实。

4.6 总结:LSC 调试清单

步骤 操作 检查点
1 均匀光源下拍灰卡 光源均匀性 < 2%
2 分通道统计增益 R/Gr/Gb/B 独立计算
3 平滑与裁剪 最大增益 ≤ 2.5
4 软件模拟验证 五区域亮度偏差 < 2%
5 硬件烧录 定点数格式正确
6 实拍验证 D65 和 A 光下均合格

LSC 说难不难,说简单也不简单。核心就三件事:理解阴影来源、生成准确的 Gain Map、控制好校正力度。你按这个清单走一遍,基本不会出大问题。