0%

图像信息处理作业Assignment3

第三次图像信息处理作业解析,这次要对直方图动手了。

Assignment-3作业要求

  • Image logarithmic operation for visibility enhancement
  • Histogram equalization

    作业分析

    图像对数强化

这玩意儿老师上课貌似没讲,检索了一下大概就是通过如下的公式进行操作

S=c×log(1+r)where,S=output pixel valueC=scaling constantR=input pixel value

在这里,我们定义如下的常数C

C=255log(1+max input pixel value)

通过加一我们可以保证所有的CS是非负数

首先先求出C

1
2
3
4
5
6
7
8
unsigned char* max;
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
unsigned char data = *(biData + lineBytes * (height - 1 - i) / 3 + j);
max = max > data ? max : data;
}
}
double c = 255.0 / (log(1 + max));

然后代入公式

1
2
3
4
5
6
7
unsigned char* logData = new unsigned char[lineBytes * height / 3];
for (int i = 0; i < height; i++) {
for (int j = 0; j < width; j++) {
unsigned char r = *(biData + lineBytes * (height - 1 - i) / 3 + j)
*(logData + lineBytes * (height - 1 - i) / 3 + j) = c * log(1 + r);
}
}

这样我们就获得了log后的图像

直方图均衡化

考虑一个离散的灰度图像x,让ni 表示灰度i出现的次数,这样图像中灰度为i的像素的出现概率是

 px(i)=p(x=i)=nin,0i<L

L 是图像中所有的灰度数(通常为256),n 是图像中所有的像素数,px(i)实际上是像素值为i的图像的直方图,归一化到 [0,1]。

把对应于px的累积分布函数,定义为:

 cdfx(i)=j=0ipx(j),

是图像的累计归一化直方图。

我们创建一个形式为y=T(x) 的变换,对于原始图像中的每个值它就产生一个y,这样 y的累计概率函数就可以在所有值范围内进行线性化,转换公式定义为:

 cdfy(i)=iK

对于常数K。CDF的性质允许我们做这样的变换(参见逆分布函数);定义为

 cdfy(y)=cdfy(T(k))=cdfx(k)

其中k属于区间 [0,L)。注意 T 将不同的等级映射到0..1​域,为了将这些值映射回它们最初的域,需要在结果上应用下面的简单变换:

 y=y(max{x}min{x})+min{x}

上面描述了灰度图像上使用直方图均衡化的方法,但是通过将这种方法分别用于图像RGB颜色值的红色、绿色和蓝色分量,从而也可以对彩色图像进行处理。

首先,我们需要先得到直方图

1
2
3
4
5
6
7
8
9
10
unsigned char* histData = new unsigned char[lineBytes * height / 3];
int hist[256] = {0}, eqHist[256] = {0};
int size = height * width;
double fpHist[256] = {0}, eqHistTemp[256] = {0};
for (int i = 0; i < height; i++) { //计算直方图
for (int j = 0; j < width; j++) {
unsigned char GrayIndex = *(biData + lineBytes * (height - 1 - i) / 3 + j);
hist[GrayIndex]++;
}
}

然后,我们计算灰度分布和累计直方图分布

1
2
3
4
5
6
7
8
9
10
11
12
for (int i = 0; i < 256; i++) { //计算灰度分布密度
fpHist[i] = (double)hist[i] / (double)size;
}

for (int i = 0; i < 256; i++) { //计算累计直方图分布
if (i == 0) {
eqHistTemp[i] = fpHist[i];
}
else {
eqHistTemp[i] = eqHistTemp[i - 1] + fpHist[i];
}
}

最后,我们可以直接得出映射关系

1
2
3
4
5
6
7
8
9
10
//累计分布取整,保存计算出来的灰度映射关系
for (int i = 0; i < 256; i++) {
eqHist[i] = (int)(255.0 * eqHistTemp[i] + 0.5);
}
for (int i = 0; i < height; i++) { //进行灰度映射均衡化
for (int j = 0; j < width; j++) {
unsigned char GrayIndex = *(biData + lineBytes * (height - 1 - i) / 3 + j);
*(histData + lineBytes * (height - 1 - i) / 3 + j) = eqHist[GrayIndex];
}
}

效果如图

总结

总的来说这次作业依然是十分的宁静祥和、简单质朴,不过在直方图均衡化的部分由于不太了解细节,因此借鉴了部分代码,写作风格也十分的奇妙,希望多多包含。