【问题标题】:How to get 0..255 colors from a picture in Java? [duplicate]如何从 Java 中的图片中获取 0..255 种颜色? [复制]
【发布时间】:2020-05-15 01:31:52
【问题描述】:

我尝试对已经是黑白灰色的图片进行灰度化,然后它变成了黑色。

当我尝试使用 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;
        }
    }

我会得到这张照片:

因此,即使这个问题有一个明确的答案,它仍然对你没有帮助。

【问题讨论】:

  • addToEntry(countRows, 0, avg)??你的意思是addToEntry(y, x, avg)吗?
  • @Andreas 不抱歉。我正在使用 Apache Common Math 库将 0..255 值保存到列矩阵中。
  • 矩阵开始时所有单元格的值为 0(黑色)。 addToEntry(int row, int column, double increment) 将增加给定单元格的值。由于您对给定图像行中的所有像素使用 column = 0 调用它,因此 第一个单元格 在多次溢出后会以某个值结束,并且该行中的所有其余单元格都保持 0(黑色)。
  • @DanielMårtensson 那么也许你应该编辑这个问题并澄清,因为我显然不是唯一一个错过了矩阵是一个向量。
  • @DanielMårtensson 我刚刚测试了你的代码,它对我来说工作得很好。我通过该方法放置了一个测试图像,结果RealMatrx 包含0到255之间的值。我还将结果avg写回图像并保存,结果是黑白版本的原图。

标签: java image grayscale


【解决方案1】:

您提到您正在阅读的图像是灰度图像,并且getRGB 返回的值类似于2324123551

这意味着您的图像使用 CS_GRAY ColorSpace,而不是 RGB 颜色空间。您可以通过调用getType() 来确认这一点,这将返回TYPE_USHORT_GRAY

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

double avg = p * 255.0 / 65535.0;

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

【讨论】:

  • 很好奇,因为当我使用 OPs 图像和他的代码时,它对我有用。他还得到了像-1-6908266这样的值,它们在RGB空间中分别是#FFFFFF#969696
  • @Marv 请参阅duplicate answer,其中提到了-1 问题。
  • 很好,但我得到了负值,因为我的 p 是负值。而p 的值根本不是 8 位的。
  • 这里所有。此 MATLAB 代码射出 0..255 github.com/bytefish/facerec/blob/…
  • @Andreas 对不起。但不能将DataBuffer 转换为DataBufferUShort
猜你喜欢
  • 2013-03-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多