3、镜头阴影校正(LSC)实战:LSC原理、Shading表生成、不同色温下的LSC一致性调试
镜头阴影校正,圈里人常说的LSC,是车载ISP调试里绕不开的一关。
你想想看,摄像头拍出来的画面,边缘发暗、中心亮,这就是镜头阴影。说白了,镜头本身的光学特性决定的——光线从中心到边缘的传输路径不一样,CMOS感光芯片的入射角度也有差异。我刚开始做车载项目时,总觉得LSC不就是拉个增益嘛,后来发现,事情远没那么简单。
3.1 LSC原理:为什么会有阴影?
镜头阴影分两种:亮度阴影(Luma Shading)和颜色阴影(Color Shading)。
- 亮度阴影:画面从中心到边缘亮度逐渐下降。原因很简单,镜头的光学设计决定了边缘进光量天生就少。
- 颜色阴影:边缘出现偏色,比如偏绿或偏红。这是因为不同波长的光在镜头里的折射率不同,导致R、G、B通道的衰减程度不一样。
我记得有一次调试一个广角镜头,边缘的亮度掉了将近40%,而且偏绿严重。当时客户拿样片一看,直接说“这画面像戴了墨镜”。嗯,从那以后我每次拿到新镜头,第一件事就是测shading曲线。
核心公式:LSC校正的本质就是给每个像素乘上一个增益系数。
校正后像素值 = 原始像素值 × Gain(x, y)
其中Gain(x, y)是像素坐标(x, y)处的增益值,中心区域增益接近1.0,边缘区域增益大于1.0。
3.2 Shading表生成:从raw图到校正参数
生成Shading表,说白了就是拍一张均匀光照下的灰卡图,然后分析每个像素位置的亮度衰减情况。
具体步骤我一般这么走:
- 采集raw图:用积分球或者均匀光源,拍一张D50或D65色温下的灰卡raw图。注意,曝光要适中,不能过曝也不能欠曝。
- 分块统计:把图像分成M×N个网格,比如15×15或17×17。每个网格内统计R、G、B通道的平均值。
- 计算增益:以图像中心区域的网格为参考,计算每个网格相对于中心的增益值。
- 插值平滑:网格增益值需要做平滑处理,避免校正后出现网格状伪影。
- 生成LUT:最终输出一个二维查找表,供ISP硬件使用。
我习惯用Python写一个自动化脚本,直接读取raw图,输出shading表。给你看看核心代码片段:
import numpy as np
import rawpy
def generate_shading_table(raw_path, grid_size=(17, 17)):
# 读取raw图
raw = rawpy.imread(raw_path)
bayer = raw.raw_image_visible
# 分块统计
h, w = bayer.shape
grid_h, grid_w = grid_size
block_h, block_w = h // grid_h, w // grid_w
gains = np.ones((grid_h, grid_w, 3)) # R, G, B三个通道
# 计算每个网格的增益
center_h, center_w = grid_h // 2, grid_w // 2
center_r = bayer[center_h*block_h:(center_h+1)*block_h,
center_w*block_w:(center_w+1)*block_w].mean()
for i in range(grid_h):
for j in range(grid_w):
block = bayer[i*block_h:(i+1)*block_h,
j*block_w:(j+1)*block_w]
gains[i, j, :] = center_r / block.mean()
return gains
小技巧:采集raw图时,建议拍多张取平均,可以降低噪声对shading表的影响。我一般拍5张,然后做中值融合。
3.3 不同色温下的LSC一致性调试
这是LSC调试里最头疼的部分。为什么?因为镜头对不同色温的光,shading表现完全不一样。
举个例子,D65(6500K)下调试好的LSC参数,换到A光源(2856K)下,边缘可能偏红得一塌糊涂。我踩过这个坑——有一次给客户交样,白天路测没问题,晚上路灯下一看,画面边缘全是红的。客户直接打电话过来问“你们这摄像头是不是坏了?”
解决思路其实不复杂:
- 多色温标定:至少标定3个色温点——D65(日光)、D50(标准)、A光源(白炽灯)。每个色温生成独立的shading表。
- 线性插值:ISP里根据当前场景的色温,在多个shading表之间做线性插值。比如色温4000K时,用D50和A光源的表按权重混合。
- R/G、B/G比率一致性:调试时要确保不同色温下,边缘区域的R/G和B/G比率与中心区域一致。偏差控制在2%以内,人眼基本看不出来。
注意:车载场景的色温变化范围很大,从清晨的2000K到正午的7000K都有可能。我曾经遇到过一个问题——在黄昏时分,色温快速变化,LSC插值跟不上,导致画面出现闪烁。解决方案是增加色温检测的更新频率,同时做时间域的平滑滤波。
3.4 实战避坑指南
调试LSC这么多年,我总结了几条血泪教训:
- 不要只用积分球:积分球出来的shading表和实际场景有差异。我建议在实车环境下再微调一次。
- 注意镜头模组公差:同一批次的镜头,shading表现可能差3%-5%。量产时建议抽检10%的模组,确认shading表是否通用。
- 温度影响不可忽视:车载摄像头工作温度范围宽,-40°C到85°C。高温下镜头的光学特性会漂移,shading也会变。我做过实验,85°C时边缘增益需要额外增加2%-3%。
- 调试完一定要做主观评价:客观指标只是参考,最终还是要人眼看。我习惯在HDR模式下看天空、看路面、看建筑物边缘,确认没有明显的亮度跳变或偏色。
嗯,LSC这块其实说难不难,说简单也不简单。关键是要理解原理,然后多积累实际数据。你想想看,每个镜头都有自己的“脾气”,摸透了就好办了。
总结一下:LSC调试的核心就三件事——准确生成shading表、多色温标定、实车验证。把这三点做到位,画面阴影问题基本能解决80%。剩下的20%,靠经验和耐心慢慢磨。