本文是isp算法学习的第六篇章,主要是讲述AWB原理和算法。

这个在某种场景下,图中左图的整体画面都发黄,图中右图稍微正常一些。AWB(自动白平衡)校正完成之后就成了右边的图。

1产生原因

右图是一个CIE的色彩空间,其中Tc(K)对应的就是黑体曲线。

人眼具有颜色恒常性,可以避免光源变化带来的颜色变化,但是图像传感器不具备这种特性,从而造成色偏,白平衡就是需要校正这个颜色的偏差;

  • 颜色恒常性:颜色恒常是指在照度发生变化的条件下人们对物体表面颜色的知觉趋于稳定的心理倾向;

  • 色温的定义:色温描述的是具有一定表面温度的“黑体”(blackbody)的辐射光的光谱特性。简单的理解就是颜色随温度的变化规律,比如生铁就是黑色,加热会变成橘红色,继续加热到液态会呈现偏白的颜色,这种随温度而产生的颜色变化就光谱特性。

    黑体

    一个物理学中的理想化的物体,它能够吸收外来的全部电磁辐射,并且不会有任何的反射与透射。黑体对于任何波长的电磁波的吸收系数为1,透射系数为0。物理学家以此作为热辐射研究的标准物体。它能够完全吸收外来的全部电磁辐射,并且不会有任何的反射与透射,这种物体就是绝对黑体,简称黑体。黑体不是黑色的物体,例如太阳可以近似看做是一个黑体。

    这里的黑体不好理解,可以类比成化学中的铁,常温下是黑色,如果对其加热会变红会变黄,最后变成铁水的时候,就变成白色,这种根据温度发生颜色的变化,黑体也是类似变化的。

2校正方法

2.1基本概念

2.1.1颜色空间

颜色空间,这里介绍RGB颜色空间(左图),YUV颜色空间(右图),其中颜色空间的变化矩阵如下所示,而上面的YCbCr是YUV的其中一种表示方式。

其中左图中(0,0,0)到(255,255,255)的线,是一条灰阶线,除了只有黑和白,就是各种比例的灰。

其中右图,两个顶点分别为白色和黑色,这条连线即为灰阶线,跟上述一致。

2.1.2白平衡校正

  • 手动白平衡:在拍照前通过拍摄一个18度灰的卡片,然后计算出当时环境的白平衡的gain值对后面的图片进行校正;

2.1.3校正方法

  • 静态矫正:通常由sensor厂商在生产后进行标定,把所有坏点的坐标位置记录下来,然后矫正的时候直接通过查表得方式找到坏点进行矫正。
  • 自动白平衡:camera通过自己本身的算法,通过获取的图像自动计算出gain值对图像进行校正的方式。

2.2算法

2.2.1灰度世界理论

灰度世界算法基于一个假说:

任一幅图像,当它有足够的色彩变化,则它的RGB分量的均值会趋于相等(R==G==B)。这是一个在自动白平衡方面应用极为广泛的理论。如上图一个颜色足够充足的画面里,假说RGB三个通道的均值是相同的。

对此算法的流程如下:

  • 计算各个颜色通道的平均值;
  • 寻找一个参考值K,一般情况选取Gmean;
  • 计算Rgain = Gmean/Rmean, Bgain = Gmean/Bmean;
  • 对图像中的每个像素都乘以对应的gain值进行校正;

2.2.2完全反射法

完全反射也是基于一个假说:

基于这样一种假设,一幅图像中最亮的像素相当于物体有光泽或镜面上的点,它传达了很多关于场景照明条件的信息。如果景物中有纯白的部分,那么就可以直接从这些像素中提取出光源信息。因为镜面或有光泽的平面本身不吸收光线,所以其反射的颜色即为光源的真实颜色,这是因为镜面或有光泽的平面的反射比函数在很长的一段波长范围内是保持不变的。

完美反射法就是利用用这种特性来对图像进行调整。算法执行时,检测图像中亮度最高的像素并且将它作为参考白点。基于这种思想的方法都被称为是完美反射法,也称镜面法。通俗的意思就是整个图像中最亮的点就是白色或者镜面反射出来的,那么最亮的点就是光源的属性,但是该点本身应该是白点,以此为基础就可计算出gain值从而进行校正。

具体步骤如下,以红色通道为例:

  • 图像相关信息统计 $$ \begin{cases} R_{max} = max(R_{ij}) &&(i=1…N,j=1…M)\
    G_{max} = max(G_{ij}) &&(i=1…N,j=1…M)\
    B_{max} = max(B_{ij}) &&(i=1…N,j=1…M)
    \end{cases} $$

  • RGB通道增益计算 $$ \begin{cases} Gain_{Rmax} = max(R_{max},G_{max},B_{max})/R_{max} \
    Gain_{Gmax} = max(R_{max},G_{max},B_{max})/G_{max} \
    Gain_{Bmax} = max(R_{max},G_{max},B_{max})/B_{max}
    \end{cases} $$

  • 校正(以红色通道为例) $$ R_{max}^{'}= \begin{cases} R*Gain_{Rmax}&&&R*Gain_{Rmax} < 255 \
    255&&&R*Gain_{Rmax} > 255 \end{cases} $$

2.2.3灰度世界和完美反射结合法(QCGP)

就是将灰度世界和完美反射算法进行融合(这里以红色通道为例),具体公式如下 $$ \begin{cases} u_RR_{mean}^2+v_RR_{mean} = K_{mean} &&其中K_{mean}=(R_{mean}+G_{mean}+B_{mean})/3\
u_RR_{max}^2+v_RR_{max} = K_{max}&&其中K_{mean}=(R_{max}+G_{max}+B_{max})/3
\end{cases} $$ 通过上面的方程组就可以解出对应的uR 和vR

那么校准之后,红色像素点的值为,Rorg为校准前原本的值 $$ R_{new}=u_{R} R_{org}^{2}+v_{R} R_{org} $$

2.2.4基于模糊逻辑的算法

如图圆圈表示该颜色本身应该在坐标系中所处的位置,箭头分别表示随色温的变化发生的偏移,这个是通过先验知识得到的,后面再通过这个进行校正。

通过以上两种方式将图像分成8块,然后通过模糊逻辑的方式计算出每个块的一个权重,这个权重和亮度和色度相关,然后通过模糊逻辑方式进行确定。求得权重后就可以计算出整个图像的加权均值。

计算出当前图片亮度下,根据这一块区域分布的像素,通过颜色空间转换,通过计算出每一个块区域的在CrCb坐标系上的位置。每一个块都有一个权重,每一个块乘以自己的权重,就是右图上所在的具体位置。

如图10a,黑点表示八个块的分布,X表示加权后整个图像的位置。然后目的是要让加权的这个值往白点上靠,就通过调整增益的方式调试,调整完增益后,每个块儿的均值又会发生变化,然后又重新计算出每个块的权重,再通过权重计算出整个图像的均值

如图10b,整个图像的均值已经靠近原点了。然后如果X和白点的差距在一个设定的范围内则认为完成白平衡,否则继续调整增益重复上述步骤进行校正。

2.2.5基于白点的算法

将RGB颜色空间转换到YUV空间,转换公式如下: $$ \begin{bmatrix} Y\
U\
V
\end{bmatrix}

\begin{bmatrix} 0.3 & 0.59 & 0.11\
-0.15 & -0.29 & 0.44\
0.51 & -0.52 & -0.095 \end{bmatrix} \begin{bmatrix} R\
G\
B
\end{bmatrix} $$ 通过限定YUV的区域来判断是否为白点,如下论文通过四个限制条件俩限制白点,满足条件的点就是白点,参与后续的计算,否则不是点直接舍弃

通过以上四个限制条件找到白点集合后,就可以对白点集合运用GW(灰度世界理论法)算法或者其他算法计算gain值从而进行后续的校正

2.2.6基于色温的方法

通过在不同色温的环境下拍摄灰卡可以得到上面的两个曲线,一个是gain值的关系曲线,另一个是R/G与色温T的关系,那么如果获取了一张图像知道了拍摄的色温,就可以通过第二张图获取R/G的值,然后将这个值代回图一就能计算出B/G从而获得R和B的gain值;

通过一定的技术手段获取色温即可,一种方法就是通过加一个色温传感器获取环境色温,这个努比亚和oppo都有相关的专利提到,这个不是常规的方式不讲解。另一种就是通过计算求出T,下面的论文就提供了一种方式

该算法通过以下步骤迭代获取色温:

  • 定义Tmin=2000K,Tmax=15000K;
  • 循环结束条件。判断Tmax-Tmin是否大于10,如果小于或等于10,那么可以直接返回T,此时T可以去min,man或者二者的均值,如果满足大于10的条件,则T=(Tmin+Tmax)/2;
  • 求取二分法当前色温对应的RGB值。通过图中一些列的公式,通过T就可以计算出一个R’G’B'。这些公式都是通过实验拟合总结的;
  • 缩小色温二分法边界。对于原始图像可以求出各个通道的均值RGB,如果B'/R'>B/R那么Tmax=T,否则Tmin=T;重复上述步骤即可迭代求出色温T。

2.2.7基于边缘的方法

  1. 先通过一定的手段,比如梯度的方式求出图像中的边缘,然后在边缘各侧各取两个点参与计算;
  2. 通过上述得到的参考点集合,就可以运行灰度世界或者其他的算法求出gain值;

该算法的有点在于,减少的大色块的干扰,因为一般认为边缘就是色块变化的的分界线,那么提取边缘两侧的样本点就可以满足颜色充分的条件,那么就可以运用灰度世界法求出gain.而且有大色块的时候计算的也是也只是选取边缘的几个点,就可以避免大色块分量太大造成白平衡异常的问题。

2.2.8多方法融合法

如图是一款ISP主控的白平衡tuning的图片。这个主要运用的是色温白点算法。

  • 每个蓝色的框就代表一种色温,比如9代表2000K,8代表2500K,这个是通过实验和经验值确定的。

  • 图中绿色的点就是通过白点算法筛选出来的白点候选点。调试的时候就是在不同色温下拍摄灰卡,然后挪动蓝色选框,使其包围绿点

    右上角就是估计色温,调试的时候就是使得这个估计色温和真是色温不要相差太多。

  • 通过标定若干组色温之后就确定了该方案的一个色温曲线

  • 后续再pipeline中通过白点检测算法筛选出白点,然后根据白点的分布,可以找到大多数白点分布的色温,那么该色温就是当前的色温

  • 通过色温再按照前面提到的算法就可以计算出一个gain值,再和灰度世界算法进行一个blending就可以得到最终ISP中使用的gain值。

3方法实现

分别用三种算法校正之后的图片,右上为灰度世界算法,左下为完全反射法,右下为灰度世界和完美反射结合法。

3.1分别使用三种算法

 1% corrected by gw
 2gwImg = gw(img);
 3subplot(222)
 4imshow(gwImg);
 5title('gw');
 6
 7% corrected by pr
 8gwImg = pr(img);
 9subplot(223)
10imshow(gwImg);
11title('pr');
12
13% corrected by qcgp
14gwImg = qcgp(img);
15subplot(224)
16imshow(gwImg);
17title('qcgp');

3.2使用灰度世界算法Gw

 1function correctedImg = gw(img)
 2[height, width, ch] = size(img);
 3r = img(:,:,1);
 4g = img(:,:,2);
 5b = img(:,:,3);
 6
 7% get the mean of three channels
 8rMean = double(mean(mean(r)));
 9gMean = double(mean(mean(g)));
10bMean = double(mean(mean(b)));
11
12% get the rGain and bGain based on gMean to make sure that 
13% the mean of the three channels are the same value after correcting,;
14rGain = gMean / rMean;
15bGain = gMean / bMean;
16
17correctedImg = zeros(height, width, ch);
18correctedImg(:,:,1) = r * rGain;
19correctedImg(:,:,2) = g;
20correctedImg(:,:,3) = b * bGain;
21% make sure there is no overflow
22correctedImg(correctedImg>255) = 255;
23correctedImg = uint8(correctedImg);
24end

3.3使用完全反射法Pr

 1function correctedImg = pr(img) 
 2[height, width, ch] = size(img);
 3r = img(:,:,1);
 4g = img(:,:,2);
 5b = img(:,:,3);
 6
 7rMax = double(max(max(r)));
 8gMax = double(max(max(g)));
 9bMax = double(max(max(b)));
10
11rGain = gMax / rMax;
12bGain = gMax / bMax;
13
14correctedImg = zeros(height, width, ch);
15correctedImg(:,:,1) = r * rGain;
16correctedImg(:,:,2) = g;
17correctedImg(:,:,3) = b * bGain;
18% make sure there is no overflow
19correctedImg(correctedImg>255) = 255;
20correctedImg = uint8(correctedImg);
21
22end

3.4使用灰度世界和完美反射结合法Qcgp

 1function correctedImg = qcgp(img) 
 2I = double(img);
 3[height, width, ch] = size(img);
 4r = I(:,:,1);
 5g = I(:,:,2);
 6b = I(:,:,3);
 7
 8% get the mean and max of three channels
 9rMean = double(mean(mean(r)));
10gMean = double(mean(mean(g)));
11bMean = double(mean(mean(b)));
12
13rMax = double(max(max(r)));
14gMax = double(max(max(g)));
15bMax = double(max(max(b)));
16
17kMean = mean([rMean, gMean, bMean]);
18kMax = mean([rMax, gMax, bMax]);
19
20correctedImg = zeros(height, width, ch);
21
22% calculate the coefficient
23a = [rMean.*rMean, rMean; rMax.*rMax, rMax];
24p = a \ [kMean; kMax];
25correctedImg(:,:,1) = p(1) * (r.*r) + p(2) * r;
26
27a = [gMean.*gMean, gMean; gMax.*gMax, gMax];
28p = a \ [kMean; kMax];
29correctedImg(:,:,2) = p(1) * (g.*g) + p(2) * g;
30
31
32a = [bMean.*bMean, bMean; bMax.*bMax, bMax];
33p = a \ [kMean; kMax];
34correctedImg(:,:,3) = p(1) * (b.*b) + p(2) * b;
35
36% make sure there is no overflow
37correctedImg(correctedImg>255) = 255;
38correctedImg = uint8(correctedImg);
39end