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

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

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

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

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

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

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

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

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

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


person hyperknot    schedule 22.10.2011    source источник
comment
Вы можете выполнять аффинные преобразования со сглаживанием в java с помощью java2d api   -  person Sibbo    schedule 23.10.2011
comment
Думали ли вы об использовании изображений SVG, которые масштабируются намного лучше, чем стандартные растровые изображения? Библиотека Batik от Apache работает с Java и, я полагаю, может справиться с этим за вас.   -  person Hovercraft Full Of Eels    schedule 23.10.2011
comment
@sibbo: это помогает с фигурами, но не поможет с растровыми изображениями.   -  person Hovercraft Full Of Eels    schedule 23.10.2011
comment
вы тоже можете преобразовывать изображения   -  person Sibbo    schedule 23.10.2011
comment
@Sibbo: Я знаю, что вы можете преобразовывать изображения, но какой эффект, по вашему мнению, будут иметь подсказки рендеринга сглаживания для растровых изображений? Подскажу: нет. Есть и другие подсказки рендеринга, которые могут помочь некоторым, но все же вы остаетесь с неоднозначностью растровых данных, расширяемых до большего размера, обнажая их пределы разрешения.   -  person Hovercraft Full Of Eels    schedule 23.10.2011
comment
zsero: пожалуйста, посмотрите здесь достойное объяснение различных типов интерполяций, доступных при преобразовании растрового изображения: Обработка геометрических изображений. В частности, ознакомьтесь с разделом 8.2. Исходя из этого, пробовали ли вы настроить RenderingHints для использования одного из типов бикубической интерполяции, такого как INTERP_BICUBIC или INTERP_BICUBIC2?   -  person Hovercraft Full Of Eels    schedule 23.10.2011
comment
Спасибо за подсказку, я не знал, что реализация Java бикубическая! Я посмотрю на это!   -  person hyperknot    schedule 23.10.2011
comment
От Microsoft Research вышла замечательная статья о преобразовании пиксельной графики в векторную графику, если вас интересуют новые разработки: research.microsoft.com/en-us/um/people/kopf/pixelart/index.html   -  person vhallac    schedule 23.10.2011


Ответы (2)


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

person mevatron    schedule 22.10.2011

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

  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 в array [] []:

        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) & 0xFF;
                    red = (color >> 16) & 0xFF;
                    value = 1f - red / 255;
                    if (alpha == 0) {
                        array[y][x] = 0;
                    } else {
                        array[y][x] = value;
                    }
                }
            }
        }
        return array;
        }
    
person hyperknot    schedule 29.10.2011