直方图均衡化,又叫做直方图修平,是对图像进行非线性拉伸,重新分配图像像素值,把原始图像的灰度直方图从比较集中的某个灰度区间转换为全部灰度范围内的均匀分布,这样就增加了像素灰度值的动态范围,达到增强图像整体对比度的效果。
具体算法步骤如下:
1,计算图像f中各个灰度级像素出现的概率,公式如下:
其中ni表示灰度级i出现的次数,L是图像中所有的灰度数。p实际上是图像的直方图归一化到0-1范围内。
2,计算p的累积概率,我们定义c作为对应于p的累积概率函数,公式如下:
c也可以看作是图像的累计归一化直方图。
3,创建y=T(x)的变换,对于原始图像中的每一个值它就产生一个y,这样y的累积概率函数就可以在所有值范围内进行线性变换,公式如下:
其中,T是将不同的等级映射到0-1范围内的映射函数。
本文程序中使用的参数为K=255。
[函数代码]
///
/// Histogram equalization process.
///
/// The source image.
///
public static WriteableBitmap HistogramEqualProcess(WriteableBitmap src)////30图像直方图均衡化
{
if (src != null)
{
int w = src.PixelWidth;
int h = src.PixelHeight;
WriteableBitmap histogramEqualImage = new WriteableBitmap(w, h);
byte[] temp = src.PixelBuffer.ToArray();
byte gray;
int[] tempArray = new int[256];
int[] countPixel = new int[256];
byte[] pixelMap = new byte[256];
for (int i = 0; i < temp.Length; i += 4)
{
gray = (byte)(temp[i] * 0.114 + temp[i + 1] * 0.587 + temp[i + 2] * 0.299);
countPixel[gray]++;
}
for (int i = 0; i < 256; i++)
{
if (i != 0)
{
tempArray[i] = tempArray[i - 1] + countPixel[i];
}
else
{
tempArray[0] = countPixel[0];
}
pixelMap[i] = (byte)(255 * tempArray[i] * 4 / temp.Length + 0.5);
}
for (int i = 0; i < temp.Length; i+=4)
{
gray = temp[i];
temp[i] = pixelMap[gray];
gray = temp[i+1];
temp[i+1] = pixelMap[gray];
gray = temp[i+2];
temp[i+2] = pixelMap[gray];
}
Stream sTemp = histogramEqualImage.PixelBuffer.AsStream();
sTemp.Seek(0, SeekOrigin.Begin);
sTemp.Write(temp, 0, w * 4 * h);
return histogramEqualImage;
}
else
{
return null;
}
}
[图像效果]
demo下载: http://www.zealfilter.com/forum.php?mod=viewthread&tid=21&extra=page%3D1