【问题标题】:How to convert int RGB into BYTE 2D array gray image如何将int RGB转换为BYTE 2D数组灰度图像
【发布时间】:2016-08-16 17:00:02
【问题描述】:

我正在尝试将彩色图像转换为灰度图像并将其作为 BYTE 值保存到二维数组中,稍后我需要对这个二维数组进行一些处理。虽然,我的数组的值都是字节,但我的输出图像变成蓝色而不是灰色。谁能帮帮我? 这是我的代码:

public class HW {

public static void main(String[] args) {
    int[][] savedImage = readimage(new File("C:\\Images\\input.jpg"));

    BufferedImage grayImage = new BufferedImage(savedImage.length, savedImage[0].length, BufferedImage.TYPE_INT_RGB);

    for (int i =0 ; i<savedImage.length ; i ++){
        for (int j=0 ; j<savedImage[0].length ; j++){
            grayImage.setRGB(i, j, savedImage[i][j]);
            System.out.print(savedImage[i][j] + ",");
        }
        System.out.println();
    }

    try {
        File outputfile = new File ("C:\\Images\\garyoutput.jpg");
        ImageIO.write(grayImage, "jpg", outputfile);
    }
    catch(IOException e ) {
        e.printStackTrace();
    }
}

public static int[][] readimage(File filename) throws IOException {
    // Grayscale Image output
    BufferedImage img = ImageIO.read(filename);

    int width = img.getWidth();
    int height = img.getHeight();
    int [][] readimageVal = new int [width][height];

    for (int i = 0; i<height ; i++) {
        for (int j =0  ; j<width ; j++) {
            int p = img.getRGB(j,i);

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

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

            readimageVal[j][i] = avg;
        }
    }
    return readimageVal;
}

}

【问题讨论】:

  • 您设置了错误的图像像素/字节类型。尝试使用new BufferedImage(savedImage.length, savedImage[0].length, BufferedImage.TYPE_USHORT_GRAY);

标签: java arrays image-processing rgb grayscale


【解决方案1】:

问题出在main方法中的主嵌套循环中:

for (int i =0 ; i<savedImage.length ; i ++){
    for (int j=0 ; j<savedImage[0].length ; j++){
           grayImage.setRGB(i, j, savedImage[i][j]);//← Here
        System.out.print(savedImage[i][j] + ",");
    }
}

int[][] savedImage 包含一个表示灰度值的字节,但grayImage 仍然是BufferedImage.TYPE_INT_RGB 类型。所以,如果你只调用grayImage.setRGB(i, j, savedImage[i][j]),只会设置int的蓝色部分:

RRRRRRRR GGGGGGGG BBBBBBBB
00000000 00000000 xxxxxxxx

所以你需要改为:

int rgb = savedImage[i][j];
rgb = (rgb<<16)|(rgb<<8)|(rgb);
grayImage.setRGB(i, j, rgb);

【讨论】:

    【解决方案2】:

    您有不同的可能性来做到这一点,但首先,这是访问像素的更简单方法:

    public static int[][] readimage(File filename) throws IOException {
        BufferedImage img = ImageIO.read(filename) ;// Grayscale Image output
        final int width = img.getWidth() ;
        final int height = img.getHeight() ;
        int[][] graylevelarray = new int[height][width] ;
    
        for (int y=0 ; y < height ; y++)
            for (int x=0 ; x < width ; x++) {
                int r = img.getRaster().getSample(x, y, 0) ;
                int g = img.getRaster().getSample(x, y, 1) ;
                int b = img.getRaster().getSample(x, y, 2) ;
                graylevelarray[y][x] = ??? ;
                }
    
        return graylevelarray ;
        }
    

    正如我所说,对于转换,您有许多不同的可能性:

    • 和你一样的平均值,但很少使用。
    • CIE 601 (0.299*R + 0.587*G + 0.114*B) 或 CIE 709 (0.2125*R + 0.7154*G + 0.0721*B) 建议,最常用。
    • 便宜/快绿(R+2*G+B)/4,即更快,例如用于Zxing库中。

    【讨论】:

      猜你喜欢
      • 2021-04-02
      • 1970-01-01
      • 1970-01-01
      • 2014-02-26
      • 2014-12-22
      • 2013-10-25
      • 1970-01-01
      • 2019-11-27
      相关资源
      最近更新 更多