数字图像处理(1) 直方图均衡化

本文地址:
http://harryguo.me/2015/11/06/%E6%95%B0%E5%AD%97%E5%9B%BE%E5%83%8F%E5%A4%84%E7%90%86%EF%BC%881%EF%BC%89-%E7%9B%B4%E6%96%B9%E5%9B%BE%E5%9D%87%E8%A1%A1%E5%8C%96/

什么是直方图均衡化?

为方便起见,本文前面讨论的都是黑白图像(灰度图),后面会特别提及彩色图像。

我们知道,一幅图像的灰度值可以看成一个随机变量,不妨设现在图片的灰度值是$r$,直方图均衡化后的灰度值是$s$。
$r$的概率密度函数(PDF)可能是这样一个乱七八糟的样子:
"变换前概率密度"
这样的概率密度是我们不希望看到的,我们希望整个图像能够均匀的占据灰度的整个区间
"变换后概率密度"
这便是直方图均衡化。


数学推理?

连续空间

对于一个转换来说,我们总是可以把他写成一个函数的形式$s=T(r)$,表示将灰度为$r$的地方都变成$T(r)$。
现在假设$T(r)$是个单调的函数,那么根据概率论的只是我们能够得到这样的变换关系:
$$p_s(s)=p_r(r)*{\left | \frac{dr}{ds} \right |}$$

对上式分离变量积分有:

$$s=T(r)=(L-1)\int_{0}^{r} p_r(w)dw$$

这就是直方图均衡化连续空间域的转换函数。

离散空间

当然一张图片不可能是连续的,所以我们要在离散空间上找寻方法来实现上述功能。

积分就是求和
微分就是差分

使用上面两个策略,我们就能获得离散时间的方法:
概率密度$p(r_k)=\frac{n_k}{MN}$,其中$n_k$表示第$k$级的灰度的个数。
那么变换函数就是:
$$s_k
=T(r_k)
=(L-1)
\sum_{j=0}^{k}
p(r_j)=
\frac{(L-1)}{MN}
\sum_{j=0}^{k}
n_j$$


效果和代码?

说了这么多小伙伴们一定迫不及待想看效果了吧。

代码:

1
2
3
4
I=imread('tree.png');%读取一个图片
J=histeq(I);%matlab自带函数,可以实现上述的变换
figure,imshow(I);%显示原本图片
figure,imshow(J);%显示转换后的图片

效果:

转换之前的:
"BadTree"
转换之后的:
"GoodTree"
很明显可以看出图像的对比度增强了。


彩色图片

我们日常的图片当然不是黑白的,那么彩色图片又该如何处理呢?
想必很多小伙伴都知道彩色图片是由RGB三个分量组成的,所以,我们只需要每个分量分别处理即可。

代码:

1
2
3
4
5
6
7
I=imread('BadRoad.png');%读取图片
r=I(:,:,1);%分离分量
g=I(:,:,2);
b=I(:,:,3);
J=cat(3,histeq(r),histeq(g),histeq(b));%转换并且合并
figure,imshow(I);
figure,imshow(J);

效果:

这效果好到我自己都怕。。。
转换之前:

转换之后:


未谈及:

直方图规定化
局部直方图均衡化