ARTICLE DETAIL

资讯详情

深耕郑州网站建设与运营推广的一线实战洞察。

ISP AWB白平衡实战详解:从灰度世界到色温曲线的算法与工程落地

ISP AWB白平衡实战详解:从灰度世界到色温曲线的算法与工程落地 做图像处理这些年我发现一个问题很多人一听到ISP-AWB第一反应是白平衡不就是调色温嘛有什么好讲的。说这话的人多半没在嵌入式平台上把白平衡真正调稳过。给一张偏蓝的照片加上红色通道增益看起来确实简单但要让它在白天、夜晚、室内、室外、暖光灯、混合光源下都能稳定输出不偏色牵扯到的东西远比想象中多。这篇文章就从一个实战过的ISP工程师视角把AWB从算法到工程实话实说地拆一遍适合做摄像头模组、FPGA图像采集、IPC/车载方案或者单纯想搞懂ISP pipeline的人看看。我先交代一下背景我最早接触AWB是在一颗老掉牙的CMOS sensor上跑的是自研的ISP pipeline后面又在FPGA上实现过整个3A链路。踩过最多的坑不是算法跑不通而是算法跑通了画面上墙就是黄、就是绿、就是莫名奇妙肤色发灰。后来才慢慢明白AWB不是一个孤立的模块它跟AE、gamma、CCM、去马赛克都是串在一根绳上的。你要把它做好需要的不只是一套灰度世界公式而是对整个ISP流程的理解。接下来我尽量把这篇写成一份能直接拿去用的实战笔记。我不会堆公式也不会贴一堆论文推断只讲我实际验证过、能在硬件上跑起来的东西。1. 先搞清楚AWB在ISP pipeline里到底在哪一步、管什么1.1 为什么一张白纸在不同光线下会变成黄纸和蓝纸想理解AWB必须先理解一个物理事实人眼和CMOS sensor对光源的响应是不同的。人类大脑会自动削弱环境光的影响你站在白炽灯下看一张白纸它仍然是白的但sensor不这么干它老老实实地把光源的光谱反射记录下来白炽灯的偏橙光谱打在纸面上拍出来就是一张黄纸。这个现象在色彩学里叫色貌恒常性。人眼天生自带一套白平衡而sensor没有所以必须在ISP里通过算法补偿。AWB干的活用一句话说清楚就是估计当前光源的色温推算出场景中本来应该是中性灰/白色的点然后给三个通道分配不同的增益把色偏拉回来。在ISP pipeline中AWB的位置通常是在去马赛克demosaic之后、色彩校正矩阵CCM之前。为什么放在这因为demosaic之后才有完整的RGB三通道信息可以计算颜色比值放在CCM之前是因为AWB补偿的是光源引起的通道增益差CCM补偿的是光学与sensor的串扰两者线性叠加先做AWB再做CCM顺序不能反。有些实现会放在RAW域直接用R、Gr、Gb、B四个通道做白平衡好处是省掉demosaic的运算量坏处是统计信息不如RGB域准确。FPGA上我见过两种都有的情况多数低成本方案会选择在RAW域做因为AWB的统计宏块可以直接复用Bayer pattern的原始数据省一组缓存。1.2 AWB、AE、AF怎么交互为什么说它是3A之一AWB很少独立工作图像层面的三个自动——自动曝光AE、自动白平衡AWB、自动对焦AF——合称3A。它们是互锁的曝光时长变了信号增益变了统计到的最亮值、平均亮度、饱和像素分布都会变而这些恰恰是AWB判断场景的重要输入。举个例子AE目标亮度调高了整个画面变亮原本接近灰的暗部噪点会被放大AWB统计时容易误判大面积暗部为灰色反过来AE欠曝时高光被削掉本来用来定位白点的像素找不到了色温估计就会飘。所以做AWB调参时手边必须有一套AE曲线和AWB联动。很多团队画蛇添足地想先单独把AWB调到完美结果一接上AE就全乱就是这个原因。AWB和AE还有个更直接的耦合点帧曝光时间和增益变化最快的时候AWB统计值会出现短时间的异常波动必须在统计端做帧间滤波。我后面会在常见问题里详细聊这个闪烁现象。2. 核心算法与工程方案选型不要只会抄灰度世界2.1 灰度世界法为什么是基本盘又为什么在纯色场景翻车AWB最经典的算法是灰度世界法Gray World假设一幅场景中所有颜色的平均反射率是灰色即R、G、B三通道的均值应该相等。用公式表达就是R_gain G_avg / R_avgB_gain G_avg / B_avg。它的实现极其简单在FPGA里就是几个累加器加除法器的事所以在低端IPC方案里非常常见。但它有个致命假设场景里的色彩要足够丰富。如果你画面里是大片的绿草地、蓝墙、红布灰度世界假设直接失效。举个我实际遇到过的案例一个室内监控场景画面中央是一整面办公绿植墙灰度世界法算出来的色温偏得离谱整幅画面发品红。为什么绿色物体在R通道均值偏低G通道均值偏高算出来R_gain被拉大结果把白墙也染红了。针对这种问题工程上有几种补丁一是降低统计权重只取图像中饱和度较低、亮度中等的那部分像素参与均值计算相当于我只相信灰一点的点二是跟下面的白点法做融合按场景置信度切换。真正的项目里基本不会只用纯灰度世界。2.2 白点法找画面里本来就应该是白色的点白点法Perfect Reflector / White Patch的思路是把画面中最亮的那些像素当作白色参考。基于一个假设场景中总存在一个接近镜面反射或白板的高亮区域它的真实颜色就该是白的那边的大比例色彩偏差就是光源造成的。实际工程里白点法不会傻到直接找全图最亮点那会找到灯泡或者太阳所以必须加约束条件。我自己的FPGA实现里白点筛选的条件是亮度大于某个阈值但没到饱和例如Y在200~245之间8bit量化饱和度RG差值和BG差值低于某个阈值且像素占比超过一定比例。然后对符合条件区域的R/G和B/G做加权平均得到一个色温估计。白点法适合高光场景、户外晴天、有高反射面的情况和灰度世界正好互补。很多商用ISP的AWB都是这两者的加权混合再加一个色温查表来兜底。2.3 色温曲线法跟物理模型对表比纯统计更抗干扰还有一个工程上非常扎实的方向叫色温曲线法先在实验室用标准光源D65、A光源、CWF、TL84等拍灰卡记录不同色温下R/G和B/G在统计空间里的分布拟合成一条色温-色比曲线。运行的时候把当前统计到的R/G、B/G值映射到这条曲线上就能反推当前色温然后直接查表获得增益。这条路的好处是物理意义明确、场景鲁棒性强而且可以针对你的sensor做定制标定——同一个白炽灯A sensor和B sensor拍出来的色比根本不一样纯理论模型通用性差。坏处是需要实验室配合产线上要跑标定流程。我在FPGA项目里采用的是曲线法做最终兜底白点法和灰度世界法做短期估计三者投票后选置信度最高的结果。2.4 在FPGA上实现AWB有哪些硬约束说完算法思路聊一下落地的约束。FPGA和PC仿真最大的区别是FPGA里除法器和缓存都是稀缺资源流水线的每一级延迟都要算。统计端一般做法是把图像切成16x16或32x32的宏块每个宏块单独统计R/G/B之和与像素数然后按宏块汇总到二值化直方图。宏块太大则空间分辨率低纯色物体会盖过一切宏块太小则统计噪声大而且DDR带宽受不了。定点化AWB增益一般用12bit定点表示G通道增益固定为1.0或者512/1024R/B增益围绕1.0上下浮动。用整数乘法加移位避免浮点除法。除法只用在统计归一化的最终阶段。帧级处理 vs 像素级处理AWB不需要逐像素实时处理它只需要一帧统计值。所以FPGA架构通常是采样统计单元和增益应用单元分离的。增益应用单元是逐像素乘一个固定值这个值每帧更新一次统计单元则跑在全分辨率或降采样后的低频通路。FPGA实现里还有一个细节AWB统计通常放在demosaic之后、RGB转YUV之前。如果放在demosaic之前Bayer pattern上的R/G/B位置不齐统计时需要对插值出来的伪像素做处理增加复杂度放在demosaic之后就要等demosaic完成整行才能统计延迟会增加需要权衡。3. 实操落地从初始化到跑通一版稳定AWB的完整过程3.1 初始化阶段给AWB一个不会说胡话的初值AWB要能快速稳定但也不能在开机第一帧就乱跳。我的做法是初始化阶段不给AWB全自动权重先锁定一个保守色温值。比如Sensor默认在室内场景时色温初始化到4500K~5000K增益初值R1.0、B1.0等AE稳定后AWB才参与调节。否则开机瞬间画面忽蓝忽黄非常劝退。如果你做的是IPC或车载DVR还要考虑不同sensor上电时序。有些sensor冷启动时Bayer pattern输出会先闪几帧统计值完全不可信。这个阶段如果AWB开启了会让增益限幅器疯狂上下跳动后续恢复会很慢。所以工程上必须有个帧数安全期例如前10帧只统计不调整。3.2 统计模块如何科学地选点、分区、定权重统计是整个AWB的地基统计做错后面所有算法都是空中楼阁。我常用的统计策略分三层像素级筛选先排除过暗Y16、过曝Y240和饱和度过高的像素。过暗的像素噪点大色比浮动剧烈过曝像素三通道被削顶色比失真高饱和像素会让灰度世界假设失效。区域级加权图像中心区域给予更高权重边缘区域尤其是四角因为镜头暗角lens shading的影响即使做了校正色比也会偏移。直接不加权会导致画面中心颜色正确、四周发青的经典问题。时间级滤波统计得到的R/G、B/G值不要直接用于增益计算先做一阶IIR滤波例如new_value (3 * old 1 * new) 2的权重。帧间色温突变平滑掉防止画面闪烁。还有一个我踩过的坑统计宏块如果只放在有效像素区域内一旦实际画面尺寸小于ISP输入尺寸比如视频裁剪后统计区会扫过黑色无效区域导致亮度均值被拉低AWB误判为低色温。这个在调试时一定要先输出统计Region的可视化结果看一眼不要直接信曲线。3.3 增益计算为什么G通道不动R和B怎么配AWB增益计算的核心原则是保持G通道增益固定调整R和B因为Bayer阵列中G像素数量是R和B的两倍人眼对绿色最敏感固定G能最大程度保持亮度稳定。计算方法假设你估计出当前色温下的标准白点R_target/G_target 1.15B_target/G_target 0.85而统计到的当前值R_cur/G_cur 0.9B_cur/G_cur 1.2则R_gain (R_target/G_target)/(R_cur/G_cur) 1.28B_gain 0.71。最终像素值R_out R_in * R_gainG_out G_inB_out B_in * B_gain。增益限幅也很重要。一般R_gain、B_gain限制在0.5~2.0之间防止在极端光源下增益过大导致噪点爆炸。实际在暗光场景下B通道增益拉到1.8时蓝色通道噪声会有很明显的放大画面会偏紫或者全是彩噪。所以AWB的增益上限要和ISP的降噪模块耦合做。3.4 从实验室标定到现场联调一个可复用的调参流程我自己的调参流程分五步每一步都有明确的输出物灰卡标定用标准灯箱D65、A光源、TL84、CWF、Horizon分别拍灰卡记录每个色温下统计到的R/G、B/G值拟合出这条sensor对应的色温-色比曲线作为后面映射表的底表。真实场景采样在早中晚、晴天阴天、室内白炽灯/荧光灯/混合光下分别录一段raw流离线回放统计值确认统计模块输出的R/G、B/G能落在曲线合理范围内。增益映射表生成根据步骤1的曲线生成一张色温到R_gain/B_gain的LUT插值间隔建议不大于100K超过则跳变会肉眼可见。FPGA联调上板后用在线调节工具逐步切换灯箱色温观察画面中灰阶是否保持中性同时输出统计值和LUT索引做日志比对。边界场景回归跑一遍黑暗房间突然开灯逆光窗户显示屏前自拍这些容易让AWB崩溃的场景确认时间滤波和模式切换是否正常工作。这个流程看起来繁琐但能一次性解决80%的后端问题。很多团队跳过第2步直接上第3步结果就是灯箱里Perfect一到实景就翻车因为真实光源永远比灯箱复杂。4. 常见问题与排查技巧实录那些教科书上不讲的坑4.1 画面偏色半天找不出原因可能是统计区被挡了现场反馈最多的一类bug明明AWB算法看起来没问题代码也没改动但画面偏绿。优先怀疑对象不是增益计算而是统计区。我遇到过几次都是因为代码里一个rounding截断导致宏块坐标偏移了半个块把一条原本黑色边框的像素算进了白色区域。排查方法很老土但有效把统计Region画在预览图上逐帧去看它到底框住了什么内容。如果你发现统计区边缘压到了暗角或者画面外的无效数据那偏色是必然的。另一个容易被忽视的是竖屏/横屏切换时宽高互换统计宏块坐标没跟着旋转这个在IPC常见。4.2 场景切换时AWB剧烈闪烁时间滤波系数怎么选从室内走到阳光下画面狂闪好几秒是另一个高频问题。根源是帧级统计发生了突变增益直接跳到位导致肉眼可见的色温跳变。解决方法是给AWB增益加时间平滑。我常用的系数是正常场景alpha0.5~0.7帧间增益变化柔和检测到场景突变时强制alpha跳到1.0直接响应。检测突变的依据可以看统计值帧间差比如|R/G差值| 0.15认为场景切换。这个思路本质上是平时尽量稳突变不拖沓比全程固定一个系数要好用。4.3 混合光源下肤色发灰、发紫怎么取舍以前的一个安防项目使用现场是大厅顶灯荧光灯加窗外阳光拍人脸时肤色经常发灰。为什么因为两个光源同时作用——人脸一半受日光色温约6000K照射一半受荧光灯色温约4000K照射AWB只能选一个全局增益。事后不管偏向哪边另一侧都偏。这种场景的工程处理一是结合人脸检测区域做加权统计人脸肤色本身就是先验二是在增益计算时给R通道增益设置一个下限避免肤色被拉灰。三是坚定接受物理限制——全局AWB无解于混合光源该上局部AWB分区域增益时才上别硬扛。成本敏感项目里我会选择牺牲次要区域优先保画面中央的人脸。4.4 极端光源和算法逃生门当AWB干什么都不对最后一个经验是给系统留一个逃生门。当统计值连续多帧处于色温映射表的边界之外比如超低色温暖光灯下R/G大得离谱或置信度低于阈值时AWB应当自动切换到预设的最安全色温并锁住增益而不是继续发疯。这个机制在灯串、蜡烛、彩色霓虹灯这种非标准光源下尤其重要——那根本不是色温能描述的。另外AWB和AE联动出现呼吸效应时优先查AE是否在感光度切换阈值上反复跳变。曝光参数抖动会导致统计像素亮度分布变化AWB跟着抖看起来像AWB的bug实际上是AE的。后记关于SNN和AI做AWB的一点个人看法最近行业内确实有讨论用神经网络或SNN脉冲神经网络做AWB的比如直接用统计特征预测色温增益甚至端到端学习RGB到目标色温的映射。我个人认为这是个有意思的方向尤其是在大算力的移动端SoC上已经能看到部分落地。但在中低端IPC和FPGA平台算力和DDR带宽都不支持跑一个完整CNNSNN的工程化程度又较低短期内主流的自研方案依然是统计筛选加权估计色温LUT最多加一个人脸/场景标签模块。如果对新方向感兴趣建议从轻量级MLP预测色温开始试输入是已有的色比直方图特征输出是增益先离线训练再量化部署比直接上SNN要稳得多。但要说替换传统AWB我持保留态度毕竟AWB本质是一个物理光源估计问题统计先验远比黑盒预测可控。最后分享一个我自己的实战习惯每次改AWB参数前先截一段raw流存档。改完再截一段离线逐帧回放对比。等你被现场看起来增加了饱和度但偏色更厉害折磨过几轮之后就会明白这个存档习惯有多救命。AWB这东西急不来慢工出细活。
返回列表