第一步:白平衡原理概述。
在画面中,寻找不同亮暗的中性色的像素点,这些点应该是满足R=G=B的,但是因为色偏的缘故不相等,于是通过将其影射为相等值获得彩色平衡的作用矩阵,就可进行彩色平衡处理。
1.1、计算输入的具有色偏的原图亮度,即:
1.2、根据计算出的亮度值来寻找图像中的白色点。考虑到实际中,白色的点不一定是理想状态下的白点,因此在这里只是将白色定 义为亮度值为最大的点,即:
1.3、考虑到对环境光照具有一定的适应性,寻找出原图中所有亮度值不小于0.95倍最大亮度值的点。令这些点构成白色点集合,即:
1.4、计算白色点集Ωwhite中所有像素的R,G,B三个颜色分量的均值。
1.5、按照下面的公式计算颜色均衡化的调整参数:
1.6、对整幅图像的R,G,B三个颜色分量,进行彩色平衡调整如下:
总结:白平衡的算法,说白了就是让R、G、B三个值趋于相等。下面用代码实现白平衡算法。
第二步:基于opencv实现白平衡算法(我已经在vs2010上面配置好了opencv的开发环境,如果不会的可以翻我之前的博文)。
2.1、打开vs2010新建一个名字为whiteBalance的工程
选择空工程
在源文件里添加一个名字为main.cpp的文件
2.2、在main.cpp加入以下代码
#include
#include
#include
#include
#include
#include
using namespace cv;
using namespace std;
int main()
{
//1 加载原图
Mat matSrc = imread("./org.png", IMREAD_COLOR);
//2 显示原图
namedWindow("org");
imshow("org", matSrc);
//3 从原图中分离出三个通道
vector
split(matSrc, vMatRGB);
//4 分别求三个通道的平均值
float fAverageR = mean(vMatRGB[2])[0];
float fAverageG = mean(vMatRGB[1])[0];
float fAverageB = mean(vMatRGB[0])[0];
//5 求每个通道的平衡系数
float fKR = (fAverageR + fAverageG + fAverageB) / (3 * fAverageR);
float fKG = (fAverageR + fAverageG + fAverageB) / (3 * fAverageG);
float fKB = (fAverageR + fAverageG + fAverageB) / (3 * fAverageB);
//6 根据平衡系数,调整每个通道的像素值,以便图像达到白平衡
vMatRGB[2] = vMatRGB[2] * fKR;
vMatRGB[1] = vMatRGB[1] * fKG;
vMatRGB[0] = vMatRGB[0] * fKB;
//7 合并调整后的三个通道图,就是白平衡图
Mat matDst(matSrc.rows, matSrc.cols, matSrc.channels());
merge(vMatRGB, matDst);
//8 显示结果图(白平衡图)、
namedWindow("whiteBalance");
imshow("whiteBalance", matDst);
waitKey(0);
return 0;
}
工程源码链接:https://download.csdn.net/download/cwj066/10657615
2.3、运行代码,显示结果如下