如何从 Java 中的图片中获取 0..255 种颜色?

How to get 0..255 colors from a picture in Java?

我试过对一张已经是黑白灰的图片进行灰度化,结果变成了黑色。

当我尝试用 Java 对图片进行灰度化时,我是这样的:

    // This turns the image data to grayscale and return the data
    private static RealMatrix imageData(File picture) {
        try {
            BufferedImage image = ImageIO.read(picture);
            int width = image.getWidth();
            int height = image.getHeight();
            RealMatrix data = MatrixUtils.createRealMatrix(height * width, 1);
            // Convert to grayscale
            int countRows = 0;
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    // Turn image to grayscale
                    int p = image.getRGB(x, y);
                    int r = (p >> 16) & 0xff;
                    int g = (p >> 8) & 0xff;
                    int b = p & 0xff;

                    // calculate average and save
                    int avg = (r + g + b) / 3;
                    data.setEntry(countRows, 0, avg);
                    countRows++;
                }
            }
            return data;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }

    }

我看到的问题是 p 是一个 32 位值,而我只想要 8 位值。即使图片已经灰度化,p值也已经是32位值了。这给我带来了麻烦。

所以如果我对灰色图片进行灰度化,它会变成黑色。或者至少更暗。 我想要 p 的 0..255 个值,这是一个 32 位整数值。

您对如何读取 8 位图片有什么建议吗? 用于图像分类。

总结:

我需要帮助从 0..255 格式的图片中获取每个像素。 一种方法是对其进行灰度化,但如何验证图片是否已灰度化?

更新:

我试图读取一张图片,因为它是 8 位值。有用。然后我尝试用相同的值保存图片。画面变得很暗。

我想展示一个 matlab 示例。 首先我读了我的照片:

image = imread("subject01.normal");

然后我保存图片。

imwrite(uint8(image), "theSameImage.gif")

如果我尝试使用最小的 Java 代码来读取图像。

private static void imageData(File picture) {
        try {
            BufferedImage image = ImageIO.read(picture);
            int width = image.getWidth();
            int height = image.getHeight();
            DataBuffer buffer = image.getRaster().getDataBuffer();
            for (int y = 0; y < height; y++) {
                for (int x = 0; x < width; x++) {
                    int p = buffer.getElem(x + y * width);
                    image.setRGB(x, y, p);
                }
            }
            File output = new File(picture.getName());
            ImageIO.write(image, "gif", output);
            return data;
        } catch (Exception e) {
            e.printStackTrace();
            return null;
        }
    }

我要这张照片:

所以即使这个问题有明确的答案,也帮不了你。

您提到您正在阅读的图像是灰度图像,getRGB returns 值如 2324123551

这意味着您的图片使用 CS_GRAY ColorSpace, not an RGB color space. You can confirm this by calling getType(), which would return TYPE_USHORT_GRAY.

这意味着您的 p 值是 0 - 65535 范围内的灰度级。由于您希望结果是 0 - 255 范围内的 double,因此您需要计算:

double avg = p * 255.0 / 65535.0;

除非您 100% 确定输入图像 始终 为灰度,否则您应该检查代码中的类型并相应地处理 p 值。