文档章节

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

abcijkxyz
 abcijkxyz
发布于 2016/11/22 16:41
字数 1971
阅读 30
收藏 0
点赞 0
评论 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
粉丝 60
博文 6195
码字总数 1876
作品 0
深圳
项目经理
OCR文字识别软件的图像编辑器功能如何用

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

ABBYY ⋅ 2016/11/23 ⋅ 0

Opencv系列-图像增强

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

googler_offer ⋅ 01/27 ⋅ 0

深度学习必备---用Keras和直方图均衡化---数据增强

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

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

深度学习AI美颜系列---AI滤镜特效算法

滤镜是图像美化中必不可少的步骤, 所谓滤镜,最初是指安装在相机镜头前过滤自然光的附加镜头,用来实现调色和添加效果。我们做的滤镜算法又叫做软件滤镜,是对大部分镜头滤镜进行的模拟,当...

trent1985 ⋅ 05/25 ⋅ 0

15种CSS混合模式让图片产生令人惊艳的效果

如果你曾经广泛地使用过图片编辑应用软件(例如,Adobe Photoshop,Pixelmator,GIMP等),那么你可能对混合模式比较熟悉。如同名称中所暗示的,混合模式是指将上层的图像融入下层图像时采用...

欲思 ⋅ 2014/07/11 ⋅ 1

【数字图像处理】七.MFC图像增强之图像普通平滑、高斯平滑、Laplacian、Sobel、Prewitt锐化详解

本文主要讲述基于VC++6.0 MFC图像处理的应用知识,主要结合自己大三所学课程《数字图像处理》及课件进行讲解,主要通过MFC单文档视图实现显示BMP图像增强处理,包括图像普通平滑、高斯平滑、...

Eastmount ⋅ 2015/06/08 ⋅ 0

MUSICA(多尺度图像对比度增强)算法的简要原理及VC实现-1[r]

MUSICA的专利文档:MUSICApatent - Original document.pdf 算法原理: 图像增强的一般方法是对比度拉伸和直方图均衡,这两种方法对于灰度级过于集中, 还有大量的灰度级没有充分利用的情况下...

技术小美 ⋅ 2017/11/20 ⋅ 0

现代图像处理技术试题

问题1:灰度图像数学形态学 以二值图像数学形态学为切入点,建立灰度图像数学形态学。 1.给出灰度图像的腐蚀、膨胀、开启和闭合等运算的表达式和基本性质; 2.对灰度图像,给出扁平结构元素...

乱世中的单纯 ⋅ 2014/11/26 ⋅ 1

Canny边缘检测算法原理及其VC实现详解(一)

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

hejunbinlan ⋅ 2015/09/08 ⋅ 0

实时图像处理和机器学习库 - cv4j

The target is to set up a high quality and real-time image process and machine learning library which is implemented in pure java. The framework can run application on java desk......

匿名 ⋅ 2017/06/13 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

OSChina 周日乱弹 —— 这么好的姑娘都不要了啊

Osc乱弹歌单(2018)请戳(这里) 【今日歌曲】 @TigaPile :分享曾惜的单曲《讲真的》 《讲真的》- 曾惜 手机党少年们想听歌,请使劲儿戳(这里) @首席搬砖工程师 :怎样约女孩子出来吃饭,...

小小编辑 ⋅ 14分钟前 ⋅ 1

Jenkins实践3 之脚本

#!/bin/sh# export PROJ_PATH=项目路径# export TOMCAT_PATH=tomcat路径killTomcat(){pid=`ps -ef | grep tomcat | grep java|awk '{print $2}'`echo "tom...

晨猫 ⋅ 今天 ⋅ 0

Spring Bean的生命周期

前言 Spring Bean 的生命周期在整个 Spring 中占有很重要的位置,掌握这些可以加深对 Spring 的理解。 首先看下生命周期图: 再谈生命周期之前有一点需要先明确: Spring 只帮我们管理单例模...

素雷 ⋅ 今天 ⋅ 0

zblog2.3版本的asp系统是否可以超越卢松松博客的流量[图]

最近访问zblog官网,发现zlbog-asp2.3版本已经进入测试阶段了,虽然正式版还没有发布,想必也不久了。那么作为aps纵横江湖十多年的今天,blog2.2版本应该已经成熟了,为什么还要发布这个2.3...

原创小博客 ⋅ 今天 ⋅ 0

聊聊spring cloud的HystrixCircuitBreakerConfiguration

序 本文主要研究一下spring cloud的HystrixCircuitBreakerConfiguration HystrixCircuitBreakerConfiguration spring-cloud-netflix-core-2.0.0.RELEASE-sources.jar!/org/springframework/......

go4it ⋅ 今天 ⋅ 0

二分查找

二分查找,也称折半查找、二分搜索,是一种在有序数组中查找某一特定元素的搜索算法。搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束;如果某一特定元素大于...

人觉非常君 ⋅ 今天 ⋅ 0

VS中使用X64汇编

需要注意的是,在X86项目中,可以使用__asm{}来嵌入汇编代码,但是在X64项目中,再也不能使用__asm{}来编写嵌入式汇编程序了,必须使用专门的.asm汇编文件来编写相应的汇编代码,然后在其它地...

simpower ⋅ 今天 ⋅ 0

ThreadPoolExecutor

ThreadPoolExecutor public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, ......

4rnold ⋅ 昨天 ⋅ 0

Java正无穷大、负无穷大以及NaN

问题来源:用Java代码写了一个计算公式,包含除法和对数和取反,在页面上出现了-infinity,不知道这是什么问题,网上找答案才明白意思是负的无穷大。 思考:为什么会出现这种情况呢?这是哪里...

young_chen ⋅ 昨天 ⋅ 0

前台对中文编码,后台解码

前台:encodeURI(sbzt) 后台:String param = URLDecoder.decode(sbzt,"UTF-8");

west_coast ⋅ 昨天 ⋅ 0

没有更多内容

加载失败,请刷新页面

加载更多

下一页

返回顶部
顶部