图像处理(二)直方图均衡化

首先给大家推荐一下我老师大神的人工智能教学网站。教学不仅零基础,通俗易懂,而且非常风趣幽默,还时不时有内涵黄段子!点这里可以跳转到网站

直方图均衡化又称直方图修平,是一种很重要的非线性点运算。使用该方法可以加强图像的局部对比度,尤其是当图像的有用数据的对比度相当接近的时候。通过这种方法,亮度可以更好的在直方图上分布。

直方图均衡化的基本思想是把原始图像的直方图变换为均匀分布的形式。这样增加了灰度值的动态范围,从而达到增强图像整体对比度的效果。

算法步骤:

1)计算图像f(x,y)的各灰度级中像素出现的概率p(i)。

2) 计算p的累计概率函数c(i),c即为图像的累计归一化直方图

3)将c(i)缩放至0~255范围内

以下为算法实现(C#)

 /// <summary>    /// 直方图均衡化 直方图均衡化就是对图像进行非线性拉伸,重新分配图像像素值,使一定灰度范围内的像素数量大致相同    /// 增大对比度,从而达到图像增强的目的。是图像处理领域中利用图像直方图对对比度进行调整的方法    /// </summary>    /// <param name="srcBmp">原始图像</param>    /// <param name="dstBmp">处理后图像</param>    /// <returns>处理成功 true 失败 false</returns>    public static bool Balance(Bitmap srcBmp, out Bitmap dstBmp) {        if (srcBmp == null) {            dstBmp = null;            return false;        }        int[] histogramArrayR = new int[256];//各个灰度级的像素数R        int[] histogramArrayG = new int[256];//各个灰度级的像素数G        int[] histogramArrayB = new int[256];//各个灰度级的像素数B        int[] tempArrayR = new int[256];        int[] tempArrayG = new int[256];        int[] tempArrayB = new int[256];        byte[] pixelMapR = new byte[256];        byte[] pixelMapG = new byte[256];        byte[] pixelMapB = new byte[256];        dstBmp = new Bitmap(srcBmp);        Rectangle rt = new Rectangle(0, 0, srcBmp.Width, srcBmp.Height);        BitmapData bmpData = dstBmp.LockBits(rt, ImageLockMode.ReadWrite, PixelFormat.Format24bppRgb);        unsafe {            //统计各个灰度级的像素个数            for (int i = 0; i < bmpData.Height; i++) {                byte* ptr = (byte*)bmpData.Scan0 + i * bmpData.Stride;                for (int j = 0; j < bmpData.Width; j++) {                    histogramArrayB[*(ptr + j * 3)]++;                    histogramArrayG[*(ptr + j * 3 + 1)]++;                    histogramArrayR[*(ptr + j * 3 + 2)]++;                }            }            //计算各个灰度级的累计分布函数            for (int i = 0; i < 256; i++) {                if (i != 0) {                    tempArrayB[i] = tempArrayB[i - 1] + histogramArrayB[i];                    tempArrayG[i] = tempArrayG[i - 1] + histogramArrayG[i];                    tempArrayR[i] = tempArrayR[i - 1] + histogramArrayR[i];                }                else {                    tempArrayB[0] = histogramArrayB[0];                    tempArrayG[0] = histogramArrayG[0];                    tempArrayR[0] = histogramArrayR[0];                }                //计算累计概率函数,并将值放缩至0~255范围内                pixelMapB[i] = (byte)(255.0 * tempArrayB[i] / (bmpData.Width * bmpData.Height) + 0.5);//加0.5为了四舍五入取整                pixelMapG[i] = (byte)(255.0 * tempArrayG[i] / (bmpData.Width * bmpData.Height) + 0.5);                pixelMapR[i] = (byte)(255.0 * tempArrayR[i] / (bmpData.Width * bmpData.Height) + 0.5);            }            //映射转换            for (int i = 0; i < bmpData.Height; i++) {                byte* ptr = (byte*)bmpData.Scan0 + i * bmpData.Stride;                for (int j = 0; j < bmpData.Width; j++) {                    *(ptr + j * 3) = pixelMapB[*(ptr + j * 3)];                    *(ptr + j * 3 + 1) = pixelMapG[*(ptr + j * 3 + 1)];                    *(ptr + j * 3 + 2) = pixelMapR[*(ptr + j * 3 + 2)];                }            }        }        dstBmp.UnlockBits(bmpData);        return true;    }

效果图

补充(20160503):

直方图均衡化是以累积分布函数变换为基础的一种直方图修改方法。假定变换函数为

(1)

x 是积分变量,是r的累计分布函数。且上式满足:

(1)在r∈[0,1]内,T(r) 是单调增加的;

(2)对于0≤r≤1,有0≤T(r)≤1。

上式对r求导,得:

(2)

(参见图像处理(〇)直方图修改基础

所以,通过上面得到推导可见,在变换后的变量S的定义域内的概率函数是均匀分布的。因此,通过图像的累计分布函数作为变换函数可以将图像的灰度级分布调整为均匀分布,结果就是增大了像素取值的动态范围,这就是直方图均衡化的数学原理。

点这里可以跳转到人工智能网站

发表评论