自动白平衡算法的比较
这个例子展示了如何估计照明和执行白平衡的场景使用三种不同的照明算法。
在不同的光照条件下,眼睛非常善于判断什么是白色的。然而,数码相机,不需要某种调整,可以很容易地捕捉到不真实的图像和强烈的色彩。自动白平衡(AWB)算法试图用最小的用户输入来校正环境光,这样得到的图像看起来就像我们眼睛看到的那样。
自动白平衡分两步完成:
第一步:估计现场光源。
第二步:调整图像的色彩平衡。
有几种不同的算法来估计场景光源。
每个算法的性能取决于场景、照明和成像条件。此示例通过将三种算法与使用ColorChecker®图表计算的地面真实场景光源进行比较,来判断特定图像的三种算法的质量。
读取和预处理原始相机数据
AWB算法通常应用于经过少量预处理后的原始图像数据,然后将图像压缩并保存到存储卡。
将16位原始图像读入工作区。foosballraw.tiff
是一个图像文件,其中包含校正黑色级别并将强度缩放为每像素16位后的原始传感器数据。该图像没有相机所做的白平衡,以及其他预处理操作,如去噪、去噪、色差补偿、色调调整和伽马校正。
A = imread(“foosballraw.tiff”);
插值恢复丢失的颜色信息
数码相机使用叠加在成像传感器上的彩色滤光片阵列来模拟彩色视觉,因此每个像素都对红色、绿色或蓝色敏感。若要恢复每个像素处缺失的颜色信息,请使用demosaic
函数。拍摄照片的相机(佳能EOS 30D)使用的拜耳模式是RGGB。
A = demosaic(A,“rggb”);
用于检测和显示的伽玛正确图像
图像一个
包含线性RGB值。线性RGB值适用于估计场景光源和校正图像的色彩平衡。然而,如果你试图显示线性RGB图像,它会显得非常暗淡,因为显示设备的非线性特性。因此,为了显示的目的,gamma校正图像到sRGB颜色空间使用lin2rgb
函数。
A_sRGB = lin2rgb(A);
显示伽玛校正前后的消隐图像。
蒙太奇({A_sRGB})标题(伽玛校正前后的原始图像)
使用ColorChecker图表测量地面真相光源
使用场景中包含的ColorChecker图表计算地面真实光源。此图表由24个已知光谱反射率的中性和彩色斑块组成。
方法检测伽玛校正图像中的图表colorChecker
函数。线性RGB图像太暗colorChecker
自动检测图表。
chart_sRGB = colorChecker(A_sRGB);
确认是否正确检测到图表。
displayChart (chart_sRGB)
得到图表四个角的定位点的坐标。
registrationPoints = chart_sRGB.RegistrationPoints;
创建一个新的colorChecker
对象从线性RGB数据。使用配准点的坐标指定图表的位置。
chart = colorChecker(A,RegistrationPoints= RegistrationPoints);
测量线性RGB数据的地真亮度measureIlluminant
函数。
光源(图表)
illuminant_groundtruth =1×3103.× 4.5407 9.3226 6.1812
创建ColorChecker图表的掩码
在测试AWB算法时,通过屏蔽图表来防止算法不公平地利用图表。
控件在图表上创建多边形ROIdrawpolygon
函数。指定多边形的顶点作为配准点。
chartROI = drawpolygon(Position=registrationPoints);
方法将多边形ROI转换为二进制掩码createMask
函数。
mask_chart = createMask(chartROI);
翻转蒙版。图表内的像素被排除在蒙版之外,而场景其余部分的像素被包含在蒙版中。
Mask_scene = ~mask_chart;
若要确认蒙版的准确性,请在图像上显示蒙版。蒙版中包含的像素具有蓝色色调。
imshow (labeloverlay (A_sRGB mask_scene));
角误差
您可以将光源视为3-D RGB颜色空间中的向量。估计光源的大小并不像它的方向那么重要,因为光源的方向是用来白平衡图像的。
为了评估估计光源的质量,计算估计光源与地面真实值之间的角度误差。角误差是两个矢量形成的角度(以度为单位)。角误差越小,估计效果越好。
为了更好地理解角度误差的概念,考虑以下任意光源的可视化和使用ColorChecker图表测量的地面真实值。的plotColorAngle
helper函数在3-D RGB颜色空间中绘制光源的单位向量,并在示例的末尾定义。
Sample_illuminant = [0.066 0.1262 0.0691];p = plot3([0 1],[0 1],[0,1],LineStyle=":"颜色=“k”);ax = p.Parent;持有在plotColorAngle(sample_illuminant,ax) title(“RGB空间中的光源”) view(28,36) legend(“消色差线”,“地面真理照亮者”,“样本光源”网格)在轴平等的
白斑视网膜
用于光源估计的白斑Retinex算法假设场景包含一个明亮的消色差斑。这个补丁反射每个颜色带的最大可能的光,这是场景光源的颜色。使用illumwhite
函数来估计照明使用白斑Retinex算法。
包括所有场景像素
使用场景中的所有像素估计光源。方法从场景中排除ColorChecker图表面具
名称-值对参数。
percentileToExclude = 0;illuminant_wp1 = illumwhite(A,percentileToExclude,Mask=mask_scene);
计算用White Patch Retinex估计的光源的角度误差。
Err_wp1 = colorangle(illuminant_wp1,illuminant_groundtruth);disp (["百分比为0的白色补丁的Angular错误:"num2str (err_wp1)))
White Patch的Angular错误,百分比=0:16.5381
白平衡图像使用chromadapt
函数。指定估计的光源,并指出颜色值在线性RGB颜色空间中。
(A,illuminant_wp1,ColorSpace=“linear-rgb”);
显示伽玛校正白平衡图像。
B_wp1_sRGB = lin2rgb(B_wp1);图imshow(B_wp1_sRGB)“白平衡图像使用白补丁视网膜x与百分位数=0”)
排除最亮的像素
白斑Retinex算法在像素过度曝光时表现不佳。为了提高算法的性能,排除最亮像素的前1%。
percentileToExclude = 1;illuminant_wp2 = illumwhite(A,percentileToExclude,Mask=mask_scene);
计算估计光源的角度误差。误差小于用所有像素估计光源时的误差。
Err_wp2 = colorangle(illuminant_wp2,illuminant_groundtruth);disp ([White Patch的Angular错误,百分位数为1num2str (err_wp2)))
White Patch的角误差,百分比=1:5.0324
利用估计的光源在线性RGB色彩空间中对图像进行白平衡。
B_wp2 = chromadapt(A,illuminant_wp2,ColorSpace=“linear-rgb”);
显示伽玛校正白平衡图像与新的光源。
B_wp2_sRGB = lin2rgb(B_wp2);imshow (B_wp2_sRGB)标题(“白平衡图像使用白补丁Retinex与百分位数=1”)
灰色的世界
用于光源估计的灰色世界算法假设世界的平均颜色是灰色或消色差的。因此,它将场景光源计算为平均图像中的RGB值。使用illumgray
函数来估计照明使用灰色世界算法。
包括所有场景像素
首先,使用图像的所有像素估计场景光源,排除与ColorChecker图表对应的像素。的illumgray
函数提供一个参数来指定要排除的底部和顶部值的百分比(按亮度排序)。在这里,将百分位数指定为0。
percentileToExclude = 0;illuminant_gw1 = illumgray(A,percentileToExclude,Mask=mask_scene);
计算估计光源与真实地面光源之间的角度误差。
Err_gw1 = colorangle(illuminant_gw1,illuminant_groundtruth);disp (["灰色世界的角错误与百分位数=[0 0]:"num2str (err_gw1)))
灰色世界的角误差与百分位=[0 0]:5.0416
利用估计的光源在线性RGB色彩空间中对图像进行白平衡。
(A,illuminant_gw1,ColorSpace=“linear-rgb”);
显示伽玛校正白平衡图像。
B_gw1_sRGB = lin2rgb(B_gw1);imshow (B_gw1_sRGB)标题("白平衡图像使用灰色世界与百分位数=[0 0]")
排除最亮和最暗的像素
灰色世界算法在像素曝光不足或过度曝光时表现不佳。为了提高算法的性能,排除最暗和最亮像素的前1%。
percentileToExclude = 1;illuminant_gw2 = illumgray(A,percentileToExclude,Mask=mask_scene);
计算估计光源的角度误差。误差小于用所有像素估计光源时的误差。
Err_gw2 = colorangle(illuminant_gw2,illuminant_groundtruth);disp ([“灰色世界的角误差与百分位数=[11 1]:”num2str (err_gw2)))
灰色世界的角误差与百分位=[1 1]:5.1094
利用估计的光源在线性RGB色彩空间中对图像进行白平衡。
B_gw2 = chromadapt(A,illuminant_gw2,ColorSpace=“linear-rgb”);
显示伽玛校正白平衡图像与新的光源。
B_gw2_sRGB = lin2rgb(B_gw2);imshow (B_gw2_sRGB)标题("白平衡图像使用灰色世界与百分位数=[11 1]")
程主成分分析(PCA)方法
Cheng的光源估计方法从空间域方法(如灰色边缘)中获得灵感[4],它假设图像的渐变是消色差的。他们表明,灰色边缘可以通过通过变换图像块人为地引入强梯度来改善,并得出结论,最强的梯度跟随光源的方向。他们的方法包括根据它们沿平均图像颜色方向的投影的范数对像素进行排序,并保留底部和顶部百分位数。这两组对应图像中的强梯度。最后,他们表演主成分分析(PCA),并返回第一个分量作为估计的光源。使用illumpca
函数来估计照明使用程的PCA算法。
包括默认的底部和顶部3.5%的像素
首先,使用Cheng的PCA方法的默认百分比值估计光源,排除与ColorChecker图表对应的百分比值。
illuminant_ch2 = illumpca(A,Mask=mask_scene);
计算估计光源与真实地面光源之间的角度误差。
Err_ch2 = colorangle(illuminant_ch2,illuminant_groundtruth);disp ([“Cheng的角误差百分比=3.5:”num2str (err_ch2)))
Cheng的角误差百分比=3.5:5.0162
利用估计的光源在线性RGB色彩空间中对图像进行白平衡。
B_ch2 = chromadapt(A,illuminant_ch2,ColorSpace=“linear-rgb”);
显示伽玛校正白平衡图像。
B_ch2_sRGB = lin2rgb(B_ch2);imshow (B_ch2_sRGB)标题(“使用Cheng的白平衡图像,百分位数=3.5”)
包括底部和顶部5%的像素
现在,沿着平均颜色的方向,使用底部和顶部5%的像素来估计场景光源。的第二个参数illumpca
函数指定要排除的底部和顶部值的百分比(按亮度排序)。
illuminant_ch1 = illumpca(A,5,Mask=mask_scene);
计算估计光源与真实地面光源之间的角度误差。误差小于使用默认百分比估计光源时的误差。
Err_ch1 = colorangle(illuminant_ch1,illuminant_groundtruth);disp ([“Cheng的Angular错误,百分比=5:”num2str (err_ch1)))
Cheng的角误差百分比=5:4.7454
利用估计的光源在线性RGB色彩空间中对图像进行白平衡。
B_ch1 = chromadapt(A,illuminant_ch1,ColorSpace=“linear-rgb”);
显示伽玛校正白平衡图像。
B_ch1_sRGB = lin2rgb(B_ch1);imshow (B_ch1_sRGB)标题(“使用Cheng的白平衡图像,百分比=5”)
找到最优参数
要找到每个算法使用的最佳参数,可以遍历一个范围并计算每个算法的角度误差。这三种算法的参数有不同的含义,但这些参数的范围相似,这使得通过编程很容易为每种算法搜索最佳参数。
Param_range = 0:0.25:5;Err = 0(数值(param_range),3);为K = 1:数值(param_range)%白斑illuminant_wp = illumwhite(A,param_range(k),Mask=mask_scene);Err (k,1) = colorangle(illuminant_wp,illuminant_groundtruth);%灰色世界illuminant_gw = illumgray(A,param_range(k),Mask=mask_scene);Err (k,2) = colorangle(illuminant_gw,illuminant_groundtruth);%程如果(param_range(k) ~= 0) illuminant_ch = illumpca(A,param_range(k),Mask=mask_scene);Err (k,3) = colorangle(illuminant_ch,illuminant_groundtruth);其他的Cheng的算法对于percentage=0没有定义err(k,3) = NaN;结束结束
方法显示角度误差的热图的热图
函数。深蓝色表示低角度误差,黄色表示高角度误差。最优参数的角误差最小。
热图(呃,Title =“角错误”Colormap = parula(长度(param_range)),...XData = [“白色补丁”“灰色的世界”“程的PCA”),...YLabel =“参数值”YData =字符串(param_range));
找出每个算法的最佳参数。
[~,idx_best] = min(err);最佳param_wp = param_range(idx_best(1));Best_param_gw = param_range(idx_best(2));最佳param_ch = param_range(idx_best(3));流(White Patch的最佳参数是%1.2f,角度误差%1.2f度\n,...best_param_wp犯错(idx_best (1), 1));
White Patch的最佳参数为0.25,角误差为3.35度
流(灰色世界的最佳参数是%1.2f,角度误差%1.2f度\n,...best_param_gw犯错(idx_best (2), 2));
灰色世界的最佳参数是0.00,角误差5.04度
流(Cheng的最佳参数为%1.2f,角误差%1.2f度\n,...best_param_ch犯错(idx_best (3), 3));
Cheng的最佳参数为0.50,角误差为1.74度
使用最佳参数计算每种算法的估计光源。
best_illum_wp = illumwhite(A,best_param_wp,Mask=mask_scene);(A,best_param_gw,Mask=mask_scene);best_param_ch = illumpca(A,best_param_ch,Mask=mask_scene);
在RGB颜色空间中显示每个最佳光源的角度误差。
p = plot3([0 1],[0 1],[0,1],LineStyle=":"颜色=“k”);ax = p.Parent;持有在plotColorAngle(illuminant_groundtruth,ax) plotColorAngle(best_illum_wp,ax) plotColorAngle(best_illum_gw,ax) plotColorAngle(best_illum_ch,ax)“RGB空间最佳光源”) view(28,36) legend(“消色差线”,“地面实况”,“白色补丁”,“灰色的世界”,“程”网格)在轴平等的
使用最佳光源计算每种算法的最佳白平衡图像。
B_wp_best = chromadapt(A,best_illum_wp,ColorSpace=“linear-rgb”);B_wp_best_sRGB = lin2rgb(B_wp_best);B_gw_best = chromadapt(A,best_illum_gw,ColorSpace=“linear-rgb”);B_gw_best_sRGB = lin2rgb(B_gw_best);B_ch_best = chromadapt(A,best_illum_ch,ColorSpace=“linear-rgb”);B_ch_best_sRGB = lin2rgb(B_ch_best);
在蒙太奇中显示每种算法的最佳白平衡图像。
图蒙太奇({B_wp_best_sRGB,B_gw_best_sRGB,B_ch_best_sRGB},Size=[1 3]) title(最佳白平衡图像蒙太奇:白点、灰色世界、程)
结论
对比两种经典的光源估计算法和最近的一种算法,Cheng的方法,使用顶部和底部0.75%最暗和最亮的像素,在特定的图像中胜出。然而,对这一结果应该持保留态度。
首先,使用ColorChecker图表测量地面真实光源,并对镜头和传感器噪声敏感。使用分光光度计可以更好地估计场景的真实光源。
其次,将地面真实光源估计为中性斑块的平均颜色。通常使用中位数而不是平均值,这可能会极大地改变基本事实。例如,对于本研究的图像,使用相同的像素,中性斑块的中位数颜色和平均颜色相差0.5度,在某些情况下,这可能超过不同算法估计的光源的角度误差。
第三,充分比较光源估计算法应该使用在不同条件下拍摄的各种图像。对于特定的图像,一种算法可能比其他算法更好,但在整个数据集上可能表现不佳。
金宝app支持函数
的plotColorAngle
函数在三维RGB颜色空间中绘制光源的单位向量。输入参数illum
指定光源为RGB颜色和输入参数斧头
指定要在其上绘制单位向量的轴。
函数plotColorAngle(illum,ax) R = illum(1);G = illum(2);B = illum(3);magRGB = norm(illum);plot3([0 R/magRGB],[0 G/magRGB],[0 B/magRGB],...标志=“。”MarkerSize = 10,父= ax)包含(“R”) ylabel (“G”) zlabel (“B”) xlim([0 1]) ylim([0 1]) zlim([0 1])结束
参考文献
[1]埃伯纳,马克。白斑视网膜,颜色稳定。约翰·威利父子,2007年。ISBN 978-0-470-05829-9。
[2]埃伯纳,马克。灰色世界假设,颜色不变。约翰·威利父子,2007年。ISBN 978-0-470-05829-9。
[3]郑栋梁,迪利普·k·普拉萨德,迈克尔·s·布朗。颜色恒常性的光源估计:为什么空间域方法工作和颜色分布的作用。Josa a 31.5(2014): 1049-1058。
Van De Weijer, Joost, Theo Gevers和Arjan Gijsenij。“基于边缘的颜色稳定性。”IEEE图像处理汇刊16.9(2007):2207-2214。
另请参阅
colorChecker
|measureColor
|illumgray
|illumpca
|illumwhite
|lin2rgb
|rgb2lin
|chromadapt
|colorangle