锐化算法的的原理及其实现

     
在开场以前,首先说飞鹤些,Photoshop的USM锐化只是本文所指USM的一种相比新鲜的例证而已。

是因为CSDN博客和天涯论坛的编写制定方面有区别的地点,导致文中部分图片错位,为不影响浏览效果,建议点击打开链接。 

     
通过增强图像的屡屡部分的剧情,图像的视觉效果能够小幅度的拿到改变。为达到规定的标准那个指标,平时能够采取经典USM技术来兑现。这一个技术的流水生产线可用下图来贯彻:

   
 在开场在此之前,首先表明某个,Photoshop的USM锐化只是本文所指USM的一种比较独特的例证而已。

                   
图片 1

     
通过抓实图像的再三部分的故事情节,图像的视觉效果能够小幅度的拿走改观。为完成这几个指标,经常能够利用经典USM技术来贯彻。这几个技能的流程可用下图来落实:

      用现实的公式表明即为:

                    图片 2

                    y(n,m)= x(n,m)+
λz(n,m)                                                      
(1)

      用实际的公式表明即为:

     
在那之中, x(n,m)为输入图像,y(n,m)为出口图像,而z(n,m)为改良信号,一般是经过对x进行MTK滤波获取。λ是用于控制增强功用的的一个缩放因子。

                    y(n,m)= x(n,m)+
λz(n,m)                                                       (1)

     
在观念的USM算法中,z(n,m)一般能够通过下式获取:

     
个中, x(n,m)为输入图像,y(n,m)为出口图像,而z(n,m)为更正信号,一般是由此对x进行MTK滤波获取。λ是用于控制增强作用的的一个缩放因子。

             
z(n,m)=4x(n,m)-x(n-1,m) -x(n +1,m)-x(n, m-1) -x(n,m+1)            
(2)

      在古板的USM算法中,z(n,m)一般能够透过下式获取:

      当然也能够用如下的沙盘:

              z(n,m)=4x(n,m)-x(n-1,m) -x(n +1,m)-x(n,
m-1) -x(n,m+1)             (2)

                     
图片 3

      当然也可以用如下的沙盘:

        贴部分参考代码:

                      图片 4

   Width = Bitmap.Width; Height = Bitmap.Height; Stride = Bitmap.Stride; 
   NewHeight = Height +  2; NewStride = (Width +  2) * BytePerPixel;          
   ExpandPtr = (byte*)Win32Api.GlobalAlloc(Win32Const.GPTR, NewStride * NewHeight);  // 为保证边缘部分处理方便,扩展边界部分
   Utility.GetExpandImage(Bitmap, 1, ExpandPtr);      // 拷贝图像到缓冲区,以及填充边缘像素
   for (Y = 0; Y < Height; Y++)                // 处理灰度图像
   {
       Pointer = Bitmap.Pointer + Y * Stride;
       ExpandP = ExpandPtr + (Y+1) * NewStride+1;
       for (X = 0; X < Width; X++)
       {
           HighPass = (ExpandP[X] << 2) - ExpandP[X - 1] - ExpandP[X + 1] - ExpandP[X - NewStride] - ExpandP[X + NewStride];   // z(n,m)
           Value = Pointer[X] + Amount * HighPass / 100;   // x(n,m)+ λz(n,m),式中的Amount即这里的λ     
           Pointer[X] = (byte)((((ushort)Value | ((short)(255 - Value) >> 15)) & ~Value >> 15));  // 防止数据溢出
        }
    }
    Win32Api.GlobalFree((IntPtr)ExpandPtr);

        贴部分参考代码:

  在不少地方,那几个措施也能获取较好的意义,比如下述的Lena图。

   Width = Bitmap.Width; Height = Bitmap.Height; Stride = Bitmap.Stride; 
   NewHeight = Height +  2; NewStride = (Width +  2) * BytePerPixel;          
   ExpandPtr = (byte*)Win32Api.GlobalAlloc(Win32Const.GPTR, NewStride * NewHeight);  // 为保证边缘部分处理方便,扩展边界部分
   Utility.GetExpandImage(Bitmap, 1, ExpandPtr);      // 拷贝图像到缓冲区,以及填充边缘像素
   for (Y = 0; Y < Height; Y++)                // 处理灰度图像
   {
       Pointer = Bitmap.Pointer + Y * Stride;
       ExpandP = ExpandPtr + (Y+1) * NewStride+1;
       for (X = 0; X < Width; X++)
       {
           HighPass = (ExpandP[X] << 2) - ExpandP[X - 1] - ExpandP[X + 1] - ExpandP[X - NewStride] - ExpandP[X + NewStride];   // z(n,m)
           Value = Pointer[X] + Amount * HighPass / 100;   // x(n,m)+ λz(n,m),式中的Amount即这里的λ     
           Pointer[X] = (byte)((((ushort)Value | ((short)(255 - Value) >> 15)) & ~Value >> 15));  // 防止数据溢出
        }
    }

    Win32Api.GlobalFree((IntPtr)ExpandPtr);

     图片 5 
  图片 6   
图片 7

  在重重地方,那些办法也能得到较好的功用,比如下述的莉娜图,

                   原图
                  Amount=25                                   
Amount=100

    
图片 8     图片 9   图片 10

      可是这些方面也有以下的缺陷: 1)
线性的高通滤波使得效果对噪声十三分灵动,那会造成都部队分不指望的扭转,特别在图像变换相比缓慢的地点的噪声,比如上海图书馆3中草帽的左侧平坦区域。2)对于图像的边缘(高相比较度区域)会冒出拉长过头的现象,如上海教室草帽的边缘。 
那两点会招致出口图像存在部分令人看起来不舒服的地点。
     很多杂谈中提议了有的自适应通过动态的改变式(1)中的λ参数来决定调节结果。在图像的变换比较坦荡的区域,λ取值小,在较大的相比较度(边缘处)地点取适量的λ,而在中比较度处取较大的λ值,以使得那有的的收获最大的滋长。
比如那篇文章Image Enhancement via Adaptive Unsharp
Masking
 中就提出了一种稳步更新的方法。但是类似这样的文章都普遍存在一个标题,那便是可控参数过多,且这么些从参数的取值须要过多的人为参加,我认为那样的算法,是不具有实用的股票总值的。

                   原图
                  Amount=25                                   
Amount=100

    
在Photoshop的锐化菜单中也有一项USM锐化,其实这一个作用也是符合式1的概念的。通过其UI界面大家能够发现其有三个参数:半径、数量、阈值,其内部的算法进程能够用如下的不难代码表示:

      可是那一个地方也有以下的弱项: 1)
线性的德州仪器滤波使得效果对噪音卓殊灵动,那会造成一些不期望的扭转,尤其在图像变换比较缓慢的地点的噪声,比如上海体育场合3中草帽的左侧平坦区域。2)对于图像的边缘(高比较度区域)相会世拉长过头的场所,如上海教室草帽的边缘。 
那两点会招致出口图像存在一些令人看上去不舒服的地点。
     很多舆论中建议了有的自适应通过动态的改变式(1)中的λ参数来决定调节结果。在图像的变换比较坦荡的区域,λ取值小,在较大的相比较度(边缘处)地点取适量的λ,而在中比较度处取较大的λ值,以使得这部分的得到最大的提升。
比如那篇小说Image Enhancement via Adaptive Unsharp
Masking
 中就提议了一种稳步更新的法子。可是类似那样的稿子都普遍存在一个题材,那正是可控参数过多,且那些从参数的取值须求过多的人为参加,笔者以为这么的算法,是不享有实用的股票总市值的。

    Width = Bitmap.Width; Height = Bitmap.Height; Stride = Bitmap.Stride; BytePerPixel = Bitmap.BitCount / 8;
    FastBitmap Clone = Bitmap.Clone();    // 备份图像数据
    BlurEffect.GaussianBlur(Clone, Radius);  // 对备份的数据进行高斯模糊处理
    for (Y = 0; Y < Height; Y++)
    {
        Pointer = Bitmap.Pointer + Y * Stride;
        PointerC = Clone.Pointer + Y * Stride;
        for (X = 0; X < Width; X++)
        {
            Value = Pointer[X] - PointerC[X];
            if (Utility.Abs (Value) > Threshold)
            {
                Value = Pointer[X] + Amount * Value / 100;
                Pointer[X] = (byte)((((ushort)Value | ((short)(255 - Value) >> 15)) & ~Value >> 15));
            }
        }
    }
    Clone.Dispose();

    
在Photoshop的锐化菜单中也有一项USM锐化,其实那个职能也是符合式1的定义的。通过其UI界面大家得以窥见其有一个参数:半径、数量、阈值,其内部的算法进程可以用如下的归纳代码表示:

     
大名鼎鼎,高斯模糊时低通滤波,那么 Value = Pointer[X] –
PointerC[X](原值-低通)则一定于高通的结果,假使原值和低通的异样的相对值超出钦命的阈值,则对改点进行所谓的锐化。

    Width = Bitmap.Width; Height = Bitmap.Height; Stride = Bitmap.Stride; BytePerPixel = Bitmap.BitCount / 8;
    FastBitmap Clone = Bitmap.Clone();    // 备份图像数据
    BlurEffect.GaussianBlur(Clone, Radius);  // 对备份的数据进行高斯模糊处理
    for (Y = 0; Y < Height; Y++)
    {
        Pointer = Bitmap.Pointer + Y * Stride;
        PointerC = Clone.Pointer + Y * Stride;
        for (X = 0; X < Width; X++)
        {
            Value = Pointer[X] - PointerC[X];
            if (Utility.Abs (Value) > Threshold)
            {
                Value = Pointer[X] + Amount * Value / 100;
                Pointer[X] = (byte)((((ushort)Value | ((short)(255 - Value) >> 15)) & ~Value >> 15));
            }
        }
    }
    Clone.Dispose();

     
那里对式(1)多引进了二个参数阈值,通过调节和测试该值,来决定达到何种程度相比较度的像素才必要提升。

      无人不晓,高斯模糊时低通滤波,那么 Value = Pointer[X] –
PointerC[X](原值-低通)则相当于联发科的结果,假诺原值和低通的出入的相对化值大于内定的阈值,则对改点进行所谓的锐化。

      实际的职能申明,那种形式的锐化要比守旧的USM锐化能博取更好的调剂效用。

     
那里对式(1)多引进了3个参数阈值,通过调节和测试该值,来决定达到何种程度相比度的像素才须要升高。

     
以下为Threshold=0,Amount=50时不相同半径的职能。

      实际的效果申明,这种形式的锐化要比古板的USM锐化能获得更好的调剂成效。

 图片 11  图片 12  图片 13  图片 14  

     以下为Threshold=0,Amount=50时不一样半径的机能。

 图片 15  图片 16  图片 17  图片 18

    
 图片 19   图片 20  图片 21 
 图片 22

                    原图                  
                                             Radius=5                  
                          Radius=50                                    
     Radius=200

      图片 23   图片 24  图片 25   图片 26

      随着半径的叠加,图像的对待度慢慢变强,边缘特别显明,不过拥有的调剂后的图像都未现身显明的噪音增强,效果至极之优异,对于Lena图,处理后的图片中能够明显的观望在肉眼部位,眼白和眼球的对待更为清晰、显明,而且整幅图形从感觉上说本来图像较为模糊,处理后的清晰不少。

                         
原图                                             Radius=5                                 
   Radius=50                                           Radius=200

     
Amount参数对职能的震慑很显眼能够识破,越大,比较度越高,然则出于其和结果的线性关系,那么些参数的生成对结果的影响比其余五个参数更敏锐。

      随着半径的附加,图像的比较度日益变强,边缘特别明朗,不过全部的调试后的图像都未出现分明的噪声增强,效果12分之美观。

     
实际上,上述高斯模糊也得以用中值模糊、方框模糊来顶替,所获取的作用和高斯滤波非凡相像。在Paint.net的效应-》相片-》尖锐化滤镜就是用的中值的法子贯彻的。

     
Amount参数对效益的震慑很强烈可以得知,越大,相比度越高,不过出于其和结果的线性关系,这一个参数的转变对结果的影响比别的三个参数更灵敏。

   
关于贯彻代码,基本上自身在地点已经提及,其实最主要依然高斯模糊的完毕。假诺您以为有难度,正如上文所说,也足以用均值来替代,而均值模糊编码则格外不难。 

     
实际上,上述高斯模糊也能够用中值模糊、方框模糊来代替,所取得的效应和高斯滤波相当相像。在Paint.net的效应-》相片-》尖锐化滤镜正是用的中值的情势贯彻的。

 

   
关于实现代码,基本上自身在上头已经提及,其实最重庆大学依然高斯模糊的完结。倘若你觉得有难度,正如上文所说,也能够用均值来替代,而均值模糊编码则非凡不难。 

   
同样,提供个编写翻译好的公文给有趣味商量该算法的恋人看看效果:

    
同样,提供个编写翻译好的文件给有趣味研商该算法的对象看看效果: 

    http://files.cnblogs.com/Imageshop/USM.rar

    http://files.cnblogs.com/Imageshop/USM.rar

 

 

 

 ***************************小编: laviewpbt
  时间: 二〇一二.5.19    联系QQ:  33184777
 转载请保留本行消息*************************