直方图均衡化

来源:互联网 发布:淘宝店铺会员管理系统 编辑:程序博客网 时间:2024/06/03 12:39

变换函数

一幅给定的图像的灰度级 r 分布在[0,1]范围内。可以对任一个 r 值进行如下变换:

s=T(r)       r[0,1]
使得每个原始图像的像素灰度值 r 都对应产生一个 s 值。

变换函数T(r)要求满足下列条件:

1.T(r)单调递增;
2. 对于r[0,1],有T(r)[0,1]

反变换函数

当 T 严格单调时,从 s 到 r 的反变换可用式下表示

r=T1(s)       s[0,1]

可得反变换函数T1(s)满足下列条件:

1.T1(s)单调递增;
2. 对于s[0,1],有T1(s)[0,1]


概率密度函数

一副图像的灰度级可被视为区间[0,1]随机变量
pr(r)ps(s)分别代表随机变量 r 和 s 的概率密度函数

已知pr(r)s=T(r),求ps(s)
即求随机变量的函数的概率密度。

在概统里面的方法一般是:
1. 分布函数法。先求分布函数再求导。
2. 特别的,当函数T严格单调,有结论如下:

ps(s)=pr(r)|dT1(s)ds|=pr(r)|drds|     ()

具体的推导过程可以去翻翻概统书。
下面提供错误的推导

pr(r)=pr(T1(s))ps(s)
ps()=pr(T1())


直方图均衡化

直方图均衡化处理是以累积分布函数变换法为基础的直方图修正法。

连续随机变量

假定变换函数为:

s=T(r)=r0pr(w) dw
对 r 进行求导得:
dsdr=pr(r)
代入到()中,得到
ps(s)=1
该结果表明在假定的变换函数的作用下,变换后的变量 s 的概率密度是均匀分布的。

因此,用 r 的分布函数作为变换函数,可产生一幅灰度级分布具有均匀概率密度的图像。其结果扩展了像素取值的动态范围。

离散随机变量

但该结果只对于连续变量而言。在实际中灰度是呈离散形式分布的,不能保证均匀分布。

当灰度级是离散值时,可用频数近似代替概率值,即

pr(rk)=nkn       rk[0,1],k=0,1,...,L1
变换函数为:
sk=T(rk)=j=0kpr(rj)

因为直方图是近似的概率密度函数,所以用离散灰度级作变换一般得不到完全平坦的结果。由于简并现象的存在,处理后的灰度级总是要减少的,这是像素灰度有限的必然结果。由于上述原因,数字图像的直方图均衡只是近似的。


代码实现

采用256灰阶的Lena图。

  1. 统计每个灰度的概率p
  2. 做累积分布s
  3. 将累积分布作为变换函数T
  4. 转换每个灰度值

github source code

Image HistogramEqualization(Image inImage, int width, int height) {    Image outImage(width, height);    int rn[256] = { 0 }, sum = width * height;    for (int y = 0; y < height; y++) {        for (int x = 0; x < width; x++) {            Pixel p = inImage.getPixel(x, y);            rn[p.getR()]++; // 统计每个灰度的数量        }    }    double p[256], s[256];    int T[256];    for (int i = 0; i < 256; i++)        p[i] = 1.0 * rn[i] / sum; // 计算每个灰度的概率    s[0] = p[0];    for (int i = 1; i < 256; i++) {        s[i] = p[i] + s[i - 1];  // 做累积分布        T[i] = (int)(s[i] * 256); // 将累积分布作为变换函数T    }    for (int y = 0; y < height; y++) {        for (int x = 0; x < width; x++) {            Pixel p = inImage.getPixel(x, y);            const int r = T[p.getR()];  // 转换灰度值            p.set(r, r, r);            outImage.setPixel(x, y, p);        }    }    return outImage;}


下面是均衡化后的图像

彩图则对rgb都均衡化处理

void HE(int *rn, int sum, int *rT) {    double rp[256], rs[256];    for (int i = 0; i < 256; i++)        rp[i] = 1.0 * rn[i] / sum;    rs[0] = rp[0];    for (int i = 1; i < 256; i++) {        rs[i] = rp[i] + rs[i - 1];        rT[i] = (int)(rs[i] * 256);    }}Image HistogramEqualization(Image inImage, int width, int height) {    Image outImage(width, height);    int rn[256] = { 0 }, sum = width * height;    int gn[256] = { 0 };    int bn[256] = { 0 };    for (int y = 0; y < height; y++) {        for (int x = 0; x < width; x++) {            Pixel p = inImage.getPixel(x, y);            rn[p.getR()]++;            gn[p.getR()]++;            bn[p.getR()]++;        }    }    // 三者都均衡化处理    int rT[256], gT[256], bT[256];    HE(rn, sum, rT);    HE(gn, sum, gT);    HE(bn, sum, bT);    for (int y = 0; y < height; y++) {        for (int x = 0; x < width; x++) {            Pixel p = inImage.getPixel(x, y);            p.set(rT[p.getR()], gT[p.getG()], bT[p.getB()]);            outImage.setPixel(x, y, p);        }    }    return outImage;}


下图为均衡化后

并没有变好吃(¬︿̫̿¬☆)!

原创粉丝点击