图像指数、对数增强、直方图均衡化

1、图像对数增强

 

    计算公式为:

                     NewPixel=255/log(255)*log(OldPixel)

    考虑到log(0)为负无穷大,对于图像来说这毫无意义,因此修改上述公式为:

                    NewPixel=255/log(256)*log(OldPixel+1);

 

    我们看下上述的公式的原理。根据增强前后的象素值的函数关系式,可得到输入和输出的关系曲线,如下图:

 

 

 

 

     可见,输出始终大于输入,整个画面的亮度增大。

     在photoshop中的曲线界面中调整曲线如上图后的效果于本例一样。

     由于根据上述算式直接编制程序如下:

 

    ******************************************************************************************

    '

    函数名   :  LogCalc

    功能     :  对图像进行对数增强(整体变亮)

    参数     :  Bmp          ------     Bitmap      待处理位图

    '               TimeElapse   ------     Integer     处理所需的时间

    返回值   :  Boolean

    作者     :  laviewpbt

    时间     :  2005-5-20  10:05

    修改者  

    修改时间 :

    '

    ******************************************************************************************

 

 Public Shared Function LogCalc(ByVal Bmp As Bitmap, ByRef TimeElapse As Integer) As Boolean

        TimeElapse = Environment.TickCount

        Dim i, j, Stride, Temp As Integer, k As Single, BmpData() As Byte

        ReadBitmap(Bmp, BmpData)

        k = 255 / Log(256)

        ReadBitmap(Bmp, BmpData)

        Stride = (((Bmp.Width * 24) + 31) / 32) * 4

        For i = 0 To Bmp.Height - 1

            For j = 0 To Bmp.Width - 1

                Temp = i * Stride + j * 3

                BmpData(Temp) = k * Log(BmpData(Temp) + 1)

                BmpData(Temp + 1) = k * Log(BmpData(Temp + 1) + 1)

                BmpData(Temp + 2) = k * Log(BmpData(Temp + 2) + 1)

            Next

        Next

        WriteBitmap(Bmp, BmpData)

        TimeElapse = Environment.TickCount - TimeElapse

        Return True

    End Function

 

上述过程对于1024*768的图片大约需要150ms的时间。仔细分析会发现这个过程大部分的运算开销在log函数的计算中,而log函数中的参数BmpData(Temp) + 1的范围是[1,256],因此如果事先计算出这255个值的对数保存在一数组中,则利用查表法可以极大的提高速度。以下是修改后的代码:

 

    Public Shared Function LogCalc(ByVal Bmp As Bitmap, ByRef TimeElapse As Integer) As Boolean

        TimeElapse = Environment.TickCount

        Dim i, j, Stride, Temp As Integer, k As Single, BmpData() As Byte

        Dim TempLogValue(256) As Single

        For i = 1 To 256  

            TempLogValue(i) = Log(i)

        Next

        ReadBitmap(Bmp, BmpData)

        k = 255 / Log(256)

        Stride = (((Bmp.Width * 24) + 31) / 32) * 4

        For i = 0 To Bmp.Height - 1

            For j = 0 To Bmp.Width - 1

                Temp = i * Stride + j * 3

                BmpData(Temp) = k * TempLogValue(BmpData(Temp) + 1)

                BmpData(Temp + 1) = k * TempLogValue(BmpData(Temp + 1) + 1)

                BmpData(Temp + 2) = k * TempLogValue(BmpData(Temp + 2) + 1)

            Next

        Next

        WriteBitmap(Bmp, BmpData)

        TimeElapse = Environment.TickCount - TimeElapse

        Return True

    End Function

 

 

                                                             对数增强效果图(整体变亮)

 

   上述过程只需40ms左右。

   (2006-6-1更改)  更改如下形式则更快:

 Public Shared Function LogCalc(ByVal Bmp As Bitmap, ByRef TimeElapse As Integer) As Boolean
        TimeElapse = Environment.TickCount
        Dim i, j, Stride, Temp As Integer
        Dim k As Single, TempLogValue(256) As Single
        Dim BmpData() As Byte
        k = 255 / Log(256)
        For i = 0 To 255
            TempLogValue(i) = k * Log(i + 1)
        Next
        ReadBitmap(Bmp, BmpData)
        Stride = (((Bmp.Width * 24) + 31) / 32) * 4
        For i = 0 To Bmp.Height - 1
            For j = 0 To Bmp.Width - 1
                Temp = i * Stride + j * 3
                BmpData(Temp) = TempLogValue(BmpData(Temp))
                BmpData(Temp + 1) = TempLogValue(BmpData(Temp + 1))
                BmpData(Temp + 2) = TempLogValue(BmpData(Temp + 2))
            Next
        Next
        WriteBitmap(Bmp, BmpData)
        TimeElapse = Environment.TickCount - TimeElapse
        Return True
    End Function

 2、图像的指数增强

 

    指数运算的的计算公式为:

 

                       NewPixel=1/255*OldPixel*OldPixel

 

    该关系的输入输出曲线如下图所示:

 

 

 

 

 

      输出始终小于输入,即图像整体变暗。同样,在循环中也要避免大量重复OldPixel*OldPixel计算,因为OldPixel属于[0,255],优化后的代码如下:

 

    ******************************************************************************************

    '

    函数名   :  ExpCalc

    功能     :  对图像进行指数增强(整体变暗)

    参数     :  Bmp          ------     Bitmap      待处理位图

    '               TimeElapse   ------     Integer     处理所需的时间

    返回值   :  Boolean

    作者     :  laviewpbt

    时间     :  2005-5-20  10:10

    修改者  

    修改时间 :

    '

    ******************************************************************************************

 

    Public Shared Function ExpCalc(ByVal bmp As Bitmap, ByRef TimeElapse As Integer) As Boolean

        TimeElapse = Environment.TickCount

        Dim i, j, Stride, Temp As Integer, k As Single

        Dim BmpData() As Byte

        ReadBitmap(bmp, BmpData)

        Dim TempPowerValue(255) As Single

        For i = 0 To 255

            TempPowerValue(i) = i ^ 2

        Next

        k = 1 / 255

        Stride = (((bmp.Width * 24) + 31) / 32) * 4

        For i = 0 To bmp.Height - 1

            For j = 0 To bmp.Width - 1

                Temp = i * Stride + j * 3

                BmpData(Temp) = k * TempPowerValue(BmpData(Temp))

                BmpData(Temp + 1) = k * TempPowerValue(BmpData(Temp + 1))

                BmpData(Temp + 2) = k * TempPowerValue(BmpData(Temp + 2))

            Next

        Next

        WriteBitmap(bmp, BmpData)

        TimeElapse = Environment.TickCount - TimeElapse

        Return True

End Function

 

计算时间大约为40ms.

    (2006-6-1更改)  更改如下形式则更快:


    Public Shared Function ExpCalc(ByVal bmp As Bitmap, ByRef TimeElapse As Integer) As Boolean
        TimeElapse = Environment.TickCount
        Dim i, j, Stride, Temp As Integer
        Dim TempPowerValue(255) As Integer
        Dim k As Single
        Dim BmpData() As Byte
        ReadBitmap(bmp, BmpData)
        k = 1 / 255
        For i = 0 To 255
            TempPowerValue(i) = k * i ^ 2
        Next
        Stride = (((bmp.Width * 24) + 31) / 32) * 4
        For i = 0 To bmp.Height - 1
            For j = 0 To bmp.Width - 1
                Temp = i * Stride + j * 3
                BmpData(Temp) = TempPowerValue(BmpData(Temp))
                BmpData(Temp + 1) = TempPowerValue(BmpData(Temp + 1))
                BmpData(Temp + 2) = TempPowerValue(BmpData(Temp + 2))
            Next
        Next
        WriteBitmap(bmp, BmpData)
        TimeElapse = Environment.TickCount - TimeElapse
        Return True
    End Function

 

  

 

                            指数增强效果(整体便暗)

     上述过程用时40ms左右。

3、直方图均衡化

直方图均衡化处理的中心思想是把原始图像的灰度直方图从比较集中的某个灰度区间变成在全部灰度范围内的均匀分布。这里选用常用的增强函数:累计分布函数(cumulative distribution function,CDF)。

   

   

    ******************************************************************************************

    '

    函数名   :  EqualizeCalc

    功能     :  直方图均衡化

    参数     :  Bmp          ------     Bitmap      待处理位图

    '               TimeElapse   ------     Integer     处理所需的时间

    返回值   :  Boolean

    作者     :  laviewpbt

    时间     :  2005-5-20  12:37

    修改者  

    修改时间 :

    '

    ******************************************************************************************

 

 

    PublicSharedFunction EqualizeCalc(ByVal Bmp As Bitmap, ByRef TimeElapse AsInteger) AsBoolean

        TimeElapse = Environment.TickCount

        Dim i, j, Stride, Temp AsInteger

        Dim BmpData() AsByte

        ReadBitmap(Bmp, BmpData)

        Stride = (((Bmp.Width * 24) + 31) / 32) * 4

        Dim MidValue(2) AsInteger, NumOfPixel AsInteger

        Dim Map(255, 2) AsByte

        Dim Histgram(255, 2) AsInteger

        NumOfPixel = Bmp.Width * Bmp.Height

 

        '********************   得到图像的灰度分布情况   *****************

        For i = 0 To Bmp.Height - 1

            For j = 0 To Bmp.Width - 1

                Temp = i * Stride + j * 3

                Histgram(BmpData(Temp), 0) += 1

                Histgram(BmpData(Temp + 1), 1) += 1

                Histgram(BmpData(Temp + 2), 2) += 1

            Next

        Next

        '***********************    计算灰度映射表   *********************

        For i = 0 To 255

            MidValue(0) = 0 : MidValue(1) = 0 : MidValue(2) = 0

            For j = 0 To i

                MidValue(0) += Histgram(j, 0)

                MidValue(1) += Histgram(j, 1)

                MidValue(2) += Histgram(j, 2)

            Next

            Map(i, 0) = MidValue(0) * 255 / NumOfPixel

            Map(i, 1) = MidValue(1) * 255 / NumOfPixel

            Map(i, 2) = MidValue(2) * 255 / NumOfPixel

        Next

 

        '**************************   更新图像数据   ***********************

        For i = 0 To Bmp.Height - 1

            For j = 0 To Bmp.Width - 1

                Temp = i * Stride + j * 3

                BmpData(Temp) = Map(BmpData(Temp), 0)

                BmpData(Temp + 1) = Map(BmpData(Temp + 1), 1)

                BmpData(Temp + 2) = Map(BmpData(Temp + 2), 2)

            Next

        Next

        WriteBitmap(Bmp, BmpData)

        TimeElapse = Environment.TickCount - TimeElapse

        ReturnTrue

EndFunction

 

                                均衡化效果(用时70ms)

 

    由上图可见,视觉效果并没有得到改善,反而差了,呵呵,这就要看你原始图片的质量了,因为我的图片质量本身是非常好的。还有一点,如果你对一副图片均衡化后在均衡则图像不会有任何变化了,这从其实现原理上可以很清楚的看到。

    要注意的是,均衡化处理后的图象只能是近似均匀分布。均衡化图象的动态范围扩大了,但其本质是扩大了量化间隔,而量化级别反而减少了,因此,原来灰度不同的象素经处理后可能变的相同,形成了一片的相同灰度的区域,各区域之间有明显的边界,从而出现了伪轮廓。如果原始图像对比度本来就很高,如果再均衡化则灰度调和,对比度降低。

                 

 

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值