我想在非常低分辨率的位图上进行仿射变换,我希望在保留最大量信息的同时进行仿射转换。
我的输入数据是手写字符的1位64×64像素图像,我的输出将是灰度和更高分辨率。在分析图像后,我构建了一系列仿射变换(旋转,缩放,剪切,平移),这些变换可以乘以单个仿射变换矩阵。
我的问题是,鉴于输入图像和我计算的仿射变换矩阵,如何以最高质量计算输出图像?我读过有关不同插值技术的文章,但所有这些都是关于如何进行缩放插值,而不是一般的仿射变换。
这是一个演示正是我正在寻找的东西。给定仿射变换矩阵和插值技术,它计算图像。
http://bigwww.epfl.ch/demo/jaffine/index.html
如果我有一个较低分辨率的1位输入和一个给定的T仿射变换矩阵,你能解释一下计算更高分辨率(例如4x)灰度图像所需的步骤吗?
您可以将我链接到 源代码 或 教程 或 文章< / em> 甚至可能 书籍 关于如何使用仿射变换实现线性,立方或更好的插值?
我需要在Java中实现这个问题,我知道Java有一个Affine类,但我不知道它是否实现了插值。你知道任何C ++或Java库有什么好看的代码来弄清楚如何使用插值来编写一个算法来进行仿射变换吗?
是否有免费的Java或C ++库,它们具有使用插值计算仿射变换的内置函数?
答案 0 :(得分:1)
您链接的同一个人拥有带有多个插值选项here的C实现。您可以使用JNI来包装它。还有JavaCV,它包含了OpenCV。 OpenCV包含warpAffine,它有插值。另外,请查看Java Advanced Imaging API here。
答案 1 :(得分: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;
}
使用AffineTransformOp和插值双三次
应用仿射变换 AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BICUBIC);
BufferedImage im_transformed = op.filter(im_src, null);
将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;
}