У меня есть проблема с помощью билинейной интерполяции для данных на 16 битов. У меня есть два изображения, origImage и displayImage. Я хочу использовать AffineTransformOp для пропущения origImage через AffineTransform в 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 битов (макс. 32 767) и один в диапазоне на 16 битов (макс. 65 535). Ниже два изображения
15 растровых изображений
16 растровых изображений
Эти два изображения были созданы идентичными способами и должны выглядеть идентичными, но заметить строку через середину 16 растровых изображений. Сначала я думал, что это было водосливной проблемой однако, странно, что это проявляется в центре градиента вместо в конце, где пиксельные значения выше. Кроме того, если бы это была водосливная проблема, чем я подозревал бы, что 15 растровых изображений были бы затронуты также.
Любая справка на этом значительно ценилась бы.
Я просто задавался вопросом, почему никто не отвечает, я предоставлял достаточно информации? Больше информации необходимо?
Ниже код, который я использую для генерации AffineTransform. Все переменные, на которые ссылаются, вычисляются базирующиеся прочь ввода данных пользователем (движение мыши) и должны быть корректными (это было протестировано большим количеством людей включая меня). Надо надеяться, это может помочь с ошибкой.
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);
Я все еще понятия не имею, что продолжается здесь. Я был бы очень признателен за любую справку, которая может быть обеспечена. Я также присоединил пример ошибки, происходящей в реальном изображении, с которым я встречаюсь для более ссылочного.
Вот ошибка, происходящая в Рентгеновском луче руки
Вот является масштабируемый версией, сфокусированной на области между ползунком и первым пальцем.
Отметьте снова, как ошибка не происходит на чрезвычайно белых областях, но на значениях посреди динамического диапазона, точно так же, как в изображении градиента.
Я обнаружил больше информации. Я корректировал некоторые преобразования и нашел, что ошибка не происходит, если я просто проникаю в единичную матрицу. Также не происходит, перевожу ли я целочисленной суммой. Действительно происходит, перевожу ли я не целочисленной суммой. Также происходит, масштабирую ли я какой-либо суммой кроме 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 и видел, что ошибка все еще присутствует.
Вы решили это? Вероятно, это вызвано неправильным использованием AffineTransformOp. Как вы создали AffineTransform atx? Если у меня есть это, я смогу реплицировать, чтобы помочь отладить.
Вы также можете посетить этот сайт . Он содержит много полезной информации об AffineTransformOp
Какую версию java (java -version) и ОС вы используете? Это может быть ошибка преобразования (которая с тех пор была исправлена) или ошибка рендеринга в PNG.
Вы пробовали использовать фильтр NEAREST_NEIGHBOR вместо BILINEAR?