前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >白平衡初探

白平衡初探

作者头像
FPGA开源工作室
发布2020-07-22 20:04:25
1.1K0
发布2020-07-22 20:04:25
举报
文章被收录于专栏:FPGA开源工作室FPGA开源工作室

1 什么叫白平衡

什么是白平衡呢?白平衡的英文为White Balance,其基本概念是“不管在任何光源下,都能将白色物体还原为白色”,对在特定光源下拍摄时出现的偏色现象,通过加强对应的补色来进行补偿。相机的白平衡设定可以校准色温的偏差,在拍摄时我们可以大胆地调整白平衡来达到想要的画面效果。

白平衡,字面上的理解是白色的平衡。白平衡是描述显示器中红、绿、蓝三基色混合生成后白色精确度的一项指标。白平衡是电视摄像领域一个非常重要的概念,通过它可以解决色彩还原和色调处理的一系列问题。白平衡是随着电子影像再现色彩真实而产生的,在专业摄像领域白平衡应用的较早。家用电子产品(家用摄像机、数码照相机)中也广泛地使用,然而技术的发展使得白平衡调整变得越来越简单容易,但许多使用者还不甚了解白平衡的工作原理,理解上存在诸多误区。它是实现摄像机图像能精确反映被摄物的色彩状况,有手动白平衡和自动白平衡等方式。许多人在使用数码摄像机拍摄的时候都会遇到这样的问题:在日光灯的房间里拍摄的影像会显得发绿,在室内钨丝灯光下拍摄出来的景物就会偏黄,而在日光阴影处拍摄到的照片则莫名其妙地偏蓝,其原因就在于白平衡的设置上。

在我们使用的相机上,都可以设定白平衡,大多数的人都设定成自动白平衡,这个方式简单又方便,大部分情况下也可以满足日常拍摄的需求。相机会分析我们拍摄场景的光线环境,并且尽力还原白色,光的色调是通过色温来实现的,色温会告诉相机这些光是暖色调还是冷色调。在我们使用的相机上,都可以设定白平衡,大多数的人都设定成自动白平衡,这个方式简单又方便,大部分情况下也可以满足日常拍摄的需求。相机会分析我们拍摄场景的光线环境,并且尽力还原白色,光的色调是通过色温来实现的,色温会告诉相机这些光是暖色调还是冷色调。

2 色温是什么?

色温说的是光线的温度,比如暖光或者冷光。色温的测量单位是开尔文,表示为K,也就是我们平常经常再说色温的时候,见到的比如5000k, 4500k这个概念。

1)冷光,色温高,偏蓝

2)暖光,色温低,偏红

现在我们是不是大概明白色温的意思了。色温其实并不难懂,上图当中色温从高到低,颜色也由偏蓝的冷光到偏黄的暖光。

3 常见的色温

有一些常见的场景的色温,我们需要比较熟悉,这样可以帮助我们快速的判断我们的拍摄场景,选择合适的色温。

  • 阴天的下午或阴天:6000-7000K
  • 直接正午的阳光:5200-5500K
  • 白色荧光灯:4000K
  • 白炽灯:2800K
  • 蜡烛:1800K

4 白平衡算法

1)原始的灰度世界算法

灰度世界算法(Gray World)是以灰度世界假设为基础的,该假设认为对于一幅有着大量色彩变化的图像, R、 G、 B 三个分量的平均值趋于同一个灰度K。一般有两种方法来确定该灰度。

(1)直接给定为固定值, 取其各通道最大值的一半,即取为127或128;

(2)令 K = (Raver+Gaver+Baver)/3,其中Raver,Gaver,Baver分别表示红、 绿、 蓝三个通道的平均值。

算法的第二步是分别计算各通道的增益:

Kr=K/Raver;

Kg=K/Gaver;

Kb=K/Baver;

算法第三步为根据Von Kries 对角模型,对于图像中的每个像素R、G、B,计算其结果值:

Rnew = R * Kr;

Gnew = G * Kg;

Bnew = B * Kb;

对于上式,计算中可能会存在溢出(>255,不会出现小于0的)现象,处理方式有两种。

a、 直接将像素设置为255,这可能会造成图像整体偏白。

b、 计算所有Rnew、Gnew、Bnew的最大值,然后利用该最大值将将计算后数据重新线性映射到[0,255]内。实践证明这种方式将会使图像整体偏暗,建议采用第一种方案。

Matlab 实现:

代码语言:javascript
复制
close allclear allclcI=imread('test1.jpg');[H,W,L]=size(I);%得到图像长宽高Rsum = 0;Gsum = 0;Bsum = 0;Rsum = double(Rsum);Gsum = double(Gsum);Bsum = double(Bsum);for i = 1 : H    for j = 1 :W        Rsum = Rsum + double(I(i,j,1));        Gsum = Gsum + double(I(i,j,2));        Bsum = Bsum + double(I(i,j,3));    endendRaver = Rsum / (H*W);Gaver = Gsum / (H*W);Baver = Bsum / (H*W);%K=128;%第一种K取值方法K = (Raver+Gaver+Baver)/3;%第二种方法Rgain = K / Raver;Ggain = K / Gaver;Bgain = K / Baver;Iwb(:,:,1) = I(:,:,1) * Rgain;Iwb(:,:,2) = I(:,:,2) * Ggain;Iwb(:,:,3) = I(:,:,3) * Bgain;imwrite(Iwb,'Result1.jpg');figure(1),subplot(121),imshow(I),title('原始图像');subplot(122),imshow(Iwb),title('自动白平衡图像');

2)完美反射算法

原理:完美全反射理论perfect Reflector假设图像上最亮点就是白点,并以此白点为参考对图像进行自动白平衡,最亮点定义为R+G+B的最大值,具体编码步骤如下:

(1)计算每个像素的R\G\B之和,并保存到一临时内存块中。

(2)按R+G+B值的大小计算出其前10%或其他Ratio的白色参考点的的阈值T。

(3)遍历图像中的每个点,计算其中R+G+B值大于T的所有点的R\G\B分量的累积和的平均值。

(4)对每个点将像素量化到[0,255]之间。

代码语言:javascript
复制
Matlab:%完美反射算法--ABWclose allclear allclcI=imread('test7.jpg');I=im2double(I);R=I(:,:,1);G=I(:,:,2);B=I(:,:,3);%(1)计算每个像素的R\G\B之和,并保存到一临时内存块中。RGBsum=R+G+B;%(2)按R+G+B值的大小计算出其前10%或其他Ratio的白色参考点的的阈值T。sumsort=sort(RGBsum(:)');count=round(size(sumsort,2)*0.9);T=sumsort(count);index=RGBsum>T;KR=max(R(:))/mean(R(index));KG=max(G(:))/mean(G(index));KB=max(B(:))/mean(B(index));R1=R*KR;G1=G*KG;B1=B*KB;out=cat(3,R1,G1,B1);figure(1),subplot(121),imshow(I),title('原始图像');subplot(122),imshow(out),title('完美反射法')

3)动态阈值法

(1). 把图像w*h从RGB空间转换到YCrCb空间。

(2). 选择参考白色点:

a. 把图像分成宽高比为4:3个块(块数可选)。

b. 对每个块,分别计算Cr,Cb的平均值Mr,Mb。

c. 对每个块,根据Mr,Mb,用下面公式分别计算Cr,Cb的方差Dr,Db。

d. 判定每个块的近白区域(near-white region)。

判别表达式为:

设一个“参考白色点”的亮度矩阵RL,大小为w*h。

若符合判别式,则作为“参考白色点”,并把该点(i,j)的亮度(Y分量)值赋给RL(i,j);

若不符合,则该点的RL(i,j)值为0。

(3). 选取参考“参考白色点”中最大的10%的亮度(Y分量)值,并选取其中的最小值Lu_min.

(4). 调整RL,若RL(i,j)<Lu_min, RL(i,j)=0; 否则,RL(i,j)=1;

(5). 分别把R,G,B与RL相乘,得到R2,G2,B2。 分别计算R2,G2,B2的平均值,Rav,Gav,Bav;

(6). 得到调整增益:

Ymax=double(max(max(Y)))/5;

Rgain=Ymax/Rav;

Ggain=Ymax/Gav;

Bgain=Ymax/Bav;

(7). 调整原图像:

Ro= R*Rgain;

Go= G*Ggain;

Bo= B*Bgain;

代码语言:javascript
复制
Matlab:clear all;close all;clc;I=imread('test1.jpg');im1=rgb2ycbcr(I);%将图片的RGB值转换成YCbCr值%Lu=im1(:,:,1);Cb=im1(:,:,2);Cr=im1(:,:,3);[H, W, L]=size(I);tst=zeros(H,W);%计算Cb、Cr的均值Mb、Mr%Mb=mean(mean(Cb));Mr=mean(mean(Cr));%计算Cb、Cr的均方差%Db=sum(sum(Cb-Mb))/(H*W);Dr=sum(sum(Cr-Mr))/(H*W);%根据阀值的要求提取出near-white区域的像素点%cnt=1;    for i=1:H    for j=1:W        b1=Cb(i,j)-(Mb+Db*sign(Mb));        b2=Cr(i,j)-(1.5*Mr+Dr*sign(Mr));        if (b1<abs(1.5*Db) & b2<abs(1.5*Dr))           Ciny(cnt)=Lu(i,j);           tst(i,j)=Lu(i,j);           cnt=cnt+1;        end    endendcnt=cnt-1;iy=sort(Ciny,'descend');%将提取出的像素点从亮度值大的点到小的点依次排列%nn=round(cnt/10);Ciny2(1:nn)=iy(1:nn);%提取出near-white区域中10%的亮度值较大的像素点做参考白点%%提取出参考白点的RGB三信道的值%mn=min(Ciny2);for i=1:H    for j=1:W        if tst(i,j)<mn           tst(i,j)=0;        else           tst(i,j)=1;        end    endendR=I(:,:,1);G=I(:,:,2);B=I(:,:,3);R=double(R).*tst;G=double(G).*tst;B=double(B).*tst;%计算参考白点的RGB的均值%Rav=mean(mean(R));Gav=mean(mean(G));Bav=mean(mean(B));Ymax=double(max(max(Lu)))/15;%计算出图片的亮度的最大值%%计算出RGB三信道的增益%Rgain=Ymax/Rav;Ggain=Ymax/Gav;Bgain=Ymax/Bav;%通过增益调整图片的RGB三信道%im(:,:,1)=I(:,:,1)*Rgain;im(:,:,2)=I(:,:,2)*Ggain;im(:,:,3)=I(:,:,3)*Bgain;%显示图片%figure(1),subplot(121),imshow(I),title('原始图像');subplot(122),imshow(im),title('动态阈值法');
本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-07-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 FPGA开源工作室 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档