基于rgb色域直方图重叠面积最大化的自动白平衡算法(附matlab程序)

本文是对论文“Auto White Balance Using the Coincidence of Chromaticity Histograms”中自动白平衡算法的matlab实现。论文思想也很简单,就是颜色直方图反映了色温信息,良好照明(合适色温)下的图像各颜色通道直方图通常具有较大的重叠面积,否则则图像中的颜色直方图的重叠面积通常较小(示例见fig1),于是可以根据颜色直方图重叠面积最大化原则来设计自动白平衡算法。其中,转换到rgb色域是为了消除亮度变化的影响。计算直方图重叠面积时则只计算50~120之间的重叠面积以增强鲁棒性和减少计算量。(先前的程序中有一处错误,现已订正)

fig1 不同色温下图像颜色直方图的重叠情况示例

 废话不多说,还是直接上代码吧。

function cimg=AWBbasedHistOverlap3(img,wid,minGain,maxGain,minGainG,maxGainG,interval)
% 基于rgb空间(对R/G/B归一化)直方图重叠面积最大化的自动白平衡算法
% img为8bit图像
% wid为统计直方图时的区间宽度
% minGain/maxGain分别是R、B通道的最小与最大增益
% minGainG/maxGainG分别是G通道的最小与最大增益
% G通道增益取值一般在0.8~1.2
% minGainG=maxGainG=1意味着不改变G分量,论文中也推荐这样操作
dimg=double(img);
R=dimg(:,:,1);
G=dimg(:,:,2);
B=dimg(:,:,3);
gainNum=floor((maxGain-minGain)/interval)+1;
gainNumG=floor((maxGainG-minGainG)/interval)+1;
overlapNum=zeros(gainNum,gainNum,gainNumG);
countsBox=zeros(floor(256/wid),floor(256/wid),floor(256/wid)); %RGB三维直方图
for i=1:size(img,1)
    for j=1:size(img,2)
        idxR=floor(R(i,j)/wid)+1;
        idxG=floor(G(i,j)/wid)+1;
        idxB=floor(B(i,j)/wid)+1;
        countsBox(idxR,idxG,idxB)=countsBox(idxR,idxG,idxB)+1;
    end
end
for i=1:gainNum
    for j=1:gainNum
        for k=1:gainNumG
            gainR=minGain+interval*(i-1);
            gainG=minGainG+interval*(k-1);
            gainB=minGain+interval*(j-1);
            rc=zeros(1,floor(256/wid)); %r分量在各区间的像素点个数,下同
            gc=zeros(1,floor(256/wid));
            bc=zeros(1,floor(256/wid));
            for m=0:floor(256/wid)-1
                for n=0:floor(256/wid)-1
                    for p=0:floor(256/wid)-1
                        mnpNum=countsBox(m+1,n+1,p+1);
                        midR=min(255,wid*(2*m+1)/2);
                        midG=min(255,wid*(2*n+1)/2);
                        midB=min(255,wid*(2*p+1)/2);
                        gainedSum=gainR*midR+gainG*midG+gainB*midB;
                        r=round(255*gainR*midR/gainedSum);
                        r=min(255,max(r,0));
                        g=round(255*gainG*midG/gainedSum);
                        g=min(255,max(g,0));
                        b=255-r-g;
                        idxR=floor(r/wid)+1;
                        idxG=floor(g/wid)+1;
                        idxB=floor(b/wid)+1;
                        rc(idxR)=rc(idxR)+mnpNum;
                        gc(idxG)=gc(idxG)+mnpNum;
                        bc(idxB)=bc(idxB)+mnpNum;
                    end
                end
            end
            minHist=min([rc;gc;bc]);
            overlapNum(i,j,k)=sum(minHist(floor(50/wid)+1:floor(120/wid)+1)); %只选取r,g,b取值在50~120的部分
        end
    end
end

%对3D/2D重叠数图像滤波,可选操作
f_overlapNum=overlapNum;
r=0;
for i=1:gainNum
    for j=1:gainNum
        for k=1:gainNumG
            ilow=max(1,i-r);
            ihigh=min(gainNum,i+r);
            jlow=max(1,j-r);
            jhigh=min(gainNum,j+r);
            klow=max(1,k-r);
            khigh=min(gainNumG,k+r);
            block=overlapNum(ilow:ihigh,jlow:jhigh,klow:khigh);
            f_overlapNum(i,j,k)=sum(block(:))/((ihigh-ilow+1)*(jhigh-jlow+1)*(khigh-klow+1));
        end
    end
end

maxOverlapIdx=find(f_overlapNum(:)==max(f_overlapNum(:)))-1; %可设置一定阈值选取多个点取平均
gainR=minGain+interval*mod(maxOverlapIdx(1),gainNum);
gainB=minGain+interval*floor(mod(maxOverlapIdx(1),gainNum^2)/gainNum);
gainG=minGainG+interval*floor(maxOverlapIdx(1)/gainNum^2);

%执行映射
cR=gainR*R;
cG=gainG*G;
cB=gainB*B;
cimg=cat(3,cR,cG,cB);
cimg=uint8(cimg);
function [rhist,ghist,bhist]=rgbhist(img)
% 求rgb色域空间各分量的直方图
img=double(img);
sumRGB=sum(img,3);
R=img(:,:,1);
G=img(:,:,2);
B=img(:,:,3);
r=R./(sumRGB+0.001);
g=G./(sumRGB+0.001);
b=1-r-g;
rr=round(255*r);
gg=round(255*g);
bb=255-rr-gg;
rhist=histcounts(rr(:),0:256);
ghist=histcounts(gg(:),0:256);
bhist=histcounts(bb(:),0:256);

 脚本文件:

clear all;close all;clc;
img=imread('3.jpg');
figure,imshow(img);
[rhist,ghist,bhist]=rgbhist(img);
figure,plot(0:255,rhist,'r',0:255,ghist,'g',0:255,bhist,'b');
saveas(gcf,'orgHist.png');
wbimg=AWBbasedHistOverlap(img,8,0.76,1.36,1,1,0.02);
figure,imshow(wbimg);
imwrite(wbimg,'res.jpg');
[rhist,ghist,bhist]=rgbhist(wbimg);
figure,plot(0:255,rhist,'r',0:255,ghist,'g',0:255,bhist,'b');
saveas(gcf,'wbHist.png');

处理结果示例:

fig2 原图1
fig3 处理后图像1

 

fig4 原始颜色直方图1
fig5 处理后颜色直方图1

 

fig6 原始图像2
fig7 处理后图像2

 

fig8 原始颜色直方图2
fig8 处理后颜色直方图2

 

fig10 原始图像3
fig11 处理后图像3

 

fig12 原始颜色直方图3

 

fig 13 原始图像4
fig14 原始图像4

 

fig15 处理后图像4

 

fig16 原始颜色直方图4
fig17 处理后颜色直方图4

 

可以看出,除了最后一张蓝天图像外,该白平衡算法处理得都还不错。最后一张图处理效果不太好,这是由于蓝天占据了过多的比例,白平衡时为了重叠面积最大化给蓝色通道分配了过低的权重,而事实上蓝天图像中本来就应该保留较多的蓝色分量。

另外,本文中所示结果与论文中所给出结果有一定出入,这有几方面原因引起:一是由于本文中进行测试时图像都是从论文PDF中截取的,与原始图像会存在一定出入;二是本文实现中直方图统计采取了更宽的区间以加速运算;三是论文中提到有高斯去噪操作,但没有给出具体的参数,笔者测试中调试了几组高斯滤波参数却发现都无法达到文中效果(主要是最后的蓝天图像);四是作者的算法实现或与笔者实现略有不同。

该算法的主要优点是计算量不随图像尺寸与表观而改变,且对图像中是否存在白色块或灰色块没有要求,整体处理效果不错。缺点是类似蓝天这样的本身某一颜色分量应该比较突出的情况可能处理结果不会太好。

  • 4
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值