2011-10-22 125 views
3

我想对极低分辨率的位图进行仿射变换,我希望在保留最大量的信息的同时进行仿射变换。插值仿射变换

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

我的问题是,鉴于输入图像和我的计算仿射变换矩阵,我怎么能计算出最高品质我的输出图像?我已经阅读了关于不同插值技术的文章,但他们都是关于如何进行插值的缩放,而不是一般的仿射变换。

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

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

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

你能联系我到一些源代码教程文章,甚至可能有关如何实现一个线性,三次或更好的插值与仿射转变?

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

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

+3

您可以使用java2d api在java中使用反锯齿进行仿射变换 – Sibbo

+0

您是否考虑过使用比标准位图图像好得多的SVG图像? Apache的[Batik库](http://xmlgraphics.apache.org/batik/)与Java协同工作,可以为你处理这个问题,我相信。 –

+0

@sibbo:这有助于Shapes,但对位图图像无帮助。 –

回答

0

好的,这里是我结束的解决方案。

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

你链接的同一个人有一个C实现与几个插值选项here。你可以用JNI来包装它。还有JavaCV,它包装OpenCV。 OpenCV包含warpAffine,它具有插值。另外,请查看Java Advanced Imaging API here