精讲:径向衰减模型、增益映射与产线标定技巧)
054、镜头阴影校正LSC精讲径向衰减模型、增益映射与产线标定技巧一个让我半夜被电话叫醒的Bug2018年某个凌晨产线那边打来电话说某款旗舰机在暗光下拍照画面左上角明显偏绿右下角偏紫红。我第一反应是LSCLens Shading Correction标定数据出了问题。等远程连上产线设备一看果然——标定板拍出来的raw图四个角落的R/G/B通道响应差异超过15%而我们的LSC增益表还是沿用上一代镜头的模板。这就是典型的“镜头换了LSC没跟上”的坑。镜头阴影校正说白了就是解决“镜头中心亮、四周暗”这个物理缺陷。但真正让工程师头疼的不是中心到边缘的亮度衰减这个相对好补而是不同颜色通道衰减不一致导致的色偏。今天就把这块硬骨头啃透。径向衰减模型别被“径向”两个字唬住镜头阴影的物理本质是余弦四次方定律但实际镜头因为设计复杂衰减曲线不是完美的cos⁴θ。我们常用的模型是径向多项式gain(r) 1 a1*r² a2*r⁴ a3*r⁶这里r是归一化半径从图像中心算起最远角点r1。注意r²项主导了大部分衰减r⁴和r⁶修正边缘的细节。踩坑记录有次我直接用r²拟合发现边缘色偏怎么都调不好。后来发现是镜头在边缘区域有非对称畸变r²模型根本描述不了。换成r⁴项后边缘色偏从8%降到1.5%。所以别偷懒至少用r⁴项。实际实现时每个像素的r计算要考虑传感器尺寸和镜头光心偏移// 计算归一化半径注意光心偏移floatdx(float)(x-center_x)/max_radius;floatdy(float)(y-center_y)/max_radius;floatr2dx*dxdy*dy;// 这里踩过坑max_radius应该是图像对角线一半不是宽或高的一半// 否则角点区域的r会大于1增益计算溢出floatgain1.0fpoly_coeff[0]*r2poly_coeff[1]*r2*r2poly_coeff[2]*r2*r2*r2;增益映射R/G/B各玩各的LSC最核心的是“分通道增益”。因为镜头对不同波长光的折射率不同导致R、G、B通道的衰减曲线不一样。这就是为什么暗角看起来是偏色的——中心区域可能偏绿角落偏红。增益映射表通常有两种存储方式1. 网格点方式把图像分成M×N个网格每个网格存一组R/G/B增益值。优点是灵活能处理非对称阴影缺点是标定数据量大产线烧录慢。2. 多项式系数方式存一组多项式系数运行时实时计算。优点是数据量小缺点是对非对称阴影拟合精度差。我的选择量产项目用网格点方式因为产线标定机台可以自动生成网格数据而且现在ISP芯片内存够大。多项式方式更适合低端平台或者算法验证阶段。网格点插值有个细节要注意// 双线性插值别用最近邻否则会出现明显的块状伪影// 这里踩过坑边界处理要小心网格点坐标要落在像素中心floatgain_rbilinear_interp(lsc_grid_r,grid_x,grid_y,grid_width,grid_height);floatgain_gbilinear_interp(lsc_grid_g,grid_x,grid_y,grid_width,grid_height);floatgain_bbilinear_interp(lsc_grid_b,grid_x,grid_y,grid_width,grid_height);// 别这样写直接乘增益会导致暗部噪声放大// pixel_out pixel_in * gain;// 正确做法先做降噪再做LSC或者用带噪声抑制的增益pixel_outpixel_in*gainnoise_floor*(gain-1.0f)*noise_suppress_factor;产线标定不是拍张灰板就完事产线LSC标定是“看起来简单做起来全是坑”的环节。标准流程是用均匀光源照射灰板拍raw图计算每个像素的增益。但实际执行时以下几个问题必须解决1. 光源均匀性校正产线用的积分球或者灯箱本身就有不均匀性。如果不做光源校正LSC会把光源的不均匀当成镜头阴影来补偿。结果就是换一个光源色偏又出来了。我的做法先标定光源的均匀性生成一个“光源校正矩阵”在计算LSC增益时先扣除光源影响。2. 灰板反射率一致性灰板本身也有反射率差异尤其是边缘区域。建议用高精度漫反射板反射率95%并且定期用光谱仪验证。3. 多色温标定别只标D656500K一个色温。实际使用场景有A光源白炽灯、D50、TL84等。不同色温下镜头阴影表现不一样。我一般标定3-5个色温点然后根据AWB结果动态切换LSC参数。4. 温度补偿这个很多人忽略。镜头模组在高温下比如夏天户外40°C镜片间距会变化导致阴影特性偏移。产线标定是在常温25°C下做的到了高温场景LSC就不准了。解决方案在模组中集成温度传感器建立“温度-LSC偏移”模型。或者更简单的方法在ISP中留一个“温度补偿系数”产线标定时同时记录高温和低温数据。调试实战一个典型的色偏问题某项目暗光下拍摄画面边缘偏红。分析raw图发现R通道中心到边缘衰减12%G通道中心到边缘衰减8%B通道中心到边缘衰减10%R通道衰减最大所以边缘相对偏红。按理说加大R通道的增益就能解决。但实际调高R增益后边缘噪声明显增大因为R通道信噪比本来就低。我的解决思路先确认是不是镜头本身的问题——检查镜头镀膜发现R通道在边缘区域的透过率确实偏低。这是镜头设计缺陷LSC只能补偿不能根治。调整LSC的增益上限——把R通道最大增益限制在1.3x以内超过的部分用G/B通道的衰减来平衡。虽然牺牲了一点亮度均匀性但噪声控制住了。在ISP中增加“边缘降噪”模块——LSC增益大的区域降噪强度自动提高。个人经验性建议LSC不是万能的。如果镜头阴影超过30%LSC补偿后噪声会非常明显。这时候应该先优化镜头设计而不是指望ISP擦屁股。标定数据要留余量。产线标定出来的增益建议乘以0.95的系数留5%的欠补偿。这样在极端场景下比如强逆光不会出现过度补偿导致的“白边”现象。动态LSC是趋势。现在的手机摄像头随着变焦、光圈变化镜头阴影特性会变。固定一套LSC参数已经不够用了。我最近在做的项目LSC参数跟焦距、光圈、色温、温度四个维度联动效果比固定参数好一个档次。调试工具要趁手。我习惯用Python写一个LSC可视化工具把raw图、增益图、补偿后效果图叠在一起看。没有可视化光看数值很难发现非对称阴影的问题。产线标定要加校验环节。标定完成后用另一块灰板验证计算最大色差ΔE。如果ΔE3说明标定有问题需要重新标定。这个校验环节能拦截掉90%的产线异常。LSC这个模块说简单也简单说复杂也复杂。简单的是原理复杂的是工程实现。希望这篇笔记能帮你少走一些弯路。下次遇到色偏问题先别急着调AWB看看LSC是不是在捣乱。