如何将图像转换为0-255灰度图像

1 java image-processing grayscale

我想将图像转换为灰度图像,其中像素强度0-255之间.

我能够使用以下Java方法将图像转换为灰度图像.

public void ConvertToGrayScale(BufferedImage bufImage, int ImgWidth, int ImgHeight) {

    for (int w = 0; w < ImgWidth; w++) {
        for (int h = 0; h < ImgHeight; h++) {

            Color color = new Color(bufImage.getRGB(w, h));
            int ColAvgVal = ((color.getRed() + color.getGreen() + color.getBlue()) / 3);
            Color avg = new Color(ColAvgVal, ColAvgVal, ColAvgVal);

            bufImage.setRGB(w, h, avg.getRGB());

            System.out.println(avg.getRGB());
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

"的System.out.println(avg.getRGB());" 用于查看像素强度,但所有灰度级都是负值,而不是0-255之间.

我做错了吗?如何将图像转换为像素强度在0-255之间的灰度图像.

谢谢

usr*_*301 6

color.getRGB()不返回0..255的值,它返回由红色,绿色和蓝色值组成的整数,包括Alpha值.据推测,这个alpha值是0xFF,这使得任何组合颜色最终成为0xFFrrggbb,或者,当你得到时,用小数写成一个巨大的负数.

要查看指定的"灰色"级别,请检查ColAvgVal.

请注意,更好的RGB和灰度转换公式是使用PAL/NTSC转换:

gray = 0.299 * red + 0.587 * green + 0.114 * blue
Run Code Online (Sandbox Code Playgroud)

因为"全蓝"的灰度应该比"全红"和"全绿"更暗.


注意:如果直接使用此公式,请注意浮点舍入错误.从理论上讲,它不应该的外面返回一个值0..255gray; 在实践中,它会.所以测试并钳制结果.

另一个不需要每像素测试和钳位的选项是使用仅整数版本:

gray = (299 * red + 587 * green + 114 * blue)/1000;
Run Code Online (Sandbox Code Playgroud)

这应该只用很小的舍入误差.

  • 另一种选择是:`gray =(77*red + 150*green + 29*blue)>> 8;`.向右移位8相当于除以256,并且"77/256 = 0.299,150/256 = 0.587"和"29/256 = 0.114".这就像你所说的那样计算转换为灰度的SMPTE标准,但它避免了所有的划分.仍然是你的整数版本的很好的解决方法! (2认同)