基于灰度世界、完美反射、动态阈值等图像自动白平衡算法的原理
一、原始的灰度世界算法
灰度世界算法(Gray World)是以灰度世界假设为基础的,该假设认为对于一幅有着大量色彩变化的图像, R、 G、 B 三个分量的平均值趋于同一个灰度K。一般有两种方法来确定该灰度。
(1)直接给定为固定值, 取其各通道最大值的一半,即取为127或128;
(2)令 K = (Raver+Gaver+Baver)/3,其中Raver,Gaver,Baver分别表示红、 绿、 蓝三个通道的平均值。
算法的第二步是分别计算各通道的增益:
Kr=K/Raver;
Kg=K/Gaver;
Kb=K/Baver;
算法第三步为根据Von Kries 对角模型,对于图像中的每个像素R、G、B,计算其结果值:
Rnew = R * Kr;
Gnew = G * Kg;
Bnew = B * Kb;
对于上式,计算中可能会存在溢出(>255,不会出现小于0的)现象,处理方式有两种。
a、 直接将像素设置为255,这可能会造成图像整体偏白。
b、 计算所有Rnew、Gnew、Bnew的最大值,然后利用该最大值将将计算后数据重新线性映射到[0,255]内。实践证明这种方式将会使图像整体偏暗,建议采用第一种方案。
二、完美反射算法
当初写这个代码的时候的一些参考文献一下子也找不到了,就从已经写好的代码中描述下该算法的过程吧。
原理:完美全反射理论perfect Reflector假设图像上最亮点就是白点,并以此白点为参考对图像进行自动白平衡,最亮点定义为R+G+B的最大值,具体编码步骤如下:
(1)计算每个像素的R\G\B之和,并保存到一临时内存块中。
1
2
3
4
5
6
7
8
9
10
11
12
|
for (Y = 0; Y < Height; Y++)
{
Pointer = bmp.Pointer + Y * Stride;
for (X = 0; X < Width; X++)
{
Sum = ( short )(*(Pointer) + *(Pointer + 1) + *(Pointer + 2)); // R+G+B
HistRGB[Sum]++;
*SumP = ( short )Sum;
Pointer += 3;
SumP++;
}
}
|
(2)按R+G+B值的大小计算出其前10%或其他Ratio的白色参考点的的阈值T。
1
2
3
4
5
6
7
8
9
|
for (Y = 767; Y >= 0; Y--)
{
Sum += HistRGB[Y];
if (Sum > Width * Height * Ratio / 100)
{
Threshold = Y;
break ;
}
}
|
(3)遍历图像中的每个点,计算其中R+G+B值大于T的所有点的R\G\B分量的累积和的平均值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
|
for (Y = 0; Y < Height; Y++)
{
Pointer = bmp.Pointer + Y * Stride;
for (X = 0; X < Width; X++)
{
if (*SumP > Threshold)
{
AvgB += *Pointer;
AvgG += *(Pointer + 1);
AvgR += *(Pointer + 2); // 为获得增益做准备
Amount++;
}
Pointer += 3;
SumP++;
}
}
AvgB /= Amount;
AvgG /= Amount;
AvgR /= Amount;
|
(4)对每个点将像素量化到[0,255]之间。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
for (Y = 0; Y < Height; Y++)
{
Pointer = bmp.Pointer + Y * Stride;
for (X = 0; X < Width; X++)
{
Blue = *Pointer * MaxValue / AvgB; // 另外一种算法需要先计算不抑制重新计算的RGB的范围,然后求RGB的最大值,如果最大值大于255,则所有的结果都要除以最大值在乘以255,但实际表明该算法、 不合适;
Green = *(Pointer + 1) * MaxValue / AvgG;
Red = *(Pointer + 2) * MaxValue / AvgR;
if (Red > 255) Red = 255; else if (Red < 0) Red = 0; // 这里需要判断,因为RGB空间所有的颜色转换到YCbCr后,并不是填充满了0-255的范围的,反转过去就会存在一些溢出的点。
if (Green > 255) Green = 255; else if (Green < 0) Green = 0; // 编译后应该比三目运算符的效率高
if (Blue > 255) Blue = 255; else if (Blue < 0) Blue = 0;
*Pointer = ( byte )Blue;
*(Pointer + 1) = ( byte )Green;
*(Pointer + 2) = ( byte )Red;
Pointer += 3;
}
|
三、动态阈值算法
参考论文:A Novel Automatic White Balance Method For Digital Still Cameras
同经典的一些算法相同,算法分为两个步骤:白点检测和白点调整。
白点检测:
(1)为了增强算法的鲁棒性,原文将图像分成12部分,其中宽高比为4:3,关于这一点,我认为不合理,对图像不是通用的,后文再说。
(2)计算每个区域的Cb\Cr分量的平均值Mb/Mr。
(3)按下式计算每个区域的Cb\Cr分量的绝对差的累积值Db/Dr:
上式中N为每个区域的像素数。
(4)如果Db/Dr的值偏小,则我们忽略这一块,因为这表明这一块的颜色分布比较均匀,而这样的局部对于白平衡不好。这个偏小的准则我们稍微再谈。
(5)统计对于除了符合第四条的的其他区域的Mb/Mr/Db/Dr的平均值作为整幅图像的Mb/Mr/Db/Dr值。
关于这一条,原文的话是:The final Mb、Mr、Db、Dr are obtained by taking the average of those regions that pass this additional step。
我在实际中做的时候就是分别对每块进行的,似乎效果也还不错。
(6)按下述规则初步确定哪些点是属于白色参考点:
(7)对于初步判断已经属于白色参考点的像素,按大小取其亮度值为前10%的位最终确定的白色参考点。
白点调整:
(1)计算白色参考点亮度值的平均值Raver,Gaver,Baver,(各通道分开计算)。
(2)按照以下各式计算每个通道的增益:
式中,Ymax就是YCbCr颜色空间中Y分量的在整幅图像中的最大值。
(3)按照以下各式计算最终每个通道的颜色值:
其中R/G/B为在原始的颜色空间中的值,注意这里要进行溢出检测的。
简单的谈下白点检测的分块操作吧,原文把图像分成4*3的12快,这样做事针对于我们很多数码照片是这个比例的,如果通用,我觉得应该用每个块的大小来控制,比如每块为 100*100个像素。
该算法效果非常好;对块大小不太敏感,因此非常适合于自动化操作。
同样,提供个编译好的文件给有兴趣研究该算法的朋友看看效果:
http://files.cnblogs.com/Imageshop/AutoWhiteBalance.zip
********作者: laviewpbt 时间: 2013.4.20 联系QQ: 33184777 转载请保留本行信息*********
基于灰度世界、完美反射、动态阈值等图像自动白平衡算法的原理相关推荐
- 基于灰度世界、完美反射、动态阈值等图像自动白平衡算法的原理、实现及效果...
原文:http://www.cnblogs.com/Imageshop/archive/2013/04/20/3032062.html 白平衡是电视摄像领域一个非常重要的概念,通过它可以解决色彩还原和 ...
- 基于灰度世界、完美反射、动态阈值等图像自动白平衡算法
文章目录 一.灰度世界算法 二.完美反射算法 三.动态阈值算法 一.灰度世界算法 C++ 算法: 灰度世界 灰度世界算法(Gray World)是以灰度世界假设为基础的,该假设认为对于一幅有着大量色彩 ...
- 白平衡算法简单原理以及灰色世界、完美反射实现
这篇文章是一次课程作业,发到网上以供参考,由于时间有点紧张导致有些部分不够详尽以及有些方法没有实现,之后如果有机会再进行补充. 作业要求 以下两题任选一道完成,自选合适的测试图象,提交代码.实验结果和 ...
- python图像分割动态域值_图像处理基本算法 动态阈值分割
在图像处理时,受外界光线的干扰一般比较大,假如在阈值分割时采用固 定阈值,那么在环境改变时分割效果受影响极大,那么为了避免此影响就 必须采用动态阈值,自动求出合适的阈值进行分割. 本文的介绍几种主要的 ...
- grads 相关系数_基于小波变换的多聚焦图像融合算法
引用本文 孟强强, 杨桄, 童涛, 张俭峰. 基于小波变换的多聚焦图像融合算法[J]. 国土资源遥感, 2014,26(2): 38-42 MENG Qiangqiang, YANG Guang, T ...
- 肤色检测算法 - 基于不同颜色空间简单区域划分的皮肤检测算法
基于RGB颜色空间的简单阈值肤色识别 在human skin color clustering for face detection一文中提出如下简单的判别算式: R>95 And G>4 ...
- 图像融合算法(像素级)
图像融合技术可以提取自然光图像和红外图像的互补信息,获得对同一场景描述解释更为准确.全面和可靠的图像.像素级融合是常用于灰度图像与可见光图像的融合.基于源图像的彩色化就是源图像和目标图像的融合过程,使 ...
- 图像处理(十三)保刚性图像变形算法-Siggraph 2004
图像变形可以说是很多图像.动画领域的一个非常常见的功能,就说ps.天天P图.美图秀秀.可牛等这些每个软件,有好多个功能都要用到图像变形,比如图像方向校正.图像全景.视频防抖等,在我的另外一篇博文全景矩 ...
- 图像缩放算法及速度优化
原文来自:博客园 小欣子 图像缩放算法及速度优化--(一)最近邻插值 图像缩放算法及速度优化--(二)双线性插值 --------------------以下为原文------------------ ...
- 基于动态阈值、灰色世界、镜面法的自动白平衡
白平衡是图像处理的一个极重要概念.所谓白平衡(White Balance),就是对白色物体的还原.当我们用肉眼观看这大千世界时,在不同的光线下,对相同的颜色的感觉基本是相同的,比如在早晨旭日初升时,我 ...
最新文章
- 转帖DataTable批量插入数据库
- 圆柱属于能滚动的物体吗_中班科学活动教案:滚动的物体教案(附教学反思)
- 不会c语言能学习python_为什么很多人学不会C语言?学霸说:你要是像我一样学肯定能行!...
- VTK:可视化算法之BluntStreamlines
- 吸烟致癌的迷思是如何破除的?
- BZOJ.4727.[POI2017]Turysta(哈密顿路径/回路 竞赛图)
- 输入URL经历的过程
- QTextEdit 不允许输入文字
- 手机交互应用服务(邮件)
- Unity汉化字段重命名Inspector中字段属性时显示错位及其解决办法——Unity常见问题
- 归并排序java详解
- 自定义图标——阿里图标库
- livereload_LiveReload
- 计算机系统结构总复习
- 如何下载Django 离线文档?
- 关于求两个球相交部分体积计算
- Android TalkingData集成 注意事项
- log4j.properties 使用说明
- iPhoneX 适配
- Pytorch迁移学习加载部分预训练权重