文档章节

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

abcijkxyz
 abcijkxyz
发布于 2016/11/22 16:41
字数 2332
阅读 84
收藏 0
     白平衡是电视摄像领域一个非常重要的概念,通过它可以解决色彩还原和色调处理的一系列问题。白平衡是随着电子影像再现色彩真实而产生的,在专业摄像领域白平衡应用的较早,现在家用电子产品(家用摄像机、数码照相机)中也广泛地使用,然而技术的发展使得白平衡调整变得越来越简单容易,但许多使用者还不甚了解白平衡的工作原理,理解上存在诸多误区。它是实现摄像机图像能精确反映被摄物的色彩状况,有手动白平衡和自动白平衡等方式,本文简要的介绍了几种自动白平衡算法。

一、原始的灰度世界算法

  灰度世界算法(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之和,并保存到一临时内存块中。

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。

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分量的累积和的平均值。

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]之间。

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;
                }
            }

        

            

            

                                原图                                                  Ratio=10%                                            Ratio=2%

    从效果上看,该算法应该比灰度世界的效果要好些,但是也还是受到Ratio这个参数的影像。特别是第二个图片,过高的Ration导致图片过于泛白。这个问题可以还是最后量化的哪一步引起的,我会抽空再研究一下其他的量化方式,尽量降低Ration的影响。

    针对上述的第二步,看到很多matlab和VC的代码,有很多人居然先用快速排序对累加后的数据进行排序,然后再取其10%的最大值,对图像的数据进行排序,可能就是再快速的排序都快不起来吧,看到这,也许全国人民都笑了。

三、动态阈值算法

      参考论文: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个像素。

          这个算法的效果如下:

          

          

          

                           原图                                              块大小50*50                    块大小100*100

      上三图表明:1、该算法效果非常好;2、对块大小不太敏感,因此非常适合于自动化操作。

       关于RGB到YCbCr的快速转换,可以参考:颜色空间系列3: RGB和YCbCr颜色空间的转换及优化算法 

      由于在上述链接的文章中,YCbCr颜色空间已经被转换到[0,255],因此白色检测部分的第(6)条中的sign函数就不需要了。

      同样,提供个编译好的文件给有兴趣研究该算法的朋友看看效果:

      http://files.cnblogs.com/Imageshop/AutoWhiteBalance.zip

   后记:

     针对动态阈值法,很多朋友反映如果YCbCr的值量化在0到255之间的话会出现所有的像素都会被式(6)初步判断为白色参考点。这样前期的工作就失去了意义,算法就变成了类似于完美反射算法那了,稍微有点不同的地方就是两者选择两点的准则有所不同。虽然这样做的最终结果还算不错,但确实和论文的本意像违背了,后面经过实践,如果把YCbCr的值量化在-127到128之间,式6中的Sgn同样适用,则初步判断为白点的数会大量的减少,对于同一个图片,同一个参数两个算法的最终的效果比较如下:

   更新后的下载链接依旧如下,以增加了修正后的功能。

          

         

 

 

 ***************************作者: laviewpbt   时间: 2013.4.20    联系QQ:  33184777  转载请保留本行信息*************************

 

 

本文转载自:http://www.cnblogs.com/Imageshop/archive/2013/04/20/3032062.html

共有 人打赏支持
abcijkxyz
粉丝 63
博文 6196
码字总数 1876
作品 0
深圳
项目经理
Canny边缘检测算法原理及其VC实现详解(一)

图象的边缘是指图象局部区域亮度变化显著的部分,该区域的灰度剖面一般可以看作是一个阶跃,既从一个灰度值在很小的缓冲区域内急剧变化到另一个灰度相差较大的灰度值。图象的边缘部分集中了图...

hejunbinlan
2015/09/08
265
0
(三)matlab数字图像处理实验-图像灰度变换处理

前两节都是熟悉一下怎么在matlab底下对图片做一些操作,并没有什么卵用,这一节稍微有点卵用,灰度变换一般是图像处理的第一步。 数字图像处理实验1-9点击下列链接有源码和链接: matlab数字...

aninstein
01/06
0
0
手写数字识别系统之图像分割

背景 本文,主要介绍我之前在学校时候,研究的一些跟手写数字识别相关的技术心得,主要涉及:数字图像处理、特征提取、神经网络等等相关的一些技术。。 虽然很多用到的还是网上现有的比较成熟...

ruki
2016/07/30
184
0
机器视觉之人脸识别的流程及主要技术

人脸识别(Face Recognition)是一种依据人的面部特征(如统计或几何特征等),自动进行身份识别的一种生物识别技术,又称为面像识别、人像识别、相貌识别、面孔识别、面部识别等。通常我们所说的...

gunser
05/08
0
0
Qt Quick 图像处理实例之美图秀秀(附源码下载)

在《Qt Quick 之 QML 与 C++ 混合编程详解》一文中我们讲解了 QML 与 C++ 混合编程的方方面面的内容,这次我们通过一个图像处理应用,再来看一下 QML 与 C++ 混合编程的威力,同时也为诸君揭...

foruok
2014/07/16
0
0

没有更多内容

加载失败,请刷新页面

加载更多

React 服务器渲染原理解析与实践

网盘下载地址 React 服务器渲染原理解析与实践 本套课程,讲解了React中SSR技术的整个搭建思路及流程,完整的从原理上讲清楚了SSR的概念,重点在于讲解编写SSR框架遇到的各种知识点,以及细节...

qq__2304636824
7分钟前
0
0
sourcetree 离线免注册登录安装教程

Sourcetree是一个优秀的git可视化管理工具,深受开发者喜爱Sourcetree官网,但是在安装时需要谷歌账户登录,需要翻qiang才可以,此一点一直被人们所诟病。今天本教程就为大家提供离线免登陆安...

QQZZFT
36分钟前
1
0
使用 PostgreSQL 解决一个实际的统计分析问题

使用 PostgreSQL 解决一个实际的统计分析问题作者:老农民(刘启华)Email: 46715422@qq.com 之前有个朋友扔给我一个奇葩需求,他们公司之前做了一批问卷调查,全部都是统一格式的excel...

新疆老农民
39分钟前
5
0
TypeScript基础入门之高级类型的映射类型

转发 TypeScript基础入门之高级类型的映射类型 高级类型 映射类型 一个常见的任务是将一个已知的类型每个属性都变为可选的: interface PersonPartial {    name?: string;    age?...

durban
54分钟前
1
0
Dubbo源码分析(6):Dubbo内核实现之基于SPI思想Dubbo内核实现

SPI接口定义 定义了@SPI注解 package com.alibaba.dubbo.common.extension; import java.lang.annotation.Documented;import java.lang.annotation.ElementType;import java.lang.an......

郑加威
54分钟前
1
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部