色彩阴影(Color Shading)校正原理
色彩阴影,说白了就是画面中间和边缘颜色不一样。你拍一张纯灰卡,中间发红,边缘发绿,这就是典型的 Color Shading。我刚开始调这个的时候,总觉得是镜头没装好,后来才发现——这是 sensor 和 lens 共同作用的结果。
今天咱们就把它拆开揉碎了讲。核心就三个东西:R/G、B/G 比率校正,色彩偏移补偿,还有那个让人头疼的色温依赖性。
R/G、B/G 比率校正
先问个问题:为什么是 R/G 和 B/G,而不是直接用 R、G、B?
因为 G 通道最稳。在 Bayer 阵列里,G 像素数量是 R 和 B 的两倍,信噪比天然高。所以业内习惯用 G 做基准,看 R 和 B 相对 G 的偏移量。
核心公式:
- R/G 增益 = 目标 R/G 值 ÷ 当前 R/G 值
- B/G 增益 = 目标 B/G 值 ÷ 当前 B/G 值
目标值通常取画面中心区域的 R/G、B/G 均值。
校正流程分三步:
- 采集原始数据——拍一张均匀光照下的灰卡,提取每个像素位置的 R、G、B 值
- 计算比率矩阵——对每个像素算 R/G 和 B/G,生成两张二维增益图
- 应用校正——用增益图对原始图像逐像素乘回去
我在项目中遇到过一个问题:灰卡本身不够均匀。你想想看,如果灰卡本身就有 1% 的色差,那校正出来的增益图就是错的。后来我改用积分球加标准白板,才把这个问题压下去。
我的习惯:校正前先拍一张暗场,确认 sensor 本身没有固定模式噪声。否则你校正的是噪声,不是 shading。
色彩偏移补偿
R/G、B/G 比率校正能解决大部分问题,但还不够。为什么?因为镜头对不同波长的光衰减不一样。比如蓝光衰减快,红光衰减慢,这就导致边缘偏红。
色彩偏移补偿,就是针对每个像素位置,再做一个精细的色差修正。具体做法是:
- 把图像分成 M×N 个网格(常见 9×9 或 17×17)
- 每个网格中心点算一个 R/G、B/G 目标值
- 网格之间用双线性插值平滑过渡
嗯,这里要注意:网格太密会引入噪声,太疏又校正不干净。我一般从 9×9 开始试,看边缘色差是否收敛。
| 网格密度 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| 5×5 | 计算量小 | 边缘校正粗糙 | 低分辨率、低端 sensor |
| 9×9 | 平衡性好 | 中等计算量 | 大多数手机、安防摄像头 |
| 17×17 | 校正精度高 | 计算量大,易引入噪声 | 高端单反、医疗影像 |
我曾经踩过的坑:网格校正后,画面出现明显的块状色差。排查了半天,发现是插值算法没处理好边界。后来在网格边界加了 2 个像素的 overlap,问题就解决了。
色温依赖性分析
这是最让人头疼的部分。同一个镜头,同一个 sensor,在 D65(6500K)下校正得好好的,换到 A 光源(2856K)就偏色了。为什么会这样?
因为 lens 的色散特性随波长变化。低色温下红光成分多,高色温下蓝光成分多,镜头对不同波段的透过率曲线不一样。说白了,Color Shading 是跟光谱绑定的。
我建议的做法是:
- 至少采集 3 个色温点的 shading 数据:D65、TL84、A 光
- 每个色温点生成独立的 R/G、B/G 增益图
- 运行时根据 AWB 估算的色温,在增益图之间做线性插值
举个例子:如果当前色温是 4000K,介于 D65(6500K)和 TL84(4000K)之间,那就用 TL84 的增益图为主,稍微 blend 一点 D65 的数据。
色温插值公式(简化版):
gain = gain_TL84 * (1 - α) + gain_D65 * α
其中 α = (CCT - 4000) / (6500 - 4000)
α 范围 0~1,CCT 是当前相关色温。
我在项目中遇到过极端情况:某款镜头在 2700K 和 6500K 下的 shading 曲线完全相反。中间色温怎么插都不对。后来没办法,只能把色温点加密到 5 个,才把问题压住。
一个小技巧:如果 sensor 支持多增益模式(HDR 合成),每个增益档位的 shading 也要单独标定。因为 sensor 内部模拟增益会改变 R、G、B 的相对响应。
下面这张图总结了 Color Shading 校正的完整流程:
最后说一句:Color Shading 没有一劳永逸的解法。换一颗镜头、换一个 sensor、甚至换一个 IR cut filter,shading 曲线都会变。我的经验是——标定流程自动化,每次换物料重新跑一遍,别偷懒。