文档章节

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

abcijkxyz
 abcijkxyz
发布于 2016/11/22 16:41
字数 1971
阅读 33
收藏 0

    在限制对比度自适应直方图均衡化算法原理、实现及效果一文中针对全局直方图均衡化的一些缺点,提出了分块的自适应均衡化技术,很好的克服了全局直方图均衡化的一些缺点,对于图像增强也有着显著的作用,我们稍微回顾下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  转载请保留本行信息************************

 

 

本文转载自:http://www.cnblogs.com/Imageshop/p/3395968.html

共有 人打赏支持
abcijkxyz
粉丝 63
博文 6196
码字总数 1876
作品 0
深圳
项目经理
SSE图像算法优化系列二十:一种快速简单而又有效的低照度图像恢复算法。

 又有很久没有动笔了,主要是最近没研究什么东西,而且现在主流的趋势都是研究深度学习去了,但自己没这方面的需求,同时也就很少有动力再去看传统算法,今天一个人在加,还是抽空分享一个简...

Imageshop
08/11
0
0
论文学习:Contrast Limited Adaptive Histogram Equalization

目录 一、背景 1、对比度和直方图均衡HE 2、HE的问题 3、AHE 4、底噪问题 二、CLAHE 1、效果展示 2、算法格式和细节 一、背景 1、对比度和直方图均衡HE “对比度contrast ratio”这一概念,类...

RyanXing
07/28
0
0
Opencv系列-图像增强

Opencv系列-图像增强 图像增强对于图像预处理有很大的帮助,再一次看到这篇文章的时候,有如看到。。。反正不一样的感觉 1. 基于直方图均衡化的图像增强 直方图均衡化是通过图像的灰阶分布,...

googler_offer
01/27
0
0
OCR文字识别软件的图像编辑器功能如何用

日常工作中,有时可能需要对图像进行编辑,可是正常情况下大家都知道图像是不能直接编辑的,需要借助工具。ABBYY FineReader 12 OCR文字识别软件可以实现图像的手动编辑,接下来就具体给大家...

ABBYY
2016/11/23
22
0
深度学习必备---用Keras和直方图均衡化---数据增强

作者:王抒伟 编辑:王抒伟 本文100字3图,阅读约三分钟 算了 爱看多久看多久 在读这技术文章之前,请大家想象一个标准河南口音的娃在读这篇文章,那么你不知不觉,你的嘴角就上扬咯。 俺、遇...

机器学习算法全栈工程师
01/26
0
0

没有更多内容

加载失败,请刷新页面

加载更多

00.编译OpenJDK-8u40的整个过程

前言 历经2天的折腾总算把OpenJDK给编译成功了,要说为啥搞这个,还得从面试说起,最近出去面试经常被问到JVM的相关东西,总感觉自己以前学的太浅薄,所以回来就打算深入学习,目标把《深入理...

凌晨一点
今天
4
0
python: 一些关于元组的碎碎念

初始化元组的时候,尤其是元组里面只有一个元素的时候,会出现一些很蛋疼的情况: def checkContentAndType(obj): print(obj) print(type(obj))if __name__=="__main__": tu...

Oh_really
昨天
6
2
jvm crash分析工具

介绍一款非常好用的jvm crash分析工具,当jvm挂掉时,会产生hs_err_pid.log。里面记录了jvm当时的运行状态以及错误信息,但是内容量比较庞大,不好分析。所以我们要借助工具来帮我们。 Cras...

xpbob
昨天
122
0
Qt编写自定义控件属性设计器

以前做.NET开发中,.NET直接就集成了属性设计器,VS不愧是宇宙第一IDE,你能够想到的都给你封装好了,用起来不要太爽!因为项目需要自从全面转Qt开发已经6年有余,在工业控制领域,有一些应用...

飞扬青云
昨天
4
0
我为什么用GO语言来做区块链?

Go语言现在常常被用来做去中心化系统(decentralised system)。其他类型的公司也都把Go用在产品的核心模块中,并且它在网站开发中也占据了一席之地。 我们在决定做Karachain的时候,考量(b...

HiBlock
昨天
2
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部