双线性插值 [英] Bilinear interpolation

查看:122
本文介绍了双线性插值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我得到了这个用于通过双线性插值来缩放图像的代码。我知道这有效但我无法弄清楚如果近似像素值是边缘的话(通过边缘我的意思是它在最后一行或最后一列)输入图像中的像素然后我可以我坐标(x + 1,y + 1)的像素,这应该导致数组索引超出范围错误,但没有出现这样的错误为什么?
代码是:

I got this code for scaling image by bilinear interpolation.I know this works but i can't figure out one thing what if the approximated pixel value is an edge(by edge i mean it is in the last row or last column) pixel in the input image then i can i gt a pixel of coordinate (x+1,y+1) ,this should lead to a array index out of range error but no such error occurs why? The code is:

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 ;
}


推荐答案

原因是 x_ratio y_ratio 计算错误。

考虑最后一行的最后一个像素:

Consider the last pixel of the last row:

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

所以索引总是小于像素的大小数组。

so the index is always less than the size of the pixels array.

但是请注意,这是一个非常脏的黑客,这将导致不准确的结果,特别是对于小图像。

Note however, that this is a very dirty hack, which will result in inaccurate results, especially for small images.

您应该按如下方式计算宽度/高度比率:

You should calculate width/height ratio as follows:

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

并创建一个将坐标转换为数组索引的函数 - 让它命名为 coord2index 。此函数考虑了超出范围的坐标并实现了所谓的边界选项模拟图像边界外有像素。

and create a function which converts coordinates to array index - let's name it coord2index. This function takes out-of range coordinates into account and implements a so-called boundary option, which simulates that there are pixels outside the image boundary.

边界的常见选项是:


  • 对称 - 图像边界外的像素通过镜像反射边界处的图像来计算。在这种情况下,这可能是最好的可能性。

  • symmetric - pixels outside the image bounds are computed by mirror-reflecting the image at the border. This is probably the best possibility in this case.

复制 - 假设图像边界外的像素等于边界处的最近像素。这是最简单的方法。

replicate - pixels outside the image bounds are assumed to be equal to the nearest pixel at the border. This is the simplest way.

循环 - 图像几乎在所有方向上定期重复。用于一些先进的图像处理算法;不适合图像大小调整。

circular - the image is virtually repeated periodically in all directions. Used for some advanced image processing algorithms; not good for image resizing.

这篇关于双线性插值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆