java处理灰度图像时的问题
周六终于可以搞点自己的事情了...对于java图像处理来说,我还在门槛上徘徊,下面就将碰到的几个问题写下来:
1 在读入灰度图像时,inputImage = Toolkit.getDefaultToolkit().getImage("\\inputImage.jpg");无法读入灰度图像;
改为
File inputFile = new File("\\inputImage.jpg");
BufferedImage input = ImageIO.read(inputFile);
就可以读入了。
2 显示灰度图像时,有两种方法,一种是使用ImageProducer,如下
ImageProducer ip = new MemoryImageSource(iw,ih,pixels,0,iw);
tmp = createImage(ip);
repaint();
另一种方法是grayImage.setRGB,如下
在两个for循环中调用grayImage.setRGB(i, j, rgb);
处理完后继续
tmp = grayImage;
repaint();
这两种方法的区别是,第一种改变了灰度图像的像素值,使图像明显变亮,这应该是java的一个bug,无奈探讨的人少,具体原因我也不知道。第二种方法是没有问题。
原始的lena图像在附件里,为lena_grey;显示如下:
使用ImageProducer方法产生图片是附件里边的liang_lena_grey.jpg,可以从下图看到,图像明显变亮:
3 将paint函数写在这里吧:
public void paint(Graphics g){
if(flag_Load){
g.drawImage(tmp,0,0,this);
}else{}
}
4 还有一个问题是如何保存图像。在使用ImageIO.write()是,我遇到的问题是
sun.awt.image.ToolkitImage cannot be cast to java.awt.image.RenderedImage
也就是说,tmp的类型是sun.awt.image.ToolkitImage,而ImageIO.write能操作的图像是 java.awt.image.RenderedImage,为了解决这个问题,需要转换一下格式再进行保存,程序如下:
BufferedImage bi = new BufferedImage(tmp.getWidth(null),tmp.getHeight(null),
BufferedImage.TYPE_INT_RGB);
Graphics g = bi.getGraphics();
g.drawImage(tmp,0, 0,null);
g.dispose();
File save_path=new File(filepath);
ImageIO.write(bi, "JPG", save_path);
5 最后一个问题是像素值的获取。java好像没有直接读取灰度值的函数,在处理灰度图像时,java仍将灰度图像当做彩色图像处理,因此使用公式转换就好了。
int rgb=inputImage.getRGB(i, j);
int grey = (int) (0.3*((rgb & 0xff0000 ) >> 16) + 0.59*((rgb & 0xff00 ) >> + 0.11*((rgb & 0xff )));
还要注意的是,直接调用inputImage.getRGB(i, j)得到的像素并不是我们熟悉的0-255,以lena为例,第5行第5列的像素值为-3026479,必须将red>>16,green>>8之后才能得到0-255之间的值,就像上面第二行代码写到的那样。转换完之后,-3026479就变成了209.
这几个问题虽然很小,但是相比C++,java图像处理的资料偏少,好多技术细节只能自己去摸索。