双线性插值的最近邻

时间:2016-02-24 12:10:01

标签: java algorithm graphics image-scaling

我目前正在开展一个项目,要求我阅读并放大图像。

我目前正在使用最近邻算法来放大我的图像,但我试图使用双线性插值并发现难以实现。

以下是我目前的NN算法:

public void doThumbnailResize() {
    resizedImage = new BufferedImage(55, 55, BufferedImage.TYPE_3BYTE_BGR); 
    int h = resizedImage.getHeight(), h2 = image1.getHeight();
    int w = resizedImage.getWidth(), w2 = image1.getWidth();
    for (int j = 0; j < h; j++) {
        for (int i = 0; i < w; i++) {
            float y = j * ((float) h2 / (float) h);
            float x = i * ((float) w2 / (float) w);
            resizedImage.setRGB(i, j, image1.getRGB((int) x, (int) y));
        }
    }
    image_icon.setIcon(new ImageIcon(resizedImage));        
}

我发现很难在网上找到资料,并且想知道是否有人能指出我正确的方向,也许还有一些伪代码。

提前致谢。

1 个答案:

答案 0 :(得分:0)

双线性插值基本上用于插值4像素的正方形。您首先要查找最近的邻居,即目标像素映射到哪个源像素,以及相对于该像素的位置。然后创建一个目标像素大小宽和高的框,并检查该框与哪些像素相交(最多为4)并计算该重叠与框大小的关系。然后将该百分比应用于颜色并添加到最终颜色。

示例:

假设我们有一个像这样的9x9图像(每个字符表示一个像素):

ABC
DEF
GHI

现在我们要将其放大到4x4并计算第一个像素(0/0)的插值:

  • 目标像素的相对大小为(3 / 4,3 / 4),即每个目标像素跨越源像素的宽度和高度0.75
  • 像素A跨越纹理坐标(0,0)到(0.333,0.333)
  • 我们的第一个目标像素的中心位于(0.125,0.125)(1 /宽* 0.5,1 /高* 0.5),因此目标框将跨越坐标(0.0,0.0)到(0.25,0.25)
  • 如您所见,我们的第一个目标像素完全位于源像素A内,从而获得A的颜色。

现在换第二个像素(1/0):

  • 第二个目标像素的中心位于(0.375,0.125),因此跨越坐标(0.25,0.0)到(0.5,0.25)
  • 如您所见,这将与源像素A,B,D和E
  • 重叠
  • 我们的目标框的面积是0.25 * 0.25 = 0.0625
  • 与A重叠的面积为(0.333-0.25)*(0.25-0)〜= 0.02075
  • 因此我们目标像素盒的大约33%与A
  • 重叠
  • B的重叠将是((0.5-0333)*(0.25-0))/ 0.0625~ = 67%
  • 因此,目标像素的颜色将是A的颜色的33%+ B
  • 的颜色的67%

让我们考虑另一个像素,这次(1/1):

  • A的重叠将是:((0.333 - 0.25)*(0.333 - 0.25))/ 0.0625~ = 11%
  • B的重叠为:((0.5-0.333)*(0.333 - 0.25))/ 0.0625~ = 22%
  • D的重叠为:((0.333 - 0.25)*(0.5-0.333))/ 0.0625~ = 22%
  • E的重叠为:((0.5-0.333)*(0.5-0.333))/ 0.0625~ = 45%
  • 目标像素(1/1)的颜色因此是11%A + 22%B + 22%D + 45%E