Аффинное преобразование с интерполяцией

#java #c #image-processing #interpolation

#java #c #обработка изображений #интерполяция

Вопрос:

Я хотел бы выполнить аффинное преобразование на растровом изображении с очень низким разрешением, и я хотел бы сделать это, сохранив максимальный объем информации.

Мои входные данные представляют собой 1-битное изображение размером 64 на 64 пикселя, написанное от руки, а мои выходные данные будут в оттенках серого и с более высоким разрешением. Проанализировав изображение, я строю серию аффинных преобразований (вращение, масштабирование, сдвиг, перемещение), которые я мог бы умножить на единую матрицу аффинных преобразований.

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

Вот демонстрация того, что делает именно то, что я ищу. Учитывая матрицу аффинного преобразования и метод интерполяции, он вычисляет изображение.

http://bigwww.epfl.ch/demo/jaffine/index.html

Можете ли вы объяснить мне, какие шаги требуются для вычисления изображения в оттенках серого с более высоким разрешением (например, 4x), если у меня 1-битный ввод с более низким разрешением и заданная T-аффинная матрица преобразования?

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

Мне нужно реализовать эту проблему в Java, и я знаю, что Java имеет аффинный класс, но я не знаю, реализует ли он интерполяцию. Знаете ли вы какую-нибудь библиотеку C или Java, в которой есть приятный для чтения код, чтобы выяснить, как написать алгоритм для выполнения аффинного преобразования с использованием интерполяции?

Существуют ли какие-либо свободно доступные библиотеки для Java или C , которые имеют встроенные функции для вычисления аффинного преобразования с использованием интерполяции?

Комментарии:

1. Вы можете выполнять аффинные преобразования со сглаживанием в Java с помощью java2d api

2. Рассматривали ли вы возможность использования SVG-изображений, которые масштабируются намного лучше, чем стандартные растровые изображения? Библиотека Batik от Apache работает с Java и, я полагаю, справится с этим за вас.

3. @sibbo: это помогает с формами, но не поможет для растровых изображений.

4. вы тоже можете трансформировать изображения

5. В Microsoft Research была потрясающая статья о преобразовании пиксельной графики в векторную графику, на случай, если вас интересуют новые разработки: research.microsoft.com/en-us/um/people/kopf/pixelart/index.html

Ответ №1:

Те же люди, с которыми вы связались, имеют реализацию C с несколькими вариантами интерполяции здесь. Вероятно, вы могли бы использовать JNI для его переноса. Существует также JavaCV, который обертывает OpenCV. OpenCV содержит warpafine, который имеет интерполяцию. Кроме того, ознакомьтесь с Java Advanced Imaging API здесь .

Ответ №2:

Хорошо, вот решение, к которому я пришел.

  1. Я преобразовал весь свой массив [][] в объект BufferedImage
     static BufferedImage BImageFrom2DArray(float data[][]) {
        int width = data.length;
        int height = data[0].length;
        BufferedImage myimage = new BufferedImage(width, height,  BufferedImage.TYPE_INT_RGB);
        for (int x = 0; x < width; x  ) {
            for (int y = 0; y < height; y  ) {
                int value = (int) ((1f - data[x][y]) * 255f);
                myimage.setRGB(y, x, (value << 16) | (value << 8) | value);
            }
        }
        return myimage;
    }
     
  2. Применил аффинное преобразование с использованием AffineTransformOp с бикубической интерполяцией
         AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BICUBIC);
        BufferedImage im_transformed = op.filter(im_src, null);
     
  3. Преобразовал объект BufferedImage обратно в массив[][]:
         static float[][] ArrayFromBImage(BufferedImage bimage, int width, int height) {
        int max_x = bimage.getWidth();
        int max_y = bimage.getHeight();
        float[][] array = new float[width][height];
        for (int x = 0; x < width; x  ) {
            for (int y = 0; y < height; y  ) {
                float red, alpha, value;
                int color;
                if (x >= max_x || y >= max_y) {
                    array[y][x] = 0;
                } else {
                    color = bimage.getRGB(x, y);
                    alpha = (color >> 24) amp; 0xFF;
                    red = (color >> 16) amp; 0xFF;
                    value = 1f - red / 255;
                    if (alpha == 0) {
                        array[y][x] = 0;
                    } else {
                        array[y][x] = value;
                    }
                }
            }
        }
        return array;
        }