图像自动白平衡算法C++实现之全反射理论算法PR(Perfect Reflector Assumption)

全反射理论算法PR(Perfect Reflector Assumption)

1.理论详解

全反射理论PR假设图像上最亮点就是白点,并以此白点为参考进行自动白平衡矫正,最亮点定义为R+G+B的最大值。显然只是用一个点作为标准来进行校验的话显然不足,因此通常是用图像上最亮的一部分点的均值作为参考,对图像进行矫正。本文使用Ratio来进行不同比率的矫正

核心公式

dstB = srcB * Kb = srcB * \frac{MaxVal}{Baver}

dstG = srcG * Kg = srcG * \frac{MaxVal}{Gaver}

dstR = srcR * Kr = srcR * \frac{MaxVal}{Raver}

其中

MaxVal所有像素点中的R+B+G的最大值

Baver为前RgbSum > row * col * Ratio下B通道的像素点的平均值,同理Gaver和Raver

2.基于Opencv的C++实现

#include
#include
using namespace std;
cv::Mat  PerfectReflector(cv::Mat src,float Ratio = 0.1)
{
	int MaxVal = 0;
	int row = src.rows;
	int col = src.cols;
	int Hist[767] = { 0 };
	//计算R+B+G的最大值->MaxVal;
	//并统计每个R+B+G值的个数,放进list中->Hist
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			int tmp = max(src.at(i, j)[0], max(src.at(i, j)[1], src.at(i, j)[2]));
			MaxVal = max(MaxVal, tmp);
			int RgbSum = src.at(i, j)[0] + src.at(i, j)[1] + src.at(i, j)[2];
			Hist[RgbSum] += 1;
		}
	}	
	//其中Hist保存的是R+G+B数值的个数
	//计算前row * col*Ratio的R+B+G数值的总和->RgbSum
	//找出满足RgbSum > row * col * Ratio的个数->Threshold
	//并计算前row * col*Ratio的个数->counter
	int cnt = 0;
	int RgbSum = 0;
	int counter = 0;
	int Threshold = 0;
	for (int i = 766; i >= 0; i--)
	{		
		RgbSum = RgbSum + Hist[i];
		if (RgbSum > row * col * Ratio)
		{
			Threshold = i;
			break;
		}
		counter += Hist[i];
	} 	
	int SumB = 0;
	int SumG = 0;
	int SumR = 0;
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			int sum = src.at(i, j)[0] + src.at(i, j)[1] + src.at(i, j)[2];
			if (sum > Threshold)
			{
				SumB += src.at(i, j)[0];
				SumG += src.at(i, j)[1];
				SumR += src.at(i, j)[2];
			}
		}
	}	
	float Baver = SumB / counter;
	float Gaver = SumG / counter;
	float Raver = SumR / counter;
	//分别计算三个通道的矩阵增益	
	float Kb = float(MaxVal / Baver);
	float Kg = float(MaxVal / Gaver);
	float Kr = float(MaxVal / Raver);
	cv::Mat dst(row, col, CV_8UC3);//建立一个三通道UNIT8的图像矩阵
	for (int i = 0; i < row; i++)
	{
		for (int j = 0; j < col; j++)
		{
			int Bdst = src.at(i, j)[0] * Kb;
			int Gdst = src.at(i, j)[1] * Kg;
			int Rdst = src.at(i, j)[2] * Kr;
			//处理边界0和255
			if (Bdst > 255) Bdst = 255;
			else if (Bdst < 0) Bdst = 0;
			if (Gdst > 255) Gdst = 255;
			else if (Gdst < 0) Gdst = 0;
			if (Rdst > 255) Rdst = 255;
			else if (Rdst < 0) Rdst = 0;
			dst.at(i, j)[0] = Bdst;
			dst.at(i, j)[1] = Gdst;
			dst.at(i, j)[2] = Rdst;
		}
	}
	return dst;
}
int main()
{	
	cv::Mat src= cv::imread("E:\\Py3.6_Proje\\AWB\\img2.jpg");	
	cv::Mat dst = PerfectReflector(src,0.1);
	cv::imshow("dst", dst);	
	cv::imshow("src", src);
	cv::waitKey(0);
	system("pause");	
	return 0;
}
	

3.实验结果

Ratio对处理结果有较大的影响,本程序Ratio =0.1时,效果如下所示。

图像自动白平衡算法C++实现之全反射理论算法PR(Perfect Reflector Assumption)_第1张图片

 

 

你可能感兴趣的:(算法学习)