局部自适应自动色阶/对比度算法在图像增强上的应用。

    在限制对比度自适应直方图均衡化算法原理、实现及效果一文中针对全局直方图均衡化的一些缺点,提出了分块的自适应均衡化技术,很好的克服了全局直方图均衡化的一些缺点,对于图像增强也有着显著的作用,我们稍微回顾下CLAHE的算法流程,简单的可以用下面的过程描述:

for each Tile in Image 
{
   Calcuate( HistGram);
   ClipHistGram(HistGram, ClipLimit);
   MakeMapping(HistGram);
}
for each Tile in Image 
    for each Pixel in Tile
        use bilinear interpolation between four adjacent HistGram info to generate new Pixel

   原始的直方图均衡化算法的核心在上述 MakeMapping(HistGram)函数中得以体现,

void MakeMapping(int* Histgram)
{
    int I, Sum = 0, Amount = 0;
    for (I = 0; I < 256; I++) Amount += Histgram[I];
    for (I = 0; I < 256; I++)
    {
        Sum += Histgram[I];
        Histgram[I] = Sum * 255/ Amount;     // 计算分布
    }
}

上述Histgram[I] = Sum * 255/ Amount;   一句就是HE算法的核心,就直方图数据重新分布。

    我们回顾一下PS的调整菜单,除了直方图均衡化是一键式菜单(即点击无可调参数界面,实际上直翻图均衡化还是有的,在有选区的情况下回弹出一个框),还有另外三个常用的一键操作,即:自动色阶、自动对比度以及自动颜色。从本质上讲,这三个算法同直方图均衡化一样,在内部也是一个直方图重新分布和像素重新映射的过程,因此,如果把这里的MakeMapping函数总映射过程替换他们三者中的某一种会是什么情况和效果呢, 这其实是了解了CLAHE算法的原理后,很自然的能拓宽和联想到的。

     关于自动色阶和自动对比度的原理,我在调整图像- 自动对比度、自动色阶算法一文中已经有了较为详细的实现,而关于自动颜色的原理,目前为止我似乎没有发现有任何人对其进行了详细的解释。我在Imageshop中也只是做了一种简单的模拟,这里就不提了。

     以自动色阶为例,上述MakeMapping函数的形式可能如下所示:

void MakeMapping(int* Histgram,float CutLimit=0.01)
{
    int I, Sum = 0, Amount = 0;
    const int Level = 256;
    for (I = 0; I < Level; I++) Amount += Histgram[I];
    int MinB,MaxB;
    for (I = 0; I < Level; I++)
    {
        Sum = Sum + Histgram[I];
        if (Sum >= Amount * CutLimit )
        {
            MinB = I;                              
            break;
        }
    }  
    Sum = 0;
    for(I = Level-1; I >= 0; I--)
    {
        Sum = Sum +Histgram[I];
        if (Sum >= Amount * CutLimit )
        {
            MaxB = I ;                            
            break;
        }   
    }
        
    if (MaxB!=MinB)
    {
        for (I = 0; I < Level; I++)
        {
            if (I<MinB)
                Histgram[I] =0;
            else if(I>MaxB)
                Histgram[I]=255;
            else
                Histgram[I] = 255* (I - MinB) / (MaxB - MinB) ;     
        }
    }
    else
    {
        for (I = 0; I < Level; I++) Histgram[I]=MaxB;        //     必须有,不然会有一些图像平坦的部位效果出错
    }
}

  注意在这个函数里我增加了CutLimit参数,这个参数名和CLAHE的一样,实际上是因为自动色阶这种工作方式,就是对直方图的一种裁剪,因此CLAHE算法的ClipHistGram过程就可以舍去了,而把CutLimit作为自动色阶的一个调节参数也是顺其自然的一个事情了。

      在上述代码代码中,if (MaxB!=MinB)的判断主要是防止出现除以0的错误,同时在这种情况发生时,必须把直方图中的所有数据都设置为MaxB(其实这种情况发生时,原始直方图数据中必然是大部分都等于MaxB,但可能还是有部分是不同的,如果不赋值为MaxB,处理的结果图像中会出现莫名其妙的纹理图)。

      把上述代码替换掉CLAHE算法中相应的部分,保持插值等代码不动,可获得如下效果:

          原图

                 块大小为200,CutLimit =0.01 处理后结果

     由上面的图可以看出,处理前后的增强效果还是很明显的,整个图像显得更清晰。

     根据上述代码分析,这样处理的效果肯定是原先图像中的黑的部分更黑,白的部分更白,因此,对比度更加宣明。为了能控制整个对比度调节的程度,我们新增加一个参数,用来调节在最后隐射阶段的最大值。我这里做了如下的处理:

void MakeMapping(int* Histgram,float CutLimit=0.01,float Contrast = 1)
{
    int I, Sum = 0, Amount = 0;
    const int Level = 256;
    for (I = 0; I < Level; I++) Amount += Histgram[I];
    int MinB =0 ,MaxB=255;
    int Min = 0,Max=255;
    for (I = 0; I < Level; I++)
    {
        if  (Histgram[I]!=0) 
        {
            Min = I ;
            break;
        }
    }

    for(I = Level-1; I >= 0; I--)
    {
        if  (Histgram[I]!=0) 
        {
            Max = I ;
            break;
        }
    }
    for (I = 0; I < Level; I++)
    {
        Sum = Sum + Histgram[I];
        if (Sum >= Amount * CutLimit )
        {
            MinB = I;                              
            break;
        }
    }
  
    Sum = 0;
    for(I = Level-1; I >= 0; I--)
    {
        Sum = Sum +Histgram[I];
        if (Sum >= Amount * CutLimit )
        {
            MaxB = I ;                            
            break;
        }   
    }
    int Delta = (Max - Min) * Contrast * 0.5  ;
    Min = Min - Delta;
    Max = Max +    Delta ;
    if (Min    < 0) Min = 0;
    if (Max > 255) Max = 255;

    if (MaxB!=MinB)
    {
        for (I = 0; I < Level; I++)
        {
            if (I<MinB)
                Histgram[I] =Min;
            else if(I>MaxB)
                Histgram[I]=Max;
            else
                Histgram[I] = (Max-Min)* (I - MinB) / (MaxB - MinB) + Min ;     
        }
    }
    else
    {
        for (I = 0; I < Level; I++) Histgram[I]=MaxB;        //     必须有,不然会有一些图像平坦的部位效果出错
    }
}

首先分析获得原始块中的最大值和最小值,然后再这个的基础上按照设定的参数向黑和白两个方向同等程度扩展,这样就避免了无论什么情况下的分布都直接扩展到0-255内。有效的抑制了噪音的放大。

  修改后,我们看看一些效果:

         原图

                    CutLimit =0.01,Contrast=1

                    CutLimit =0.05,Contrast=1

    分析:上面这幅图原始图像整体就比较亮,因此,在Contrast=1的时候,很多块调整后的Min=0,Max也等于255了,因此继续增加Contrast参数,图像的效果基本没有什么变化了。而增加CutLimit值使得图像的映射表由两个极端向中间靠拢,图像会稍微显得浓烈一些。

  原图

                    CutLimit =0.01,Contrast=1

                     CutLimit =0.01,Contrast=2.5    

    而上面这幅图像,则由于整体比较暗,增加Contrast的效果就比较明显了,当Contrast=2.5,图像顶部的一些细节信息也能清晰的表达出来。

    另外,分析原始代码的双线性插值部分可知,在四周边缘处,特备是离边缘小于TileX/2或小于TileY/2的部分,由于其临近信息的缺失,实际上是没有进行双线性插值的,这样对于部分图像,边缘处显得有点不自然,弥补的方式就是在处理前对图像进行扩展,分别向四周扩展TileX/2和TileY/2大小,当然扩展部分的数据需要按照镜像的方式填充数据。

    在贴一些这个算法的处理效果:

   特别是最后一幅图,处理的效果都要比我博客中其他的几种方法来的好,感觉真是帅呆了。

      实际中还发现,如果每个块的大小太小,处理的速度和效果都会有所下降,太大就相当于全局的处理了,因此,一般情况下可取将一副图平均分成约4*4块大小的块大小。同时,调节块大小时还会出现一些点突然过亮或过暗的现象,这个问题可能会影响一部分图的效果。

用C写个DLL,并提供了C#调用的实例:http://files.cnblogs.com/Imageshop/AdaptAutoContrastTest.rar

上图中通道分离选项可以看成是局部自动色阶和自动对比度算法的切换,在勾选通道分离选项时,对于部分图像会发现有偏色的现象,这个现象在PS中使用自动色阶和自动对比度时也会出现。

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

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏大数据挖掘DT机器学习

用Python实现PCA和MDA降维和聚类

降维和聚类算是无监督学习的重要领域,还是那句话,不论是PCA、MDA还是K-means聚类,网上大牛总结的杠杠的,给几个参考链接: http://www....

3548
来自专栏工科狗和生物喵

【机器视觉与图像处理】基于MATLAB+Hough的圆检测

本次文章,没有太多好写的,就是最近做的一个机器视觉的课程设计作业,是要做一个流水线的生产线建模以及对于产品的检测识别,我个人承包了圆心半径检测的内容,熬了好几天...

1001
来自专栏Hadoop数据仓库

HAWQ + MADlib 玩转数据挖掘之(六)——主成分分析与主成分投影

一、主成分分析(Principal Component Analysis,PCA)简介         在数据挖掘中经常会遇到多个变量的问题,而且在多数情况下,...

1746
来自专栏机器学习算法与Python学习

【源码分享】机器学习之Python支持向量机

关键字全网搜索最新排名 【机器学习算法】:排名第一 【机器学习】:排名第一 【Python】:排名第三 【算法】:排名第四 前言 在写代码前,先简单的过一下SV...

37810
来自专栏大数据挖掘DT机器学习

R语言与机器学习(分类算法)决策树算法

决策树定义 首先,我们来谈谈什么是决策树。我们还是以鸢尾花为例子来说明这个问题。 ? 观察上图,我们判决鸢尾花的思考过程可以这么...

3914
来自专栏ml

模式识别---图像二值化

要对图像进行识别,首先要做的将图像从多通道颜色分量变为单通道,也就是gray色调中来,常用的方法有目下三种, 第一种  求rgb颜色风量的平均值:       ...

36912
来自专栏AI研习社

我们分析了最流行的歌词,教你用 RNN 写词编曲(附代码)

翻译 | 余若男 李振 吴章勇 整理 | 凡江 此文展示了基于 RNN 的生成模型在歌词和钢琴音乐上的应用。 介绍 在这篇博文中,我们将在歌词数据...

2804
来自专栏大数据挖掘DT机器学习

R语言中的情感分析与机器学习

利用机器学习可以很方便的做情感分析。本篇文章将介绍在R语言中如何利用机器学习方法来做情感分析。在R语言中,由Timothy P.Jurka开发的情感分析以及更...

3543
来自专栏SeanCheney的专栏

《利用Python进行数据分析·第2版》第13章 Python建模库介绍13.1 pandas与模型代码的接口13.2 用Patsy创建模型描述13.3 statsmodels介绍13.4 sciki

本书中,我已经介绍了Python数据分析的编程基础。因为数据分析师和科学家总是在数据规整和准备上花费大量时间,这本书的重点在于掌握这些功能。 开发模型选用什么库...

6236
来自专栏瓜大三哥

形态学滤波(二) 之Tophat滤波

形态学滤波(二) 之Tophat滤波 Tophat滤波变换实际上是原图像与“开运算”的结果图之差。算法的数学表达式如下: ? 因为开运算带来的结果是放大了裂缝或...

2227

扫码关注云+社区