【问题标题】:Affine transform with interpolation带插值的仿射变换
【发布时间】:2011-12-13 08:06:21
【问题描述】:

我想在分辨率非常低的位图上进行仿射变换,并希望在保留最大信息量的同时进行。

我的输入数据是 1 位 64×64 像素的手写字符图像,我的输出将是灰度和更高分辨率。在分析图像后,我构建了一系列仿射变换(旋转、缩放、剪切、平移),我可以将它们相乘成一个仿射变换矩阵。

我的问题是,鉴于 输入图像 和我计算的 仿射变换矩阵,我怎样才能以尽可能高的质量计算我的输出图像?我读过有关不同插值技术的文章,但所有文章都是关于如何为缩放进行插值,而不是针对一般仿射变换。

这是一个演示,它正在做我正在寻找的东西。给定一个仿射变换矩阵和一个插值技术,它会计算出一幅图像。

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

如果我有较低分辨率的 1 位输入和给定的 T 仿射变换矩阵,您能解释一下计算更高分辨率(例如 4 倍)灰度图像所需的步骤吗?

你能把我链接到一些源代码教程文章 甚至可能是书籍,了解如何使用仿射变换实现线性、三次或更好的插值?

我需要在Java中实现这个问题,我知道Java有一个Affine类,但我不知道它是否实现了插值。你知道任何 C++ 或 Java 库,有什么好读的代码来弄清楚如何编写使用插值进行仿射变换的算法?

是否有任何免费的 Java 或 C++ 库,它们具有使用插值计算仿射变换的内置函数?

【问题讨论】:

  • 您可以使用 java2d api 在 java 中使用抗锯齿进行仿射变换
  • 您是否考虑过使用比标准位图图像缩放更好的 SVG 图像? Apache 的 Batik library 与 Java 一起工作,我相信可以为您处理这个问题。
  • @sibbo:对形状有帮助,但对位图图像没有帮助。
  • 你也可以变换图片
  • 微软研究院有一篇很棒的论文将像素艺术转换为矢量图形,如果您对新的发展感兴趣:research.microsoft.com/en-us/um/people/kopf/pixelart/index.html

标签: java c++ image-processing interpolation


【解决方案1】:

您链接到的同一个人拥有一个带有多个插值选项的 C 实现 here。您可能可以使用 JNI 来包装它。还有JavaCV,它封装了OpenCV。 OpenCV 包含带有插值的 warpAffine。另外,请查看Java Advanced Imaging API here

【讨论】:

    【解决方案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对象转回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;
          }
      

    【讨论】:

      猜你喜欢
      • 2010-12-17
      • 2020-03-19
      • 2013-07-04
      • 1970-01-01
      • 2016-01-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多