直方图均衡虽然可以显著改善图像质量,但是它是一个全局修改的方法——图像的每一个像素值都用完全相同的变换函数来修改。这样做的弊端在于图像局部的细节很可能因为受到其他区域的属性的影响而丢失。例如在下图的高亮度区域,全局直方图均衡调整之后,由于亮度过高而呈现一片亮白,很难再看清楚海豹的细节纹理。
原图
直方图均衡后
既然全局调整效果不太理想,一个直接的想法就是进行局部调整。将图片分成若干区域,每个区域单独进行直方图均衡操作,这样各个区域就不会受到其他区域的影响而导致细节丢失了。显然,这个方法的也不是完美的。由于各个区域采用了不同的变换函数,在相邻区域的边界处的像素值在处理后几乎不可能保持连续性——只有在每个区域各自的直方图都完全一致的情况下才有可能保持连续性,而这显然和实际情况不符。
解决这个问题的办法其实也很简单,既然是由于采用了不同的变换函数而导致的不连续性,那就对变换函数插值使得最终的变换函数在整个图像上是连续的就好了(Wiki)。插值的方法跟图像双线性插值是一样的,只要将变换函数想象成一个图像就好了。把每个小区域内的变换函数想象成一个像素点,这些变换函数共同构成了一副小图像,而原图像的像素点则相当于这个小图像内的亚像素元素(sub-pixel elements)。在进行直方图均衡操作时,原图的每个像素点的变换函数由它所在的区域以及周围三个相邻区域的变换函数插值得到。插值的时候考虑该像素点离这四个区域中心的距离并以此为权重进行线性插值。如下图所示,红色像素点的变换函数T由T1, T2, T3和T4插值得到:
T = T1 * (1-fx) * (1-fy) + T2 * fx * (1-fy) + T3 * (1-fx) * fy + T4 * fx * fy
因为直方图均衡的变换函数本身也是线性的,所以上面的公式可以直接改写成:
k = 255 / n * [ c1(I) * (1-fx) * (