#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:
Хорошо, вот решение, к которому я пришел.
- Я преобразовал весь свой массив [][] в объект 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; }
- Применил аффинное преобразование с использованием AffineTransformOp с бикубической интерполяцией
AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BICUBIC); BufferedImage im_transformed = op.filter(im_src, null);
- Преобразовал объект 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; }