为了账号安全,请及时绑定邮箱和手机立即绑定

在java中区分16位和8位grascale图像

在java中区分16位和8位grascale图像

鸿蒙传说 2023-06-28 15:53:46
我正在尝试读取 .png 灰度图像并将灰度值转换为 double[][]数组。我需要将它们映射到 0 到 1 之间的值。我使用 BufferedImage,并且尝试找出使用的颜色深度,img.getColorModel().getColorSpace().getType()但返回了 TYPE_5CLR 或 TYPE_6CLR 通用组件颜色空间,这没有帮助。目前我正在读取这样的值:BufferedImage img = null;        try {            img = ImageIO.read(new File(path));        } catch (IOException e) {            return null;        }        double[][] heightmap= new double[img.getWidth()][img.getHeight()];        WritableRaster raster = img.getRaster();        for(int i=0;i<heightmap.length;i++)        {            for(int j=0;j<heightmap[0].length;j++)            {                heightmap[i][j]=((double) raster.getSample(i,j,0))/65535.0;            }        }如果 65535 是 8 位的话,它应该是 256,但我不知道什么时候。
查看完整描述

2 回答

?
蝴蝶刀刀

TA贡献1801条经验 获得超8个赞

我在评论中写道,您可以使用ColorModel.getNormalizedComponents(...),但由于它使用float值并且不必要的复杂,因此实现这样的转换可能会更容易:


BufferedImage img;

try {

    img = ImageIO.read(new File(path));

} catch (IOException e) {

    return null;

}


double[][] heightmap = new double[img.getWidth()][img.getHeight()];


WritableRaster raster = img.getRaster();


// Component size should be 8 or 16, yielding maxValue 255 or 65535 respectively

double maxValue = (1 << img.getColorModel().getComponentSize(0)) - 1;


for(int x = 0; x < heightmap.length; x++) {

    for(int y = 0; y < heightmap[0].length; y++) {

        heightmap[x][y] = raster.getSample(x, y, 0) / maxValue;

    }

}


return heightmap;

请注意,上面的代码仅适用于灰度图像,但这似乎是您的输入。所有颜色分量的分量大小可能相同 ( getComponentSize(0)),但 R、G 和 B(以及 A,如果有 alpha 分量)可能有单独的样本,并且代码将仅获取第一个样本 ( getSample(x, y, 0)) 。


xPS:为了清楚起见,我重命名了你的变量y。x如果交换高度图中的尺寸并在内循环中循环,则很可能会获得更好的性能,而不是y由于更好的数据局部性。


查看完整回答
反对 回复 2023-06-28
?
互换的青春

TA贡献1797条经验 获得超6个赞

如果您假设图像是灰度图像,则调用getRGB并除以其分量之一可能会更容易:

heightmap[i][j] = (img.getRGB(j, i) & 0xff) / 255.0;


查看完整回答
反对 回复 2023-06-28
  • 2 回答
  • 0 关注
  • 128 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信