直方图均衡化计算题
讲解直方图均衡化之前,先解释一下图像的统计直方图与累加概率。
1. 统计直方图,就是统计图像中每一个像素值的个数。比如对于8位的图像,每一个像素点的像素值取值范围是0~255,那么其统计直方图就是统计0~255中所有像素值在图像中的个数,比如0像素值有几个点、1像素值有几个点、2像素值有几个点......像素255有几个点,如下图所示:
2. 像素的概率,也就是该像素值的统计直方图值(像素数)除以图像的总像素数,假设像素x的统计直方图值为hist(x),图像的总像素数为size,那么该像素的概率为:
像素值x的累加概率,就是所有小于等于x的像素值的像素数,除以图像的总像素数,可按下式计算:
3. 接下来讲解直方图均衡化的原理。通常认为,图像的统计直方图分布越均匀,图像的质量越好,直方图均衡化可以提升图像的对比度和质量。比如有的图像整体较暗,那么说明其直方图中低像素值分布较多,高像素值分布较少,这时可以使用直方图均衡化来平衡其直方图分布,即减少低像素值,增加高像素值。从直观上看,均衡化的效果就是图像的部分区域相对原来变亮了,所以提升了图像的对比度。
直方图均衡化就是一个所有像素值重映射的过程。比如像素值x的直方图均衡化之后的值可按下式计算,其中n为图像的每一个像素点的位宽,对于灰度图通常n=8,P(x)为像素值x的累加概率。
使用C++实现上述算法:
运行上述代码,对Lena图像进行直方图均衡化,结果如下,可以看到直方图均衡化之后,图像对比度增强了,统计直方图分布也更加均匀。
原图
直方图均衡化之后图像
原图的统计直方图
直方图均衡化之后的统计直方图
4. 观察上方H(x)的计算公式,P(x)的取值范围是0~1,H(x)与P(x)具有线性关系。为了进一步提升图像对比度,可以对P(x)作一个非线性的S型变换T(P(x)),并保证变换之后T(P(x))的取值范围还在0~1之间。本文分别构造了T1和T2这两个非线性函数用于非线性变换,同时我们可以把原本H(x)与P(x)的线性关系看成函数T0,于是有以下三种变换:
画出以上三种变换函数在0~1区间的曲线如下图所示,可以看到T1和T2的曲线都是S型。
从而H(x)与P(x)有三种映射关系:
增加非线性变换的代码实现与上述代码大同小异:
分别选择T0、T1和T2变换,运行以上代码,得到的结果如下,可以看到使用T1和T2变换得到结果的对比度相对于T0有所提高。
T0
T1
T2
5. 上述直方图均衡算法还存在一个问题,就是当图像的0像素值占很大比例时,从起始的0像素值的累加概率就很大了,导致后面的1~255像素值的累加概率均变得很大,从而造成直方图均衡化之后的像素值都偏大。比如下图,可以看到直方图均衡化之后图像变白了,严重失真。
原图
直方图均衡化之后的图像
为解决上述问题,我们可以把0像素值排除在外,也即0像素值不做处理,从像素值1开始计算累加概率,同时计算累加概率时使用到的图像总像素数应减去0像素值的像素数。代码如下:
运行上述代码,得到结果,可以看到直方图均衡化之后,像素值不会再有整体偏高的问题。