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 需要一张均匀光源下的灰卡图。流程如下:
- 拍图:用积分球或均匀光源拍一张 18% 灰卡,确保画面亮度均匀。
- 分通道统计:把 R、Gr、Gb、B 四个通道分别提取出来。
- 计算增益:以图像中心区域的平均值为基准,每个格点的增益 = 中心均值 / 该格点均值。
- 平滑与裁剪:对增益做低通滤波,防止突变。同时设定最大增益上限(比如 2.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 图可能要几秒钟。
4.5 调试技巧:过校正与欠校正
LSC 调试最怕两个极端:过校正和欠校正。
- 欠校正:四角还是暗,或者色偏没拉回来。原因通常是 Gain Map 增益不够,或者格点太稀疏没覆盖到最边缘。
- 过校正:四角比中心还亮,或者边缘出现奇怪的色块。原因往往是增益太大,或者平滑不够导致网格噪声。
我的调试流程:先用软件模拟跑一遍,肉眼确认校正效果。然后截取边缘区域的 ROI,看 R/Gr/Gb/B 四个通道的均值是否接近中心。如果偏差 < 2%,硬件烧录基本没问题。
几个实用技巧:
- 分区域验证:不要只看中心和一个角。左上、右上、左下、右下、中心,五个点都要测。
- 用色温不同的光源:D65(6500K)和 A 光(2856K)下,Color Shading 表现可能完全不同。我建议至少测两种色温。
- 注意 Gr 和 Gb 的差异:很多 sensor 的 Gr 和 Gb 通道增益不同,必须分开校准。偷懒共用的话,会出现棋盘格状的亮度条纹。
- 最大增益设限:我一般设 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、控制好校正力度。你按这个清单走一遍,基本不会出大问题。