程序不能对某些图像进行灰度图像处理?

时间:2018-05-09 01:36:53

标签: java image-manipulation grayscale

我正在尝试创建一个程序,在我选择的图像上为我的计算机科学课程应用灰度滤镜。 我在教程中找到了以下代码,它演示了灰度算法,其中图像中每个像素的R,G和B值都被RGB值的平均值替换。

import java.io.File;
import java.io.IOException;
import java.awt.image.BufferedImage;
import javax.imageio.ImageIO;

public class Grayscale{
public static void main(String args[])throws IOException{
BufferedImage img = null;
File f = null;

//read image
try{
  f = new File("D:\\Image\\Taj.jpg");
  img = ImageIO.read(f);
}catch(IOException e){
  System.out.println(e);
}

//get image width and height
int width = img.getWidth();
int height = img.getHeight();

//convert to grayscale
for(int y = 0; y < height; y++){
  for(int x = 0; x < width; x++){
    int p = img.getRGB(x,y);

    int a = (p>>24)&0xff;
    int r = (p>>16)&0xff;
    int g = (p>>8)&0xff;
    int b = p&0xff;

    //calculate average
    int avg = (r+g+b)/3;

    //replace RGB value with avg
    p = (a<<24) | (avg<<16) | (avg<<8) | avg;

    img.setRGB(x, y, p);
  }
}

//write image
try{
  f = new File("D:\\Image\\Output.jpg");
  ImageIO.write(img, "jpg", f);
}catch(IOException e){
  System.out.println(e);
}
}//main() ends here
}//class ends here

问题是,程序没有在某些图像上正确应用灰度滤镜。例如,代码可以在this图片上正确应用过滤器,从而创建grayscale image。但是下面的图像了 rainbow看起来像this,并且应用了灰度滤镜。

为什么红色,绿色,蓝色和粉红色显示过滤器?我的理解是,当一个像素的R,G和B值相同时,应该创建一个灰色?

1 个答案:

答案 0 :(得分:0)

来自BufferedImage.setRGB()

的JavaDoc

&#34;将此BufferedImage中的像素设置为指定的RGB值。假设像素位于默认的RGB颜色模型TYPE_INT_ARGB和默认的sRGB颜色空间中。对于具有IndexColorModel的图像,选择具有最近颜色的索引。&#34;

要解决此问题,请创建一个新的BufferedImage,其中包含所需的颜色空间,与原始图像的尺寸相同,并将像素写入其中,而不是回到原始的BufferedImage。

BufferedImage targetImage = new BufferedImage(img.getWidth(),
        img.getHeight(),  BufferedImage.TYPE_3BYTE_BGR);

将像素写入此图像......

targetImage.setRGB(x, y, p);

然后保存这个新图片..

ImageIO.write(targetImage, "jpg", f);

注意,将彩色图像转换为灰度的更准确方法是将RGB像素转换为YUV颜色空间,然后使用亮度值,而不是RGB的平均值。这是因为R G和B的亮度加权不同。