Ошибка Java на билинейной интерполяции данных на 16 битов

У меня есть проблема с помощью билинейной интерполяции для данных на 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 растровых изображений alt text

16 растровых изображений alt text

Эти два изображения были созданы идентичными способами и должны выглядеть идентичными, но заметить строку через середину 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);

Я все еще понятия не имею, что продолжается здесь. Я был бы очень признателен за любую справку, которая может быть обеспечена. Я также присоединил пример ошибки, происходящей в реальном изображении, с которым я встречаюсь для более ссылочного.

Вот ошибка, происходящая в Рентгеновском луче руки 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 и видел, что ошибка все еще присутствует.

10
задан 12 revs, 2 users 100% 23 March 2010 в 00:10
поделиться

2 ответа

Вы решили это? Вероятно, это вызвано неправильным использованием AffineTransformOp. Как вы создали AffineTransform atx? Если у меня есть это, я смогу реплицировать, чтобы помочь отладить.

Вы также можете посетить этот сайт . Он содержит много полезной информации об AffineTransformOp

0
ответ дан 4 December 2019 в 04:01
поделиться

Какую версию java (java -version) и ОС вы используете? Это может быть ошибка преобразования (которая с тех пор была исправлена) или ошибка рендеринга в PNG.

Вы пробовали использовать фильтр NEAREST_NEIGHBOR вместо BILINEAR?

2
ответ дан 4 December 2019 в 04:01
поделиться
Другие вопросы по тегам:

Похожие вопросы: