本文系微信公众号《大话成像》,知乎专栏《all in camera》原创文章,转载请注明出处。大话成像读者QQ 交流群2 :833282006 大话成像技术论坛:ww.dahuachengxiang.com本站教学视频《图像传感器技术与应用》《成像系统图像质量调试》《成像算法基础(python版)》 《成像系统镜头光学》《新版图像质量测试测量与国际标准》《新版cmos sensor测试测量与国际标准》《新版数字成像系统42讲》课程大话成像淘宝教育官方网店有售:https://shop322456667.taobao.com/
之前的公众号文章介绍了树莓派的自动曝光算法,这一期我们介绍树莓派的自动白平衡算法。树莓派的3A都是放在linux的userspace,并且开源。相机驱动则是放在kernel层,所有ISP的相关驱动都是由博通负责,与GPU代码被一起封装成库,不开放给用户。camera sensor的驱动文件是开放的,但是因为调用sensor驱动的代码不开放,所以用户也没法自己添加新的image sensor驱动。AWB代码文件是awb.cpp,这部分是完全开源的。
树莓派的awb算法设计是基于一个贝叶斯假设来解决自动白平衡问题。即在给定的若干光源下,对任一图像输入,从给定的光源序列中,选择一个最可能产生出适当颜色的光源,作为自动白平衡的结果。即自动白平衡问题的数学本质是统计推断的求解问题,求解出最可能的光源,以此作为光源白点施以白平衡增益。这一指导思想与当今流行的主要自动白平衡算法的指导思想一致,无论是较早的最大似然估计,贝叶斯估计,以及现在神经网络模型估计的方法,都是通过数据进行统计推断求解的一种。
树莓派是采用贝叶斯估计(Bayesian Estimation),即根据贝叶斯定理而进行概率推断的方法,即:
后验概率 = (似然性*先验概率)/标准化常量
也就是说,后验概率与先验概率和相似度的乘积成正比。
公式为:
换作AWB的语境下,所谓先验数据就是awb的校准(calibration)数据,即在给定的一系列的标准光源下通过实验室采集的方式得到r/g 与b/g坐标下的分布特征,以及色温CCT值。树莓派的文档把Y轴b/g记作b,X轴r/g记作r。
同时对每个光源(即先验数据)赋予一定概率,即先验概率,最简单的一个先验概率的例子就是户外情况的光源,在当前的照度情况下(比如10000lux),高CCT的光源的概率就可以赋予较高的数值,低CCT的光源概率就可以赋予较低数值。
后验概率即新的图像数据的概率,树莓派的ISP把输入图像分为16x12 zones,每个zone都会由ISP计算出R,G,B均值,进而计算出zone的R/G,B/G值。
比如图像分辨率如果是1280x768,那么图像会被分为16x12个zone,每个zone内,就有80x64个像素,这80x60个像素会被分为5x4个cell,每个cell包含16x16个像素。
每个cell ISP都会统计出该cell有多少接近饱和的像素和多少接近黑电平的像素,如果过多比例的像素饱和,或者过多比例的像素太黑,都会被认为这个cell的数据不可靠,会被剔除出去。
代码里定义了至少要有80%的非饱和像素的cell才会被采用。
255x90%是判定饱和的threshold。
有了这些前提AWB套用到Bayes理论即如下表达:
I是光源,P(I),即光源的先验概率
P(D)即像素值的先验概率
P(D|I)即在给定光源I下,像素数据D的后验概率
P(I|D)即在给定数据D下,光源I的后验概率
所以AWB的求解即:
求最大的P(I|D),即根据输入图像(统计)数据,求得哪个光源的概率P最大。
P(D),像素的先验概率是个常量,即所有像素(统计)数据,先验概率相等。所以公式即可简化为求max P(D|I)*P(I)
如何定P(I)?就成了一个非常灵活的技巧,比如我们之前说,根据当前的光照强度,来给光源定概率,当然也可以根据其它条件来定。
如何计算P(D|I)?
树莓派的awb采用了色差评估的算法,即如果光源选择正确,那么图像施以这个WB Gain,色差就会更小,由下图可见,原始图像(没有白平衡)图像偏绿,经过正确的WB gain,图像会更neutral。
落到具体实现层面,WB Gain是被加到图像的近灰区块,然后计算色差Δr,Δb。
色差越接近0,则说明光源为正确的概率越高,即P(D|I)更高。
假设Δr,Δb的分布服从二位高斯分布,这样即存在如下的正比关系
在实际计算中,未来加快计算, 不会逐像素求,而且是把每个zone作为一个‘像素’D,那么就可以对所有Zone的色差与P(I)乘积求和
指数运算不方便,转换为log求似然(L)更为方便,求log之后,(认为σr = σb)就可以进一步把运算简化为
L(i)是该光源的先验log likelihood。
树莓派的算法设计还留了一些控制参数,比如切换bayers算法和灰世界算法,隔多少帧(frame_period)做一次AWB,AWB的收敛速度控制(Speed)等等,感兴趣的读者可以自行对照代码进行理解。