今天看大疆招聘岗位时看到了图像算法岗,斗胆看了一眼岗位要求,咱就是说,高低搞过医学图像处理,不要怂就是干。看了眼面经就查到了今天的主题:什么是3A算法?以及自动白平衡方法

参考链接:3A算法——自动白平衡算法

3A算法

3A算法包括:AWB自动白平衡、AE自动曝光、AF自动对焦

自动白平衡

人眼在观察物体的时候,可以根据不同光源的性质调整被观察到的物体颜色。而相机在不同色温的光源下拍摄到的图像会产生偏色。相机的自动白平衡就是通过改变RGB感光电路信号的放大比例,让受环境光影响的图像颜色保持和物体真实的颜色一致。

白平衡的本质是使白色物体在任何光源下都显示白色。

一般的算法通过调节白平衡增益, 使拍摄画面的颜色接近物体真实的颜色, 增益调节的根据是环境光源的色温。

AWB算法的步骤:

  1. 估计环境光色温
    灰度世界算法、完美反射算法、动态阈值算法。
  2. 计算增益并调节
    通过求取图像的平均颜色分量对应的增益,然后, 对整副图的RGB分量进行调整 。

灰度世界算法

灰度世界算法基本原理:对于一幅图像,当有足够的色彩变化时,可认为它的RGB分量均值倾向于“R平均=G平均=B平均”,图像呈现为灰色。

  1. 读取R、G、B分量
  2. 计算各分量均值
  3. 通道均衡化操作,计算各自增益
    算法简单快捷,适用于一般场景,但是当图片颜色比较单一或者单一色块面积较大,处理结果存在偏差
close all
clc,clear
 
% 输入图像(存在颜色偏差的原始图像)
imageInput=imread('test2.JPG');

% 分离各个通道
imageR=imageInput(:,:,1);    
imageG=imageInput(:,:,2);   
imageB=imageInput(:,:,3);
 
% 求RGB分量的均值
R=mean(mean(imageR));       
G=mean(mean(imageG));       
B=mean(mean(imageB));
 
% 计算各分量的增益
RGB=(R+G+B)/3;  
kR=RGB/R;   
kG=RGB/G;               
kB=RGB/B;
 
% 计算各通道变换后的灰度值
imageR=imageR*kR;            
imageG=imageG*kG;           
imageB=imageB*kB;
 
% 合并成三通道图像
imageOutput=cat(3,imageR,imageG,imageB);
 
% 输出图像(自动白平衡校正-灰度世界法)
% figure;imshow(imageInput); title('原始图像');  
% figure;imshow(imageOutput);title('白平衡后图像'); 
figure;imshow([imageInput imageOutput]);

完美反射算法

假设图中最亮点就是白点,以此为白点参考对图像进行自动白平衡,亮点定义为R+G+B的最大值。

  1. 计算每个像素点的R+G+B之和并保存;
  2. 按照值的大小计算出其亮点前10%参考点阈值T;
  3. 计算前10%的点的R、G、B分量的平均值;
  4. 计算分量对应的增益
    完美反射算法比灰度世界算法稍好,但是对亮度最亮区域不是白色的图像效果不佳。
%close all
clc,clear
 
% 输入图像(存在颜色偏差的原始图像)
I=im2double(imread('test2.JPG'));

% 分离各个通道
imageR=I(:,:,1);
imageG=I(:,:,2);
imageB=I(:,:,3);
 
% 计算每个RGB灰度值之和
sumRGB=imageR+imageG+imageB;
 
% 将RGB值的大小进行排序
sumsort=sort(sumRGB(:),'descend'); % 降序排列
count=round(length(sumsort)*0.1);
T=sumsort(count);
 
index=sumRGB>T;
 
KR=max(imageR(:))/mean(imageR(index));
KG=max(imageG(:))/mean(imageG(index));
KB=max(imageB(:))/mean(imageB(index));
 
R1=imageR*KR;
G1=imageG*KG;
B1=imageB*KB;

out=cat(3,R1,G1,B1);

% 输出图像(自动白平衡校正-完美反射法)
figure;imshow([I,out]);

动态阈值算法

动态阈值算法引入YCrBr颜色空间进行评价,其中Y表示亮度,Cr表示RGB输入信号红色部分与RGB信号亮度值之间的差异,Br表示RGB输入信号蓝色部分与RGB信号亮度值之间的差异。
YCrBr与RGB变换,在MATLAB中使用‘rgb2ycbcr’实现。

  1. 将RGB变化到YCrCb颜色空间;
  2. 对图像分区,计算每个区域的Cr、Br均值和绝对偏差;
  3. 偏差大过一定阈值计入白点区域;
  4. 根据白点存在区域计算白点位置;
  5. 计算前10%的白点的亮度均值;
  6. 计算分量对应的增益;
%% 基于阈值的动态白平衡
%close all
clc
clear
 
% 输入图像(存在颜色偏差的原始图像)
I=im2double(imread('test2.jpg'));
ImageOutput = dynamic_awb(I);

figure;imshow([I ImageOutput]);


%% 函数
function [output] = dynamic_awb(im)
[m,n,~] = size(im);
R = im(:,:,1);
G = im(:,:,2);
B = im(:,:,3);

map = rgb2ycbcr(im);
Y = map(:,:,1);
Cb = map(:,:,2);
Cr = map(:,:,3);

% Y = 0.257*R+0.504*G+0.098*B+16/255;
% Cb = -0.148*R-0.291*G+0.439*B+128/255;
% Cr = 0.439*R-0.368*G-0.071*B+128/255;、

% 将image分块4*4块
row = m/4; % row为每分块的行数
col = n/4; % col为列数
%row = 10;
%col = 10;
count = 1;

% 初始化
MCb = 0;
MCr = 0;
DCb = 0;
DCr = 0;
for i=1:row:m
    for j=1:col:n
        %每分块的Cb值
        ICb = Cb(i:1:i+row-1,j:1:j+col-1); 
        ICr = Cr(i:1:i+row-1,j:1:j+col-1);

        MICb = mean(mean(ICb)); % 分块的Cb均值
        MICr = mean(mean(ICr)); % 分块的Cr均值

        Dbt = sum(sum(abs(ICb-MICb)))/(row*col); % 分块的绝对偏差
        Drt = sum(sum(abs(ICr-MICr)))/(row*col); % 
        
        if Dbt>0.01 && Drt>0.01     % 判断该分块的

            MCb(count) = MICb;
            MCr(count) = MICr;
            DCb(count) = Dbt;
            DCr(count) = Drt;

            count = count+1;
        end
        
    end
end
  
MCb = mean(MCb); % 得到分块Mb的均值
MCr = mean(MCr);

DCb = mean(DCb);
DCr = mean(DCr);

% 测试输出 [Cb,Cr]
[MCb-0.5*DCb,2.5*DCb+MCb; 1.5*MCr-0.5*DCr, 2.5*DCr+1.5*MCr]

J = zeros(m,n); % 记录候补白点的位置信息,若(i,j)位置为1,则(i,j)像素是候补白点
  
for i=1:1:m
    for j=1:1:n
        bv = abs(Cb(i,j) - (MCb + DCb*sign(MCb)));
        rv = abs(Cr(i,j) - (1.5*MCr + DCr*sign(MCr)));
        if (bv < 1.5*DCb) && (rv < 1.5*DCr) % 判断是否满足候补条件
            J(i,j) = 1;
        end
    end
end

% 判断成立 意味着无法筛选亮点
if sum(sum(J))==0
    J = ones(m,n);  % 完美反射法
end
candidate = Y.*J;
candidate=sort(candidate(:),'descend'); % 降序
kk=round(sum(sum(J))*0.1);
min_v = candidate(kk);    % 得到前10%的最小值


index = (Y > min_v);  % 得到参考白点的亮度矩阵

Ravg = mean(R(index));
Gavg = mean(G(index));
Bavg = mean(B(index));

Ymax = double(max(max(Y))); % 亮度最大值
 
Rgain = Ymax/Ravg; % 计算增益
Ggain = Ymax/Gavg;
Bgain = Ymax/Bavg;

im(:,:,1) = R*Rgain;
im(:,:,2) = G*Ggain;
im(:,:,3) = B*Bgain;
 
output = im;
end

分割4X4图块

分割40X40图块,效果就要比4X4的好很多

更进一步,现在是基于10%白点的亮度均值做增益,可以根据白点的色温分布做矫正
自动白平衡(AWB)算法---2,色温计算