实现原理
白平衡的意义在于,对在特定光源下拍摄时出现的偏色现象,通过加强对应的补色来进行补偿,使白色物体能还原为白色。
灰度世界算法是白平衡各种算法中最基本的一种。它假设图像世界具备丰富色彩,红蓝绿三通道的灰度值在平均后趋近一致,该值作为“灰色”;若各通道均值偏离“灰色”,则将其进行补偿,使其回归“灰色”,进而实现白平衡的效果。
通俗的讲,若图像中绿色较强,蓝色和红色较弱,则用了灰度世界算法后,绿色会适当减弱,蓝色和红色会适当加强,这样就使原本偏色严重的情况得到了缓解。
灰度世界算法的实现流程如下:
1.计算图像RGB三通道各自的灰度平均值Raver、Gaver、Baver。
2.计算“灰色”:Gray=(Raver+Gaver+Baver)/3。
3.计算三通道的补偿系数,即灰色值除以单通道平均值。
功能函数代码
// 白平衡-灰度世界 cv::Mat WhiteBalcane_Gray(cv::Mat src) { cv::Mat result = src.clone(); if (src.channels() != 3) { cout << "The number of image channels is not 3." << endl; return result; } // 通道分离 vector<cv::Mat> Channel; cv::split(src, Channel); // 计算通道灰度值均值 double Bm = cv::mean(Channel[0])[0]; double Gm = cv::mean(Channel[1])[0]; double Rm = cv::mean(Channel[2])[0]; double Km = (Bm + Gm + Rm) / 3; // 通道灰度值调整 Channel[0] *= Km / Bm; Channel[1] *= Km / Gm; Channel[2] *= Km / Rm; // 合并通道 cv::merge(Channel, result); return result; }
C++测试代码
#include <iostream> #include <opencv.hpp> using namespace std; // 白平衡-灰度世界 cv::Mat WhiteBalcane_Gray(cv::Mat src) { cv::Mat result = src.clone(); if (src.channels() != 3) { cout << "The number of image channels is not 3." << endl; return result; } // 通道分离 vector<cv::Mat> Channel; cv::split(src, Channel); // 计算通道灰度值均值 double Bm = cv::mean(Channel[0])[0]; double Gm = cv::mean(Channel[1])[0]; double Rm = cv::mean(Channel[2])[0]; double Km = (Bm + Gm + Rm) / 3; // 通道灰度值调整 Channel[0] *= Km / Bm; Channel[1] *= Km / Gm; Channel[2] *= Km / Rm; // 合并通道 cv::merge(Channel, result); return result; } int main() { // 载入原图 cv::Mat src = cv::imread("test.jpg"); // 白平衡-灰度世界 cv::Mat result = WhiteBalcane_Gray(src); // 显示 cv::imshow("src", src); cv::imshow("result", result); cv::waitKey(0); return 0; }
测试效果
图1 原图
图2 白平衡后图像
如图1所示,是傍晚的一张图像,众所周知,傍晚的色温是较低的,此时采用高于傍晚色温的色温值拍照,就会得到一张暖色系的图片,偏黄;对其进行白平衡,使图片颜色回归真实的环境色温,就得到如图2的效果。
图3 单色原图
图4 白平衡后图像
如图3所示,是一张色彩相对一致的图像,整体呈粉色系,此时应用灰度世界算法,图像会整体调整,使得颜色趋近于灰色;感兴趣的可以去看看该颜色的色条,三通道的数值在180-220左右,没有过大的差异,平衡后三数值接近于190,因而呈灰色。
接下来做个有趣的测试,将原本粉色的墙纸设为较纯的绿色。
图5 调色后的图像
图6 白平衡后效果
如图5所示,因为图像中存在色调相冲的两个部分,在白平衡后,原本的绿色会调整为深绿色,图像绿色分量降低,其他分量升高,这就导致原本偏粉色的人像区更粉了,这也是该算法的弊端。做该测试也是为了帮助大家更全面深层地理解算法应用场景。
最近乘风破浪3开播了,大家支持下王心凌姐姐吧~
如果函数有什么可以改进完善的地方,非常欢迎大家指出,一同进步何乐而不为呢~
如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!