ARTICLE DETAIL

资讯详情

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

AWB自动白平衡全解析:ISP图像处理中的色彩校正原理与工程落地

AWB自动白平衡全解析:ISP图像处理中的色彩校正原理与工程落地 做图像处理这一行的应该都遇到过这种场景傍晚室内开了暖光灯泡拿手机拍一张白墙画面黄得离谱人脸直接成了“煮熟的螃蟹”。大多数时候问题不在传感器本身而在ISP里的白平衡。AWBAuto White Balance自动白平衡是ISP pipeline里看起来最不起眼、实际上最折磨人的一个环节。我先说结论AWB解决的是“传感器不知道光源是什么颜色”的问题核心就是根据场景估算光源色温再调整RGB通道增益把白色还原成白色。这篇文章适合刚接触ISP的新人、从FPGA/嵌入式转图像方向的朋友以及正在调摄像头效果但被偏色问题折磨的工程师。我会把AWB的原理、算法、落地实现和调试避坑都讲一遍尽量不堆公式但关键算法思路会给出可参考的实现路径。1. 内容整体设计与思路拆解1.1 AWB到底在整个相机链路里做什么先把它放回ISP pipeline里看。一颗sensor输出的RAW数据进ISP以后一般要依次经过黑电平校正、坏点校正、镜头阴影校正、AWB、去马赛克、CCM色彩校正、Gamma、降噪锐化最后转成YUV或RGB出图。AWB卡在RAW域、去马赛克之前这个位置不是随便定的。因为AWB的本质是对R、G、B三个通道分别乘不同的增益如果在去马赛克之后再乘增益等于在已经形成的彩色图像上再做一次全局色偏一方面会放大插值误差另一方面还会跟CCM发生不可控的叠加调试起来非常被动。在RAW域做每一个像素点还是单通道的Bayer值乘增益不会引入颜色插值噪声物理上最干净。很多新人对AWB有个误解以为它只是“把照片调得更顺眼”。实际上AWB在pipeline里的地位非常关键它直接决定后续CCM能不能找到正确的颜色线性关系。CCM矩阵通常是在某个标准光源下标定的如果AWB给了错误的增益CCM拿到的RGB比值就是错的后面无论怎么调饱和度和色相都救不回来。这也是为什么ISP调试流程里AWB永远是先调的那一步AWB不收敛后面一切免谈。1.2 为什么人眼不需要白平衡sensor需要人眼其实是有“自动白平衡”的只不过它是长期演化的结果。你坐在一盏白炽灯底下看书刚开始会觉得纸面发黄几分钟后就没有知觉了因为视皮层会自动把环境光里多余的黄色“减掉”这叫色适应。但是CMOS sensor没有这个机制它只记录光子数量。同样一张白纸在6500K日光下R/G/B比值和2700K白炽灯下的比值完全不同。如果相机不做任何处理白纸在日光下发白在白炽灯下发橙在荧光灯下发绿。AWB要做的就是模拟人眼的色适应估算出当前光源的色温然后乘一组增益让白纸在任何光源下都尽量回到中性灰白色。这里补一个色温的直觉理解。低色温光源偏红偏黄比如蜡烛、白炽灯高色温光源偏蓝比如阴天天空、LED冷光屏。从2700K到6500K甚至更高同一个场景会让sensor的R/G、B/G比值在很大范围内移动。AWB算法本质上就是在估这个比值估得准增益就准估不准画面就开始偏。你可以用这个色温表来建立直觉光源场景典型色温画面倾向烛光/日出日落1800-3000K偏橙红白炽灯/暖黄LED2700-3500K偏黄冷白荧光灯4000-5000K中性偏绿正午日光5200-5500K中性阴天/阴影6500-7500K偏蓝晴朗天空/极地10000K明显偏蓝1.3 AWB方案设计的整体思路从工程上看AWB算法不管复杂度高低跑不出三件事统计场景颜色信息、估计光源颜色、计算并应用增益。最难的不是第三步而是第二步。因为场景里的颜色是混杂的有物体本身的固有色也有光源的颜色算法需要想办法把“光源的颜色”从混合信号里剥离出来。业界常见路线有三条其一是灰度世界法认为整个场景的RGB平均应该趋近于中性灰然后反推增益其二是白点检测法认为场景里的高亮区域或者饱和度最低的区域大概率来自白色物体用这些区域来估计光源其三是色温估计法把图像颜色比值落在普朗克轨迹黑体轨迹上找最接近的点来估计色温再查表得到增益。实际产品的AWB通常不是单用某一种而是多策略加权融合后面我会展开讲。2. 核心细节解析与实操要点2.1 灰度世界法简单但容易翻车灰度世界法是最朴素最容易上手的AWB实现很多嵌入式工程师第一次写AWB都用它。它的假设是自然场景里所有颜色的平均亮度应该趋近于灰。换句话说如果把一张风景照所有像素的R值求平均、G值求平均、B值求平均这三个平均值应该大致相等。基于这个假设增益的计算就非常直白以G通道为参考gainR G_avg / R_avggainB G_avg / B_avg然后把R和B通道分别乘上gainR和gainBG通道不动。我早期在PC上做仿真就是用这个方法几行Python就能跑出效果对大多数风景照还挺好用。但它的毛病也很致命假设不成立的时候结果直接崩。比如一个场景里有一面巨大的红色围墙R通道的平均值会非常高算法会认为“R太多了”于是疯狂压低R通道增益结果整张图变成青绿色。再比如傍晚的夕阳场景整个画面本来就是橙红色灰度世界法会强行把这种氛围感拉回中性色反而成了“核污染风格”。所以灰度世界法只能作为兜底策略或者预估计不能直接进产品。2.2 白点检测与动态阈值产品级AWB的常见底盘产品级的AWB算法一般不直接拿全图平均值算而是先做一个“白点初筛”。它的核心逻辑是白色物体在任意光源下其R、G、B三个通道的值都应该是接近的且亮度高、饱和度低。反过来想只要从图像里找出这些“疑似白色”的像素用它们的平均RGB来代表光源颜色就能避开大面积纯色物体的干扰。这个初筛怎么做在RAW域一般会先把R、G、B归一化到同一个亮度尺度然后做三个判断亮度不能太低太暗的像素噪声大不做参考亮度不能太高过曝区域的R/G/B比值会被曝死失去颜色信息饱和度要低也就是R/G和B/G的比值不能偏离1太远偏离太大说明这个像素是纯色物体不是白点。筛选完所有“准白点”以后把它们的R、G、B分别取均值再用类似灰度世界的逻辑计算增益。这里有个技巧如果准白点的数量太少比如场景里根本没有白色物体就自动放宽阈值同时加大灰度世界法的权重两边互补。我调过的一些摄像头方案内部其实就是这个结构动态阈值白点检测为主、灰度世界为辅最后用两路结果加权平均。相比单一灰度世界法它在纯色场景下的抗翻车能力要好很多。2.3 色温曲线估计AWB进阶的必修课再往上走就是色温估计法。Bayer RAW里每一个像素只保留一种颜色但假如某个像素真的是白色它在不同色温下R/G和B/G的落点会沿着一条固定的曲线移动这条曲线就是普朗克轨迹在R/G-B/G坐标系的投影。ISP调试时光源箱里会摆一组标准光源D65、D50、A光源等拍完之后把每个光源下灰块的R/G、B/G标在校准坐标系里连成一条曲线这个就是后续算法做色温判断的依据。运行时算法把画面里检测出来的“灰色点”的R/G、B/G统计出来投影到这条曲线上找距离最近的色温点就得到了场景的估计色温然后查表取增益。这个方法的好处是物理意义明确不需要假设全局平均是灰它只需要场景里存在少量白色或灰色物体。坏处是要标定、要维护曲线而且在混合光源场景下灰点的落点会偏离任何一条单色温曲线这时候就得靠多个色温区域的加权决策来扛。我在实际调方案时AWB算法选型基本遵循这个原则如果是低端IPC和USB摄像头用“白点检测灰度世界”就够了成本低还好调如果做的是高端摄影类产品或者对色彩一致性要求高的机器视觉设备一定要把色温曲线的标定做起来能让偏色控制提升一个档次。3. 实操过程与核心环节实现3.1 先用Python把AWB原理跑通不管是做FPGA还是做SoC我建议你拿到算法先别急着上硬件先在PC上用Python验证算法逻辑。这里给你一个能跑的最小复现用OpenCV读图模拟Bayer域增益。实际产品里RAW域的增益是乘在Bayer值上的但仿真阶段直接在RGB图上演示逻辑完全够用import cv2 import numpy as np image cv2.imread(test.jpg).astype(np.float32) b, g, r cv2.split(image) # 灰度世界法以G平均为参考 avg_r np.mean(r) avg_g np.mean(g) avg_b np.mean(b) gain_r avg_g / avg_r gain_b avg_g / avg_b r_awb np.clip(r * gain_r, 0, 255) b_awb np.clip(b * gain_b, 0, 255) out cv2.merge([b_awb, g, r_awb]).astype(np.uint8) cv2.imwrite(awb_result.jpg, out)这个demo跑通以后你可以再试试只统计画面最亮的5%像素作为白点效果会更接近产品级。步骤是算全图灰度取阈值让最亮区域参加统计把它们当成白点再用平均值算增益。我个人建议把这些实验都写成对比脚本同一张图、同一个场景三套算法跑出来摆在一起看你很快就能建立“什么场景下哪种算法失效”的直觉。3.2 在FPGA/嵌入式SoC上怎么落地FPGA上做AWB第一步永远是分层统计逻辑、决策逻辑、应用逻辑要分离别揉在一起。先说统计。AWB不需要全分辨率统计每个像素成本太高常见做法是先把图像降采样或者利用ISP里已有的统计窗口对每一帧图像生成一个颜色直方图。统计模块的输入是黑电平校正之后的Bayer数据输出是R/G/B各自的像素和、像素数、以及满足白点条件的像素掩码。决策模块不必逐帧推理因为光源色温变化是慢过程可以每隔几帧或者每到一帧的statistics ready信号触发一次。决策模块里跑的是简单比较逻辑和查表把统计得到的R/G、B/G值和预设的色温区间比较落在哪个区间就选哪个增益。比如设定日光增益为R1.1、B1.4暖光增益为R1.4、B0.9然后做线性插值。这里要记住增益系数本身不要直接改成浮点FPGA里一般用定点数表示常见的做法是增益乘以256或者1024的固定倍率输出时再右移避免小数运算占用大量DSP资源。应用模块的位置要在Demosaic之前对Bayer图像里的R通道乘增益R对B通道乘增益BG通道可以顺带做Gr/Gb平衡微调。这里有一个资深工程师容易踩的坑有些人为了省事把AWB的增益应用放到了Demosaic之后、RGB转YUV之前直接对三通道彩色图乘系数结果就是边缘容易出现彩色锯齿因为RGB插值已经做完了你再放大某一通道等于把插值过程的微小误差也跟着放大。我做FPGA方案时AWB乘加模块是直接吸在去马赛克之前的Bayer流里一个时钟周期处理一个像素延迟只有几个周期效果和SoC里的专用硬件没有本质区别。3.3 增益平滑和AE联动的处理只有AWB模块还不够还要处理它和自动曝光的联动。很多偏色问题不在AWB本身而在AE和AWB互相抢。想象一下画面里走进一个人AE开始调整曝光画面整体亮度变化AWB的统计也跟着变了AWB还没来得及收敛AE又变了画面颜色就来回跳。解决方案通常是两件事第一AWB统计前先做亮度归一化让统计结果不随曝光变化剧烈漂移第二AWB输出的增益不能一帧一变要做IIR滤波或者限幅。我给一个通用的参数模板增益变化步长每帧限制在一个小范围比如每帧最大变化1/64统计窗口可以用过去的8帧做低通滤波AE和AWB还可以增加联动锁AE稳定多少帧之后才触发一次AWB重新计算。这些参数不同平台略有差异但思路是一致的——颜色变化永远比亮度变化慢半拍观众才不会觉得画面在“闪”。4. 常见问题与排查技巧实录4.1 画面偏色先分清是RAW的问题还是AWB的问题调试AWB遇到偏色心情容易烦躁但第一件事永远是定位问题在哪个环节。我的习惯是先用调试工具拉一帧RAW数据在PC上将RAW直接做简单的线性显示不做任何ISP处理然后看画面里的灰色物体灰卡、白墙的原始R/G、B/G比例。如果RAW域的灰块本身R/G和B/G就符合当前光源下的理论值问题就在AWB的增益计算或应用环节如果RAW域灰块色偏就离谱问题更可能在sensor黑电平没有校正好或者镜头 shading 影响了颜色均匀性。这里多说一句黑电平很多偏色案例最后查出来根本不是AWB算法的问题而是黑电平校准值不对。黑电平偏了相当于在每个通道的暗电流补偿上产生了固定偏差这个偏差会在增益乘上去以后被放大导致暗部偏绿或者偏紫。所以AWB调试前先把黑电平校准这一步做扎实能省掉接下来一半的排查时间。4.2 AWB跳变/闪烁问题排查用户反馈“画面颜色正常但镜头移动一下颜色会抖”这类问题多半是AWB的统计结果不够稳定或者增益套用了极限值。排查顺序一般是先关掉AWB的增益输出手动锁一组增益看颜色还抖不抖。如果不抖确认AWB统计或决策问题如果还抖查AE是不是在跟着场景频繁变化。确认是AWB统计抖动后再看统计窗口设置把统计区域从全图改成中央偏下的主区域能屏蔽天空、强光源等高亮区干扰。再做统计时序处理连续多帧统计结果求平均或者对增益做最大步长限制。我调过的最极端的情况是LED灯光下光源本身以100Hz频率闪动AWB统计随着灯的频闪周期波动解法是把统计窗口拉长到覆盖多个频闪周期再做时间滤波才能稳住。4.3 混合光源场景的偏色混合光源是AWB的头号难题。办公室开着窗窗外是冷色天空室内是暖色射灯同一个画面里白纸在窗口区域偏蓝、在射灯区域偏黄。任何一个全局增益都无法同时满足两边的白平衡这时候方案分成两档低端方案是加“光源模式选择”让用户手动切“室外优先”还是“室内优先”中高端方案是分区统计把画面划分成多个区域每个区域独立估计色温再通过空间滤波生成一张“色温权重图”对图像做空间自适应增益。第二种方案效果好但计算量大在低帧率或者监控场景还可以接受。如果你手里的平台不具备分区能力一个折中做法是把统计的加权重心放在画面中央区域边缘区域让点也没有办法因为人眼注意力通常集中在画面中央。确实会牺牲边缘色彩一致性但主观体验比全图平均要好很多。4.4 AWB调试需要一个标准流程AWB效果好不好不能靠肉眼“拍着看”必须靠标准流程。我常用的流程是准备一个标准灯箱能切D65、D50、TL84、A光源等一张灰卡或者X-Rite 24色卡里的灰阶部分。把摄像头对着灯箱里的灰卡分别在每个光源下记录AWB统计值和输出增益验证R/G、B/G落点是否在预期曲线上。然后再拍一个标准色彩环境确认纯色物体不会把AWB带偏比如红色杯子、绿色植物分别占画面一半的场景。把这两类测试结果记到一张表里作为每次固件改动的回归基线。测试场景预期结果常见异常D65光源下灰卡R/G接近参考值灰卡呈现中性灰卡偏红检查黑电平或增益上限A光源下灰卡B通道增益明显增大灰卡中性灰卡偏蓝说明低色温估计不到位大面积红色物体灰度世界法权重应降低白点检测应主导画面发青说明灰度世界权重太大画面明暗交替增益平滑不出现跳变颜色闪烁统计未做时间滤波5. 工程落地与算法演进趋势5.1 低成本SoC上的AWB调试习惯现在很多IPC和车载摄像头用的都是集成了ISP的SoC比如富瀚这类安防芯片AWB已经以硬件模块的形式固定在里面不需要你自己写算法逻辑但需要配置寄存器。这类平台的AWB开放接口通常包括统计窗口坐标、白点阈值上下限、最大/最小增益、自动增益区间、输出增益观察寄存器。我接手过的项目里最容易出问题的是寄存器默认的最大增益给的过宽比如允许B通道增益拉到4倍这在低照度下会把蓝色噪声放大得没法看。所以我的习惯是把增益范围限制在0.5到2.5倍之间除非有特殊的弱光需求否则不放开上限。另外这类SoC的ISP调试工具一般都能看到AWB统计的散点分布图R/G-B/G坐标。你要学会看这个图正常情况下灰卡的点应该落在标定曲线附近偏离太远就要检查是不是白点检测阈值配得太松把大量非白像素纳入了统计。很多“拍天空偏紫”的案例追根溯源都是白点检测把蓝色天空当成了白点落点直接拉到了高色温区。5.2 从传统AWB到AI辅助AWBSNN的新探索最近几年有个方向引起了我注意就是用SNN脉冲神经网络做AWB相关的光源分类和色彩估计。传统ISP里的AWB统计模块本质上是在做颜色直方图而SNN的特点是使用脉冲时序来编码信息神经元只在特定条件下发放脉冲功耗天然比传统CNN低。研究人员尝试用SNN对场景进行光照分类暖光、冷光、混合光、异常光驱动、频闪光源等然后把分类结果作为AWB决策图的前端这样AWB可以更智能地选择切哪套策略而不是像现在这样用一个固定权重融合。这个方案目前量产案例不多主要停留在预研和学术阶段。但我判断它在低功耗边缘端是有潜力的尤其是电池供电的智能摄像头、事件相机这种设备SNN的低功耗特性跟AWB这种“慢变决策”任务很契合。如果你做的是边缘AI设备可以关注一下这个方向的进展短期替代不了传统ISP算法但很有可能会作为辅助光源分类器嵌入到ISP链路里提升混合光源场合的鲁棒性。5.3 AWB与HDR、多帧融合的联动最后补一个容易忽略的问题AWB在HDR模式下的行为。HDR多帧曝光时短帧可能暗部信噪比很差长帧可能高光溢出如果直接用合成后的HDR图做白点统计很容易统计到过曝或欠曝区域。正确做法是让AWB统计模块知道哪些像素来自长帧、哪些来自短帧给不同信噪比区域设定不同的统计权重。多帧降噪同理降噪后的图像颜色已经被时间域平均过AWB统计再做一次可能滞后或者过度平滑。这里我的建议是开启HDR或运动多帧降噪时AWB的统计输入应该前置到RAW域、滤波之前的帧上得到的增益再应用到最终合成帧这样颜色收敛更快也不会被运动拖尾影响。我个人的体会是AWB是个“三分算法七分调试”的模块。原理几页纸就能讲完真正复杂的是场景覆盖、参数取舍和与AE/CCM之间的平衡。每次拿到新平台我都不急着调参先把标准灯箱下的RAW流和统计值摸清楚再针对实际场景一点点收敛。把调试基线建好后面遇到的偏色问题大多都能快速定位到具体环节。这套方法陪我调过不少摄像头方案今天整理出来希望对你有用。
返回列表