经典AWB(自动白平衡)算法——灰度世界算法

物体在不一样的光照下,能够呈现一样的颜色,这种特性称为色彩一致性。人类的眼睛有“色彩一致”的能力,它使人能够通过调节光谱响应来适应不同光照条件。

对于白色物体,如果它周围的光线色温较低,那么它看起来就会偏微红色; 相反,如果它周围的光线色温较高,那么它看起来就会偏微蓝色。因此,AWB的作用就是用来处理图像的色彩,使其看起来更加接近自然色。

对于白光,它的RGB三通道值完全一样,都是255,如果我们能够让图像中原本是白色的部分恢复到了真正的白色,即 RGB三通道值完全一样且均为255,那么可以认为图像中其他的颜色也恢复正常了。对于灰色,它的RGB也完全一样,因而我们也可以让图像中的灰色部分恢复到它的正常颜色来恢复整个图像的颜色 。

简单的来说,AWB其实就是一种色彩校正算法,目的就是要让处于不同情景光照下拍摄得到的图像中的物体,呈现出统一的、正常的、符合人眼对物体本身颜色认知的画面。

最简单、也是最经典的AWB算法是灰度世界算法。

灰度世界算法来源于胶片相机,它的基本观念是:对于一副色彩丰富的图像,其RGB三通道的平均灰度值是相等的,也即符合灰度世界理论。

其算法流程也非常简单,可以分为以下几步:
(1)计算图像三通道的均值
经典AWB(自动白平衡)算法——灰度世界算法_第1张图片

(2)判断是否符合灰度世界理论,即三通道均值是否相等
在这里插入图片描述

(3)以绿色通道(G通道)作为主亮度通道,分别计算对于红色通道(R通道)和蓝色通道(B通道)的灰度值增益
经典AWB(自动白平衡)算法——灰度世界算法_第2张图片

(4)利用求得的增益值对R通道和B通道进行修正,一般G通道不进行修正
经典AWB(自动白平衡)算法——灰度世界算法_第3张图片
(5)将修正后的R通道和B通道,结合原先的G通道进行合并,得到经过白平衡处理后的校正图像

至此,就实现了最简单的经典AWB算法——灰度世界算法。但要注意的是,灰度世界理论是建立在图像的色彩丰富、色彩种类繁多的基础上,所以对于这种类型的图像进行处理能够有良好的效果。但如果是对色彩较为单一的图像进行处理,则效果会大打折扣。所以灰度世界算法虽然是最简单的AWB算法,但其缺点也是较为明显的。

下面给出利用OpenCV实现的灰度世界算法的主要代码。

	//分离图像为BGR三通道
	vector<Mat>inputImg_BGR;
	split(inputImg, inputImg_BGR);
	Mat inputImg_B, inputImg_G, inputImg_R;
	inputImg_B = inputImg_BGR[0];
	inputImg_G = inputImg_BGR[1];
	inputImg_R = inputImg_BGR[2];

	//计算三通道均值
	double R_ave, B_ave, G_ave;
	Scalar mean_BGR = mean(inputImg);
	B_ave = mean_BGR[0];
	G_ave = mean_BGR[1];
	R_ave = mean_BGR[2];

	//判断是否符合灰度世界假设
	if (B_ave == G_ave == R_ave)
	{
		cout << "图像已符合灰度世界假设" << endl;
		return 0;
	}

	//计算B、R通道增益
	double gain_B, gain_R;
	gain_B = G_ave / B_ave;
	gain_R = G_ave / R_ave;

	Mat result_B(inputImg.size(), CV_8UC1);
	Mat result_R(inputImg.size(), CV_8UC1);	
	//计算色彩校正后的B、R通道值
	for (int row = 0; row < inputImg.rows; row++)
	{
		for (int col = 0; col < inputImg.cols; col++)
		{
			result_B.at<uchar>(row, col) = saturate_cast<uchar>(gain_B * inputImg_B.at<uchar>(row, col));
			result_R.at<uchar>(row, col) = saturate_cast<uchar>(gain_R * inputImg_R.at<uchar>(row, col));
		}
	}

	//合并校正后的图像
	vector<Mat>result_BGR;
	result_BGR.push_back(result_B);
	result_BGR.push_back(inputImg_G);
	result_BGR.push_back(result_R);
	Mat resultImg;
	merge(result_BGR, resultImg);

	//对比显示
	imshow("input", inputImg);
	imshow("result", resultImg);

下面给出原图与处理后图像的对比效果:

上图中,左边是原图像,可以很明显的看到处于一种暖色调的状态,以至于原本是白色的云也显得偏暖偏黄;而右边的图是经过自动白平衡处理后的结果图像,可以看出白云蓝天回归了正常的色彩,还有建筑也显得更加真实、自然,符合人眼观感。

再看一些对比图像:

参考论文:《基于图像分析的3A算法研究》——杜磊(西安电子科技大学)

你可能感兴趣的:(学习笔记,opencv)