gpt4 book ai didi

16 位数据双线性插值的 Java 错误

转载 作者:塔克拉玛干 更新时间:2023-11-03 03:00:54 27 4
gpt4 key购买 nike

我在对 16 位数据使用双线性插值时遇到问题。我有两个图像,origImage 和 displayImage。我想使用 AffineTransformOp 通过 AffineTransform 将 origImage 过滤为显示区域大小的 displayImage。 origImage 的类型为 BufferedImage.TYPE_USHORT_GRAY 并且栅格类型为 sun.awt.image.ShortInterleavedRaster。这是我现在的代码

displayImage = new BufferedImage(getWidth(), getHeight(), origImage.getType());
try {
op = new AffineTransformOp(atx, AffineTransformOp.TYPE_BILINEAR);
op.filter(origImage, displayImage);
}
catch (Exception e) {
e.printStackTrace();
}

为了显示错误,我创建了 2 个渐变图像。一个值在 15 位范围内(最大值为 32767),一个值在 16 位范围内(最大值为 65535)。下面是两张图片

15 位图像 alt text

16 位图像 alt text

这两个图像以相同的方式创建,看起来应该相同,但请注意 16 位图像中间的线条。起初我以为这是一个溢出问题,但是奇怪的是它出现在渐变的中心而不是像素值较高的末端。此外,如果这是一个溢出问题,我怀疑 15 位图像也会受到影响。

如有任何帮助,我们将不胜感激。

我只是想知道为什么没有人回答,我是否提供了足够的信息?需要更多信息吗?

下面是我用来生成仿射变换的代码。所有引用的变量都是根据用户输入(鼠标移动)计算的,应该是正确的(已经过很多人测试,包括我自己)。希望这可以帮助解决错误。

AffineTransform panTranslate = new AffineTransform();
panTranslate.translate(imagePanOffset.x, imagePanOffset.y);

AffineTransform rotateCenterTranslate = new AffineTransform();
rotateCenterTranslate.translate(imageRotateCTR.x, imageRotateCTR.y);
AffineTransform rotateTransform = new AffineTransform();
rotateTransform.rotate(Math.toRadians(rotateValue));
AffineTransform rotateAntiCenterTranslate = new AffineTransform();
rotateAntiCenterTranslate.translate(-imageRotateCTR.x, -imageRotateCTR.y);

AffineTransform translateTransform = new AffineTransform();
translateTransform.translate(imageMagOffset.x, imageMagOffset.y);

AffineTransform flipMatrixTransform = new AffineTransform();

switch (flipState) {
case ENV.FLIP_NORMAL: // NORMAL
break;

case ENV.FLIP_TOP_BOTTOM: // FLIP
flipMatrixTransform.scale(1.0, -1.0);
flipMatrixTransform.translate(0.0, -h);
break;

case ENV.FLIP_LEFT_RIGHT: // MIRROR
flipMatrixTransform.scale(-1.0, 1.0);
flipMatrixTransform.translate(-w, 0.0);
break;

case ENV.FLIP_TOP_BOTTOM_LEFT_RIGHT: // FLIP+MIRROR
flipMatrixTransform.scale(-1.0, -1.0);
flipMatrixTransform.translate(-w, -h);
break;
}

scaleTransform = new AffineTransform();
scaleTransform.scale(magFactor, magFactor);

AffineTransform atx = new AffineTransform();
atx.concatenate(panTranslate);
atx.concatenate(rotateCenterTranslate);
atx.concatenate(rotateTransform);
atx.concatenate(rotateAntiCenterTranslate);
atx.concatenate(translateTransform);
atx.concatenate(flipMatrixTransform);
atx.concatenate(scaleTransform);

我仍然不知道这里发生了什么。如果能提供任何帮助,我将不胜感激。我还附上了我遇到的真实图像中发生的错误示例,以供更多引用。

这是手部 X 光片中出现的错误 alt text

这是一个放大的版本,重点是拇指和食指之间的区域。 alt text

请再次注意错误并没有出现在极白的区域,而是出现在动态范围中间的值上,就像在渐变图像中一样。

我发现了更多信息。我正在调整一些转换,发现如果我只是通过单位矩阵进行过滤,则不会出现错误。如果我按整数翻译,它也不会发生。如果我按非整数翻译,它确实会发生。如果我缩放 1 以外的任何数量(整数或非整数),也会发生这种情况。希望这会有所帮助。

经过更多实验后,错误肯定会出现在最大强度一半 (65535/2 = 32767.5) 之间的边界像素处。它也只出现在这个值。我希望这可能有助于诊断!!

应 AlBlue 的要求,这里的代码完全独立于我的应用程序,可以生成错误。请注意,在原始帖子中,我包含了一个使用以下代码生成的图像渐变,但是我放大了其中一个渐变以更好地显示效果。您应该在 0.5 转换后的图像上看到四次效果,而不是在其他两个图像中的任何一个上。另请注意,此错误会在按 1 以外的任何数量缩放时出现。只需将 AffineTransform.getTranslateInstance() 替换为 AffineTransform.getScaleInstance(0.9, 0.9) 即可查看此错误。

private static class MyJPanel extends JPanel {
BufferedImage displayImage = null;
public MyJPanel(double translateValue) {
super();
BufferedImage bi = new BufferedImage(1024, 1024, BufferedImage.TYPE_USHORT_GRAY);

int dataRange = (int)Math.pow(2, 16);
double step = dataRange/(bi.getRaster().getDataBuffer().getSize()/4.0);
double value = 0;
for (int i=0; i<bi.getRaster().getDataBuffer().getSize(); i++) {
bi.getRaster().getDataBuffer().setElem(i, (int)value);
if (value >= dataRange)
value = 0;
else
value += step;
}
displayImage = new BufferedImage(bi.getWidth(), bi.getHeight(), bi.getType());
AffineTransform tx = AffineTransform.getTranslateInstance(translateValue, translateValue);
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR);
op.filter(bi, displayImage);
}

public void paint(Graphics g) {
super.paint(g);
g.drawImage(displayImage, 0, 0, this);
}
}

private static void showDisplayError() {
JDialog dialog1 = new JDialog();
dialog1.setTitle("No Translation");
MyJPanel panel1 = new MyJPanel(0);
dialog1.getContentPane().add(panel1);
dialog1.setSize(1024, 1024);
dialog1.setVisible(true);

JDialog dialog2 = new JDialog();
dialog2.setTitle("Translation of 0.5");
MyJPanel panel2 = new MyJPanel(0.5);
dialog2.getContentPane().add(panel2);
dialog2.setSize(1024, 1024);
dialog2.setVisible(true);

JDialog dialog3 = new JDialog();
dialog3.setTitle("Translation of 1.0");
MyJPanel panel3 = new MyJPanel(1.0);
dialog3.getContentPane().add(panel3);
dialog3.setSize(1024, 1024);
dialog3.setVisible(true);
}

作为另一个更新,我刚刚在 Fedora 10 上尝试了这个,发现错误仍然存​​在。

最佳答案

您使用的是什么版本的 java (java -version) 和操作系统?它可能是转换中的错误(此后已修复),也可能是渲染到 PNG 时的错误。

您是否尝试过使用 NEAREST_NEIGHBOR 过滤器而不是 BILINEAR 过滤器?

关于16 位数据双线性插值的 Java 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2428109/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com