对数函数图像增强
上一篇我们说到的图像线性增强是对于黑白图片整体像素值局限于某一区间的情况进行线性增强。但是有时候的图片显示效果不好并不是这个原因,而是一张图片中的大部分像素值都偏高或偏低,这样的图片整体看起来偏亮或偏暗,这时候利用线性增强所取得的效果或许并不好,甚至于无效(因为一张图片尽管整体偏暗,但是它的最大像素值能达到255,最小像素值能达到0),因此我们需要利用其它方法来进行色彩均衡。这里我们介绍一下利用log函数和幂函数的方法来均衡图像色彩。
首先我们写一个log函数表达式:Y=logaX。这里我们再结合一下log函数图像来直观的感受一下自变量X和因变量Y的关系。函数图像如下:
从该函数图像中我们可以得到以下几点信息:
1、 自变量变化△X时,设因变量变化△Y,其中△Y<△X;
2、 当底数a>1时,log函数为单调递增函数;
3、 当自变量X<1时,因变量Y为负数。
根据以上函数特征,我们知道利用log函数,可以根据底数a的不同,将X作为输入的像素值,Y作为目的像素值,对一张图像的低灰度进行不同程度的拉伸,对于一张图像的高灰度部分进行不同程度的压缩,但是结合图像特征,我们在编写程序时应当注意以下几点:
1、 因为当X的取值达到很大时,Y的值可能仍然很小,所以我们应当添加一个常数C,将log函数公式稍加变形为:Y=ClogaX;
2、 添加的常数C应当有一个原则,即当我们输入的X为输入图像中最大的像素值时,应当能够保证log函数运算后输出的像素值为255,因此我们的C=255/logaFMAX(其中FMAX为当前输入图像的最大像素值);
3、 因为当log函数中的自变量小于1时,函数结果为负,为了防止这种情况出现,我们应当设定X=输入图像的像素值+1;
以上,图像log增强的原理已经讲解完毕,下面是代码实现过程,为了代码简洁性,因此我在代码中直接设定了log的底数a为2(实际上可根据不同情况自行设定,但是需要满足条件a>1)。
```java
public static BufferedImage image_Log(BufferedImage leftImage){
int width = leftImage.getWidth();
int height = leftImage.getHeight();
int srcRGBs[] = leftImage.getRGB(0, 0, width, height, null, 0, width);
int rgb[]=new int[3];
BufferedImage destImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
int fmin=0,fmax=0;
for (int j = 0; j < height; j++) {
for(int i=0; i<width; i++) {
ImageUtil.decodeColor(srcRGBs[j*width+i],rgb);
if(j==0&&i==0){
fmin=rgb[1];
fmax=rgb[2];
}
if (rgb[1]<fmin){
fmin=rgb[1];
}
if (rgb[1]>fmax){
fmax=rgb[1];
}
}
}
for (int j=0;j<height;j++) {
for (int i = 0; i < width; i++) {
ImageUtil.decodeColor(srcRGBs[j * width + i], rgb);
rgb[0]=(int)(((255.0/Math.log(1+fmax))*Math.log(1+rgb[0])));//这里之所以这么乘,是为了保证最大值(不到255)能到达255
rgb[1]=(int)(((255.0/Math.log(1+fmax))*Math.log(1+rgb[1])));
rgb[2]=(int)(((255.0/Math.log(1+fmax))*Math.log(1+rgb[2])));
destImage.setRGB(i,j, ImageUtil.encodeColor(rgb));
}
}
return destImage;
}
``
下面是实现效果图:
以上就是利用对数函数实现图像增强的具体实现,但是你用对数函数仍然有一定的局限性,如它的作用所提,它对于过亮的图像无法进行增强。因此,下篇我将介绍更为强大的伽马变换进行图像增强,他可以对于过亮或过暗的图像进行调节。
总代码包下载:https://download.csdn.net/download/yiyexy/12323645