双线性插值

4

我收到了一段使用双线性插值缩放图像的代码。我知道这段代码是可行的,但有一件事情我想不明白:如果所估计的像素值是输入图像中的边缘像素(即在最后一行或最后一列),那么我怎么能得到坐标为(x+1,y+1)的像素,这应该会导致数组索引超出范围错误,但实际上并没有发生这样的错误,为什么呢? 以下是代码:

public int[] resizeBilinearGray(int[] pixels, int w, int h, int w2, int h2) {
    int[] temp = new int[w2*h2] ;
    int A, B, C, D, x, y, index, gray ;
    float x_ratio = ((float)(w-1))/w2 ;
    float y_ratio = ((float)(h-1))/h2 ;
    float x_diff, y_diff, ya, yb ;
    int offset = 0 ;
    for (int i=0;i<h2;i++) {
        for (int j=0;j<w2;j++) {
            x = (int)(x_ratio * j) ;
            y = (int)(y_ratio * i) ;
            x_diff = (x_ratio * j) - x ;
            y_diff = (y_ratio * i) - y ;
            index = y*w+x ;

            // range is 0 to 255 thus bitwise AND with 0xff
            A = pixels[index] & 0xff ;
            B = pixels[index+1] & 0xff ;
            C = pixels[index+w] & 0xff ;
            D = pixels[index+w+1] & 0xff ;

            // Y = A(1-w)(1-h) + B(w)(1-h) + C(h)(1-w) + Dwh
            gray = (int)(
                    A*(1-x_diff)*(1-y_diff) +  B*(x_diff)*(1-y_diff) +
                    C*(y_diff)*(1-x_diff)   +  D*(x_diff*y_diff)
                    ) ;

            temp[offset++] = gray ;                                   
        }
    }
    return temp ;
}

你试过使用 w=w2 h=h2 吗? - leonbloy
如果算法正确的话,它应该给出相同的图像。顺便说一下,这是Java语言。 - leonbloy
2个回答

6
原因是计算x_ratioy_ratio时出现错误。
考虑最后一行的最后一个像素:
i=h2, j=w2 

然后:
x = x_ratio * j = (w-1)/w2 * (w2-1) = (w-1) * (w2-1)/w2 <= w-1
y = y_ratio * i = (h-1)/h2 * (h2-1) = (h-1) * (h2-1)/h2 <= h-1

index = y*w+x <= (h-1)*w + (w-1) < w*h

因此,索引始终小于pixels数组的大小。


但请注意,这是一种非常不规范的方法,会导致结果不准确,特别是对于小图像。

您应该按照以下方式计算宽度/高度比:

float x_ratio = ((float)w)/w2;
float y_ratio = ((float)h)/h2;

创建一个函数将坐标转换为数组下标 - 我们称之为coord2index。该函数考虑到超出范围的坐标,并实现了所谓的边界选项,它模拟在图像边界外存在像素。

常见的边界选项包括:

  • 对称 - 在镜像反射图像边缘处计算图像边界外的像素。这可能是这种情况下最好的选择。

  • 复制 - 假定图像边界外的像素与边缘处最近的像素相等。这是最简单的方法。

  • 循环 - 图像在所有方向上被虚拟地周期性地重复。用于一些高级图像处理算法;不适用于图像调整大小。


你能提供一个更好的实现链接吗? - Alex_ban

0
我猜诀窍在于x_ratio = (float)(w-1))/w2,它计算的比率好像是原始图像比实际小一个像素。但我不确定这是否是万无一失和正确的(例如,当w=w2 h=h2时应该给出完全相同的图像)。我真的不喜欢这种方法。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接