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

    http://www.cnblogs.com/Imageshop/archive/2013/04/20/3032062.html

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

    一、原始的灰度世界算法

      灰度世界算法(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)计算每个像素的RGB之和,并保存到一临时内存块中。

         (2)按R+G+B值的大小计算出其前10%或其他Ratio的白色参考点的的阈值T。

        (3)遍历图像中的每个点,计算其中R+G+B值大于T的所有点的RGB分量的累积和的平均值。

       (4)对每个点将像素量化到[0,255]之间。

            

                

                

                                    原图                                                  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)计算每个区域的CbCr分量的平均值Mb/Mr

                (3)按下式计算每个区域的CbCr分量的绝对差的累积值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同样适用,则初步判断为白点的数会大量的减少,对于同一个图片,同一个参数两个算法的最终的效果比较如下:

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

              

              

  • 相关阅读:
    c#自动更新+安装程序的制作
    VS2013项目受源代码管理向源代码管理注册此项目时出错
    WinDbg配置和使用基础
    InstallShield Limited Edition for Visual Studio 2013 图文教程(教你如何打包.NET程序)
    PowerDesigner 如何生成数据库更新脚本
    用户故事(User Story)
    Troubleshooting Record and Playback issues in Coded UI Test
    Coded UI
    compare two oracle database schemas
    How to: Use Schema Compare to Compare Different Database Definitions
  • 原文地址:https://www.cnblogs.com/jukan/p/7161007.html
Copyright © 2011-2022 走看看