本文会涉及到一些和直方图均衡相关的公式推导以及编程实现,这部分内容在这以下这篇博文中已经详细说明过了:
【图像处理笔记】正方图均衡 http://blog.csdn.net/u013162930/article/details/48087527
直方图均衡化,可以无需参数,自动寻找变换函数,从而自动的的增强整个图像的对比度,简单易行便于实现,结果可预知,但是增强的效果不受控制,处理的结果总是得到全局均衡化的直方图。
而实际上呢,有时候,我们需要变换直方图,使之成为某个特定的形状,从而有选择的增强某个灰度范围内的对比度。这时,就可以采用本文介绍的这种,比较灵活的直方图匹配(直方图规定划)。
现在,我们暂时回到连续灰度r 和z (看成是连续的随机变量)并且Pr(r)和Pz(z)表示它们所对应的连续概率密度函数。在这种表示方法中,r 和z 分别代表输入图像和输出图像的灰度级。我们可以由给定的输入图像估计出Pr(r),而Pz(z)是我们希望输出图像所具有的指定概率密度函数。
令S为一个有着如下特性的随机变量:
w为积分假变量。上式是直方图均衡的连续形式。
接着我们定义一个有如下特性的随机变量Z:
其中,t为积分假变量。
由以上两个等式可知,G(z) = T(r),因此,z也必须满足以下的条件
一旦由输入图像估计出Pr(r),变换函数T(r)就可以由得到。
类似地,因为Pz(z)已知,变换函数G(z)可由得到。
上面的证明过程表明,按照上面的步骤,可由一幅给定图像得到一幅其灰度级具有给定概率密度函数的图像。
直方图规定化,在原理上并不复杂,但是有一个困难是寻找T(r)和G-1的有意义的表达式。
幸运的是,在处理离散量时,问题可以被大大的简化。处理离散量时,仅希望得到一个近似的直方图,所以付出的代价与直方图均衡一样。不去考虑这些代价的话,我们可以得到一些非常有用的结果,尽管是粗糙近似的。
离散形式的直方图均衡如下
MN是图像的像素总数,
nj是灰度值rj 的像素的个数。
类似地,给定一个规定的Sk值
对于一个q值,有G(Zq) = Sk
其中,Pz(Zi)是规定的直方图的第i个值。
与前面一样,我们用反变换找到期望的值Zq:
换句话说,该操作对每个S给出一个Z值,这样,就形成了从S到Z的一个映射。
我们可以总结直方图规定化的变换过程如下:
①计算给定图像的值反图Pr(r),并对他进行直方图均衡变换。把Sk的结果四舍五入为[0,L - 1]内的整数,并存入一个表中。
②用变换q = 0,1,2,...,L - 1,Pz(Zi)是规定的直方图的值,并存入一个表中。
③对于每一个值Sk,使用②存储的值寻找相应的Zq值,使G(Zq)最接近Sk,并存储这些从S到Z的映射。
下面是我用vb实现的直方图规定化:
首先对比一下原图与直方图均衡化后的结果。
原图 直方图均衡化后的结果
分析:
直方图均衡化后的图像对比度明显增加了,但是边角部分阴影加重了。
因此想降低这部分PDF的斜率,或许可以增加图片的质量。
红色部分是我想规定的变换后的PDF。
Pz(Z)我假定为以下的分段函数
{
0.5 * Z + 60 , ( 0 , 80 ],
2.6 * Z - 108 , ( 80 , 140 ],
- 2.09 * Z + 547.6 , ( 140 , 255 ]
}
这一部分理解的不太到位,也不知道我假定的PDF是否可以改善图像。以后对这部分有更深的理解的时候再来补充~
欢迎留言指教~
'直方图规定化
'先对图像进行直方图均衡
Dim img As New Image(Of Gray, Byte)("C:\图像处理实验\test1.bmp")
Dim height As Integer = img.Height
Dim width As Integer = img.Width
'统计每级灰度的像素个数
Dim pixelCounts(255) As Integer
For i = 0 To height - 1
For j = 0 To width - 1
pixelCounts(img.Data(i, j, 0)) = pixelCounts(img.Data(i, j, 0)) + 1
Next
Next
'统计每级灰度的累计像素个数
Dim pixelAccumulative(255) As Integer
For i = 0 To 255
For j = 0 To i
pixelAccumulative(i) = pixelAccumulative(i) + pixelCounts(j)
Next
Next
'根据像素的灰度值映射到新的灰度值
For i = 0 To height - 1
For j = 0 To width - 1
img.Data(i, j, 0) = (256 - 1) / (width * height) * pixelAccumulative(img.Data(i, j, 0))
Next
Next
For i = 0 To 255
pixelAccumulative(i) = (256 - 1) / (width * height) * pixelAccumulative(i)
Next
'计算变换函数的PDF
'Pz(Z) = {
'0.5 * Z + 60 , ( 0 , 80 ],
'2.6 * Z - 108 , ( 80 , 140 ],
'- 2.09 * Z + 547.6 , ( 140 , 255 ]
'}
For i = 0 To 255
If i <= 80 Then
pixelPz(i) = 0.5 * i + 60
ElseIf i <= 140 Then
pixelPz(i) = 2.6 * i - 108
Else
pixelPz(i) = -2.09 * i + 547.6
End If
Next
Dim sumPz As Double = 0
For i = 0 To 255
sumPz = sumPz + pixelPz(i)
Next
For i = 0 To 255
pixelPz(i) = pixelPz(i) / sumPz
Next
'计算G
Dim pixelG(255) As Integer
For i = 0 To 255
For j = 0 To i
pixelG(i) = pixelG(i) + pixelPz(j) * (256 - 1)
Next
Next
'映射
Dim pixelSkZq(255) As Integer
For i = 0 To 255
Dim Sk = pixelAccumulative(i)
Dim flage As Boolean = False
For j = 0 To 255
If pixelG(j) = Sk Then
pixelSkZq(i) = j
flage = True
Exit For
End If
Next
If flage = False Then
For j = 0 To 255
If j = 255 Then
pixelSkZq(i) = j
Exit For
End If
If pixelG(j) < Sk And pixelG(j + 1) > Sk Then
pixelSkZq(i) = j
flage = True
Exit For
End If
Next
End If
Next
'根据像素的灰度值映射到新的灰度值
For i = 0 To height - 1
For j = 0 To width - 1
img.Data(i, j, 0) = pixelSkZq(img.Data(i, j, 0))
Next
Next
img.Save("C:\图像处理实验\直方图匹配\test_result.bmp")
以下是直方图匹配的结果与直方图均衡的结果比较
从结果上来看,实验失败了。图片的效果并没有增强。
我分析的原因可能是指定的灰度值密度变换函数并不恰当,并不能有效的改善图像。但也有可能是我对直方图匹配理解有误导致的算法的错误。有想法的同学欢迎留言指教。
直方图规定化,大多数时候,都是试凑的过程。
一般来说,并没有规定直方图的规则,对于任何一个给定的增强任务,都必须借助于实际分析。