镜头阴影校正与坏点校正调试实战 - 第3节
亮度阴影校正原理:增益补偿模型
亮度阴影,说白了就是镜头中心亮、四周暗的现象。你拿手机对着白墙拍一张,如果四角发暗,那就是典型的亮度阴影。我刚开始做ISP调试时,第一件事就是先看raw图的四角亮度——这个习惯一直保留到现在。
校正的原理其实很简单:给暗的区域多补点增益,亮的区域少补或不补。这就是增益补偿模型的核心思想。
增益补偿模型
假设镜头中心亮度为1.0,四角亮度只有0.6。那校正时,中心增益设为1.0,四角增益设为1/0.6 ≈ 1.667。这样乘上去,整张图就均匀了。
数学表达就是:
I_corrected(x, y) = I_raw(x, y) × Gain(x, y)
其中 Gain(x, y) 是每个像素位置的补偿系数。这个系数怎么来?靠标定。
关键点:增益不能无限大。我曾经遇到过一款模组,四角亮度只有中心的40%,算下来增益要2.5倍。结果校正后四角噪声爆炸,暗部全是彩噪。所以硬件设计时就要控制好镜头阴影深度,一般建议四角不低于中心的50%。
标定流程
标定增益系数,通常分三步:
- 拍灰卡:用均匀光源照射灰卡,拍一张raw图
- 计算增益:以图像中心为基准,计算每个像素位置的补偿系数
- 生成LUT:把增益系数存成查找表,供ISP运行时调用
嗯,这里要注意:灰卡必须均匀,光源不能有暗区。我见过有人用手机闪光灯当光源,结果校正出来反而更不均匀——因为光源本身就不均匀。
网格(Mesh)校正原理
如果每个像素都存一个增益值,那LUT会非常大。比如200万像素的图像,每个像素存一个16位增益,光LUT就要4MB。这在嵌入式系统里根本扛不住。
所以实际工程中,我们不会逐像素存增益,而是用网格的方式。
什么是网格?
把图像分成M×N个网格,每个网格顶点存一个增益值。比如17×13的网格,总共221个顶点。存储量从4MB降到442字节,差了将近一万倍。
我习惯用17×13的网格,水平17个点,垂直13个点。为什么是这个数?因为大部分sensor的分辨率是4:3或16:9,17×13刚好能覆盖,而且网格密度够用。
| 网格规格 | 顶点数 | 存储量(16bit) | 适用场景 |
|---|---|---|---|
| 9×7 | 63 | 126字节 | 低端芯片,性能受限 |
| 17×13 | 221 | 442字节 | 主流方案,平衡性能与精度 |
| 33×25 | 825 | 1650字节 | 高精度需求,如医疗影像 |
个人经验:网格太疏会校正不干净,太密又浪费资源。17×13是我试过的最优解。如果你用的是广角镜头,建议加到33×25,因为广角边缘的亮度变化更剧烈。
插值算法:双线性与双三次
网格只存了顶点的增益值,那网格内部的像素怎么办?插值。说白了就是根据周围四个顶点的值,算出当前像素的增益。
双线性插值
这是最常用的方法。原理很简单:
- 找到当前像素所在的网格
- 取四个顶点的增益值
- 按距离做两次线性插值(先水平,再垂直)
数学公式长这样:
G(x, y) = (1-Δx)(1-Δy)·G00 + Δx(1-Δy)·G10 + (1-Δx)Δy·G01 + Δx·Δy·G11
其中Δx、Δy是像素在网格内的归一化坐标,范围0~1。
双线性插值的优点是计算量小,硬件实现简单。大部分ISP芯片都硬支持这个算法。缺点呢?增益曲线不够平滑,在网格边界处可能会有肉眼可见的跳变。
避坑指南:我曾经在一个项目里发现,用双线性插值校正后,图像上出现了规则的条纹。查了两天才发现,是网格顶点增益标定不准,加上插值算法放大了误差。后来我把网格从17×13改成33×25,问题就解决了。所以网格密度不够时,别急着怪插值算法。
双三次插值
双三次插值用4×4=16个顶点来计算,而不是双线性的2×2=4个。它用三次多项式拟合增益曲面,结果更平滑。
优点很明显:
- 增益曲线连续且一阶导数连续
- 网格边界处没有跳变
- 校正效果更自然
缺点也很明显:
- 计算量是双线性的4倍以上
- 硬件实现复杂,很多芯片不支持
- 对噪声更敏感
我个人建议:除非你的芯片算力足够,或者对画质要求极高(比如专业相机),否则用双线性就够了。双三次带来的提升,在普通场景下肉眼几乎看不出来。
两种算法对比
| 对比项 | 双线性插值 | 双三次插值 |
|---|---|---|
| 计算量 | 低(4次乘加) | 高(16次乘加+多项式) |
| 平滑度 | C0连续 | C1连续 |
| 硬件支持 | 几乎所有ISP | 仅高端ISP |
| 适用场景 | 手机、安防、车载 | 专业相机、医疗影像 |
知识结构图
下面这张图把亮度阴影校正的完整流程串起来了:
从图上你能看到,整个流程就是:先标定出增益系数,然后用网格压缩存储,最后通过插值还原到每个像素。每一步都有取舍,没有银弹。
调试建议:如果你刚接手一个项目,先别急着调算法参数。第一步应该是确认镜头阴影的原始数据——拍一张raw图,用工具看四角亮度比。如果比0.5还低,先找硬件改镜头,别指望算法能搞定一切。