作者:翟天保Steven
版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处

实现原理

白平衡的意义在于,对在特定光源下拍摄时出现的偏色现象,通过加强对应的补色来进行补偿,使白色物体能还原为白色。

完美反射算法是白平衡各种算法中较常见的一种,比灰度世界算法更优。它假设图像世界中最亮的白点是一个镜面,能完美反射光照;基于白点,将三通道的数值进行适当地调整,以达到白平衡效果;除此之外,还需要统计最亮的一定区间的三通道均值,该均值与该通道最大值的差距决定了该通道调整的力度。

通俗的讲,若图像中绿色分量最大值是255,但是绿色最亮的前百分之10个点的平均值只有80,说明原图的绿色分量整体较低,需要对其加强;若最大值只有100,那么加强的系数就较低,白平衡的效果就不达预期。这就是完美反射算法比较依赖图像中存在白点的原因,白点的三通道灰度值接近【255,255,255】。最下方将用实际图像作进一步说明,以帮助读者理解。

完美反射算法的实现流程如下:

1.计算图像RGB三通道各自的灰度最大值Rmax、Gmax、Bmax。

2.利用三通道数值和,确定图像最亮区间的下限T。

3.计算图像三通道数值和大于T的点的三通道均值Rm、Gm、Bm。

4.计算三通道的补偿系数,即单通道最大值除以单通道亮区平均值。

功能函数代码

// 白平衡-完美反射
cv::Mat WhiteBalcane_PRA(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);// 定义参数int row = src.rows;int col = src.cols;int RGBSum[766] = { 0 };uchar maxR, maxG, maxB;// 计算单通道最大值for (int i = 0; i < row; ++i){uchar *b = Channel[0].ptr<uchar>(i);uchar *g = Channel[1].ptr<uchar>(i);uchar *r = Channel[2].ptr<uchar>(i);for (int j = 0; j < col; ++j){int sum = b[j] + g[j] + r[j];RGBSum[sum]++;maxB = max(maxB, b[j]);maxG = max(maxG, g[j]);maxR = max(maxR, r[j]);}}// 计算最亮区间下限Tint T = 0;int num = 0;int K = static_cast<int>(row * col * 0.1);for (int i = 765; i >= 0; --i){num += RGBSum[i];if (num > K){T = i;break;}}// 计算单通道亮区平均值double Bm = 0.0, Gm = 0.0, Rm = 0.0;int count = 0;for (int i = 0; i < row; ++i){uchar *b = Channel[0].ptr<uchar>(i);uchar *g = Channel[1].ptr<uchar>(i);uchar *r = Channel[2].ptr<uchar>(i);for (int j = 0; j < col; ++j){int sum = b[j] + g[j] + r[j];if (sum > T){Bm += b[j];Gm += g[j];Rm += r[j];count++;}}}Bm /= count;Gm /= count;Rm /= count;// 通道调整Channel[0] *= maxB / Bm;Channel[1] *= maxG / Gm;Channel[2] *= maxR / Rm;// 合并通道cv::merge(Channel, result);return result;
}

C++测试代码

#include <iostream>
#include <opencv.hpp>using namespace std;// 白平衡-完美反射
cv::Mat WhiteBalcane_PRA(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);// 定义参数int row = src.rows;int col = src.cols;int RGBSum[766] = { 0 };uchar maxR, maxG, maxB;// 计算单通道最大值for (int i = 0; i < row; ++i){uchar *b = Channel[0].ptr<uchar>(i);uchar *g = Channel[1].ptr<uchar>(i);uchar *r = Channel[2].ptr<uchar>(i);for (int j = 0; j < col; ++j){int sum = b[j] + g[j] + r[j];RGBSum[sum]++;maxB = max(maxB, b[j]);maxG = max(maxG, g[j]);maxR = max(maxR, r[j]);}}// 计算最亮区间下限Tint T = 0;int num = 0;int K = static_cast<int>(row * col * 0.1);for (int i = 765; i >= 0; --i){num += RGBSum[i];if (num > K){T = i;break;}}// 计算单通道亮区平均值double Bm = 0.0, Gm = 0.0, Rm = 0.0;int count = 0;for (int i = 0; i < row; ++i){uchar *b = Channel[0].ptr<uchar>(i);uchar *g = Channel[1].ptr<uchar>(i);uchar *r = Channel[2].ptr<uchar>(i);for (int j = 0; j < col; ++j){int sum = b[j] + g[j] + r[j];if (sum > T){Bm += b[j];Gm += g[j];Rm += r[j];count++;}}}Bm /= count;Gm /= count;Rm /= count;// 通道调整Channel[0] *= maxB / Bm;Channel[1] *= maxG / Gm;Channel[2] *= maxR / Rm;// 合并通道cv::merge(Channel, result);return result;
}int main()
{// 载入原图cv::Mat src = cv::imread("test21.jpg");// 白平衡-完美反射cv::Mat result = WhiteBalcane_PRA(src);// 显示cv::imshow("src", src);cv::imshow("result", result);cv::waitKey(0);return 0;
}

测试效果

图1 原图

图2 白平衡后图像

如图1所示,是傍晚的一张图像,众所周知,傍晚的色温是较低的,此时采用高于傍晚色温的色温值拍照,就会得到一张暖色系的图片,偏黄;对其进行白平衡,使图片颜色回归真实的环境色温,就得到如图2的效果。

如果你用过灰度世界算法,你会发现完美反射算法的效果更亮些;这是因为蓝通道最大值和蓝通道亮区平均值的差距较大,因而补偿的强度很强;若原图中不存在白色区,那蓝通道的补偿就会较弱,达不到较好的预期,因此该算法所处理的图像中最好有较白的点。

图3 单色原图

图4 单色图白平衡效果

如图3所示,是一张色彩相对一致的图像,整体呈粉色系。灰度世界法将三通道数值进行平均再补偿,就会使三通道的数值趋近一致,进而呈现灰色;而完美反射算法,计算的是三通道各自数值最大值和其亮区平均值的差距,再进行补偿,因此三通道的数值都会适当加强,使光感更强,即图片更亮。

接下来做个有趣的测试,将原本粉色的墙纸设为较纯的绿色。

图5 调色后的图像

图6 白平衡效果图

如图5所示,因为图像中存在色调相冲的两个部分,完美反射算法的优势在这种场景下体现的很明显。因为绿色区域较大,灰度世界算法中单纯的计算均值再平衡,会无脑地将整图的绿色分量降低,红色分量提高,使得结果异常滑稽;而完美反射算法,因为图中有白值,三通道的最大值均在250左右,对绿色分量而言,其最亮区的均值接近于230,而红色分量和蓝色分量而言,其最亮区的均值也接近于200多,因此三通道的平衡结果就是整体提亮,而不是被无脑平均。

灰度世界算法效果图见:

OpenCV-白平衡(灰度世界算法)_翟天保Steven的博客-CSDN博客

如果函数有什么可以改进完善的地方,非常欢迎大家指出,一同进步何乐而不为呢~

如果文章帮助到你了,可以点个赞让我知道,我会很快乐~加油!

OpenCV-白平衡(完美反射算法)相关推荐

  1. JavaCV - 白平衡(完美反射算法)

    一.效果图 如图所示,左侧为原图,右侧是白平衡处理后的图片 二.实现原理 白平衡的意义在于,对在特定光源下拍摄时出现的偏色现象,通过加强对应的补色来进行补偿,使白色物体能还原为白色. 完美反射算法是白 ...

  2. 白平衡之完美反射算法

    一.算法背景   白平衡是图像处理比较常见的一个概念,在采集图像的过程中,相机的感光元件或者镜头会对原始色彩造成影响,而白平衡技术通常可以用来校正这种光线和镜头对颜色影响.所以现在先记录一个白平衡算法 ...

  3. 自动白平衡之完美反射算法原理及C++实现

    自动白平衡之完美反射算法原理及C++实现 原文:https://blog.csdn.net/just_sort/article/details/85982871 算法原理 https://www.cn ...

  4. opencv 白平衡之灰度世界算法

    简述 OpenCV对图像进行处理时,有时图像RGB受光照影响比较严重,转换到HSV等空间也解决不了时,可以用白平衡算法进行修正,使其发黄.发蓝.发红的照片更加趋于自然光下的图像. 白平衡算法有很多种, ...

  5. 白平衡算法简单原理以及灰色世界、完美反射实现

    这篇文章是一次课程作业,发到网上以供参考,由于时间有点紧张导致有些部分不够详尽以及有些方法没有实现,之后如果有机会再进行补充. 作业要求 以下两题任选一道完成,自选合适的测试图象,提交代码.实验结果和 ...

  6. 基于灰度世界、完美反射、动态阈值等图像自动白平衡算法的原理、实现及效果...

    原文:http://www.cnblogs.com/Imageshop/archive/2013/04/20/3032062.html 白平衡是电视摄像领域一个非常重要的概念,通过它可以解决色彩还原和 ...

  7. 基于灰度世界、完美反射、动态阈值等图像自动白平衡算法

    文章目录 一.灰度世界算法 二.完美反射算法 三.动态阈值算法 一.灰度世界算法 C++ 算法: 灰度世界 灰度世界算法(Gray World)是以灰度世界假设为基础的,该假设认为对于一幅有着大量色彩 ...

  8. python opencv白平衡算法

    最近学习白平衡,看了一些方法,把学习过程中的算法记录下来,后续继续学习. 灰度世界.完美反射,动态阈值算法等图像算法,但都没有找到适合所有偏色类型的算法.总结:这些单纯的图像识别算法不太好,还是多看用 ...

  9. 目标跟踪之粒子滤波---Opencv实现粒子滤波算法

    目标跟踪学习笔记_2(particle filter初探1) 目标跟踪学习笔记_3(particle filter初探2) 前面2篇博客已经提到当粒子数增加时会内存报错,后面又仔细查了下程序,是代码方 ...

最新文章

  1. Delphi - 新语法介绍之For In
  2. PHP:使用Zend对源码加密、Zend Guard安装以及Zend Guard Run-time support missing的解决方法
  3. Selenium+Python ---- 免登录、等待、unittest单元测试框架、PO模型
  4. 数组与字符串三(Cocos2d-x 3.x _Array容器)
  5. Windows Azure Storage浏览器
  6. oracle编写备份数据库代码,oracle_oracle数据库创建备份与恢复脚本整理,1:创建用户 复制代码 代码如 - phpStudy...
  7. 限制IIS站点的内存,避免级联影响
  8. Linux 命令快捷键
  9. 北大青鸟:比尔盖茨:我在微软的10大失误
  10. 智慧数字门店管理系统、PAD、门店系统、收银开单、预约服务、会员管理、账单管理、数据统计、商品、库存、美容美体、美甲美睫、医疗美容、美发造型、医疗诊所、中医理疗、宠物服务、美业、经营业务、售卡、交班
  11. 亲密关系沟通-【情感勒索】建立良性沟通
  12. HDU1875 畅通工程再续【Kruskal算法+并查集】
  13. C++ Primer Plus学习(六)——分支语句和逻辑运算符
  14. 1194:移动路线(递推)
  15. MySQL5.7源码在MacOS+Clion上的单步调试
  16. dbt2 mysql_mysql dbt2 benchmark Centos6下安装配置
  17. 58到家数据库30条军规解读
  18. cufflinks 介绍使用
  19. Android TextView 文字两端对齐
  20. 四川省教育考试院计算机准考证打印,四川省教育考试网官网准考证打印

热门文章

  1. 26岁,大学肄业,家里蹲5年,这位失业青年的求救,牵动百万网友的心……
  2. JavaScript函数式编程(一)\(二)\(三)
  3. GameEntity(十一)—— Iplayer
  4. php 接口获得图形验证码,API接口图形验证码生成
  5. Vue v-for :src 循环显示图片
  6. 联想ERP项目实施案例分析(大结局):回到最初再反思IT价值
  7. overflow-wrap详解
  8. SecureCRT 设置背景和字体大小的方法
  9. JavaScript删除数组中某个元素的几种方式
  10. 微信公众平台创建自定义菜单的PHP代码