色温:
讨论白平衡,就要从色温谈起,色温顾名思义就是色彩的温度,它指的是绝对黑体从绝对零度开始持续加热所呈现出来的颜色。温度升高,颜色开始从红、橙、黄、绿、蓝、靛、紫,逐渐变化。这些颜色的差异来自于不同波长光线的比例不同,色温越低,波长较长的光线比例大,红色成分就多。色温越高,波长较短的光线比例大,蓝色的成分就多。
白平衡的目的就是让物体从在不同光源下所呈现出来的颜色,恢复到物体的固有色,以达到减少色偏或者无色偏的效果 若图像中绿色较强,蓝色和红色较弱,则用了灰度世界算法后,绿色会适当减弱,蓝色和红色会适当加强,这样就使原本偏色严重的情况得到了缓解。
该算法的优点是简单快捷,能应用于一般场景的处理,但是当图片颜色比较单一或者单一色块的面积较大时,灰度世界法不成立,处理结果会出现偏差。
基于灰度世界假设为前提 (在一副色彩多样的图像中,最终所有颜色的平均统计值应该是一致的,也就是灰色的。)认为对于一副有大量色彩的场景,R,G,B分量的平均值趋于同一个灰度。算法大致可分为三步:
1.计算三个通道的平均灰度
2.计算三个通道的增益系数
3.原始值乘上增益系数
%%白平衡与色温紧密相关,不同色温光源下图像会呈现不同程度的偏色 %%由于人眼独特的适应性,在不同光照条件下观看物体时不会出现偏色,而就没这么先进了 %%蓝色光色温高,红色光色温低 clc; clear all; close all; tic; imgSrc = imread('E:\picture\03-work\02-imgProc\00-ISP\wb_sardmen-incorrect.jpg'); imgDst = imgSrc; %%第一步,计算三个通道的平均灰度 imgR = imgSrc(:,:,1); imgG = imgSrc(:,:,2); imgB = imgSrc(:,:,3); RAve = mean2(imgR); GAve = mean2(imgG); BAve = mean2(imgB); aveGray = (RAve + GAve + BAve) / 3; %%第二步,计算三个通道的增益系数 RCoef = aveGray / RAve; GCoef = aveGray / GAve; BCoef = aveGray / BAve; %%第三步,使用增益系数来调整原始图像 RCorrection = RCoef * imgR; GCorrection = GCoef * imgG; BCorrection = BCoef * imgB; imgDst(:,:,1) = RCorrection; imgDst(:,:,2) = GCorrection; imgDst(:,:,3) = BCorrection; figure,subplot(1,2,1),imshow(imgSrc),title('original image'); subplot(1,2,2),imshow(imgDst),title('white balanced image'); toc;
全反射理论:一幅图像中亮度最大的点就是白点, 即假设在 YCbCr 空间中Y值最大的点为白色, 以此来校正整幅图像。特点是只考虑色彩最亮的那部分, 跟上面的灰度世界理论正好相反, 在处理色彩偏单调的图像时效果好些, 但面对颜色丰富的图片时, 因为最亮的点不一定是白色的, 可能会出现偏色的情况
完美反射算法基本原理:假设图像中最亮的点就是白点,并以此白点为参考对图像进行自动白平衡,最亮点定义为R+G+B的最大值。
算法步骤:计算每个像素点的R+G+B之和并保存;按照值的大小计算出其前10%或其他比例的白色参考点阈值T;遍历图像计算其中R+G+B值大于T的所有点的R、G、B分量的累积和的平均值;将每个像素量化到[0,255]。
完美反射算法优点是比灰度世界算法稍好,但是依赖比例值的选取,并且对亮度最亮区域不是白色的图像效果不佳。
%% 完美反射法 clear all close all clc % 输入图像(存在颜色偏差的原始图像) I=im2double(imread('Test.jpg')); % 分离各个通道 R=I(:,:,1); G=I(:,:,2); B=I(:,:,3); % 计算每个RGB灰度值之和 sumRGB=R+G+B; % 将RGB值的大小进行排序 sumsort=sort(sumRGB(:)'); count=round(size(sumsort,2)*0.9); T=sumsort(count); index=sumRGB>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;imshow([I out]);