来自维基百科的双线性插值

问题描述

我尝试阅读维基百科页面 https://en.wikipedia.org/wiki/Bilinear_interpolation 上的双线性插值,并且我已经实现了其中一种算法,我想知道我是否做得对。

这是我从页面实现的算法:

Bilinear interpolation from unit squre

这是我试图在代码中实现的:

for(int i = 0; i < w; i++) {
    for( int j = 0; j < h; j++) {
        new_img(i,j,0) = old_img(i,0)*(1-i)(1-j) + old_img(i+1,0)*i*(1-j) + old_img(i,j+1)*(1-i)*j + old_img(i+1,j+1,0)*i*j;
    }
}

这就是实现方式吗?

解决方法

双线性插值处理对图像进行上采样。它尝试在已知值之间估计数组(例如图像)的值。例如,如果我有一个图像并且我想估计它在位置 (10.5,24.5) 中的值,则该值将是四个邻居中值的加权平均值:(10,24),(10,25),(11,25) 是已知的。公式是您在问题中发布的方程式。

这是python代码:

    scale_factor = 0.7

    shape = np.array(image.shape[:2])
    new_shape = np.ceil(shape * scale_factor).astype(int)

    grid = np.meshgrid(np.linspace(0,1,new_shape[1]),np.linspace(0,new_shape[0]))
    grid_mapping = [i * s for i,s in zip(grid,shape[::-1])]

    resized_image = np.zeros(tuple(new_shape))
    for x_new_im in range(new_shape[1]):
        for y_new_im in range(new_shape[0]):
            mapping = [grid_mapping[i][y_new_im,x_new_im] for i in range(2)]
            x_1,y_1 = np.floor(mapping).astype(int)
            try:
                resized_image[y_new_im,x_new_im] = do_interpolation(f=image[y_1: y_1 + 2,x_1: x_1 + 2],x=mapping[0] - x_1,y=mapping[1] - y_1)
            except ValueError:
                pass


def do_interpolation(f,x,y):
    return np.array([1 - x,x]).dot(f).dot([[1 - y],[y]])

说明:
new_shape = np.ceil(shape * scale_factor).astype(int) - 重新缩放后计算新的图像形状。
grid = np.meshgrid(np.linspace(0,new_shape[0]))
grid_mapping = [i * s for i,shape[::-1])] - 生成 x,y 网格,当 x 从 0 到调整大小的图像的宽度并且 y 从 0 到新图像的高度时。现在,我们有了从新图像到原始图像的逆映射。
在 for 循环中,我们查看调整大小的图像中的每个像素,以及它在原始图像中的来源。来源不是整数而是浮点数(分数)。
现在我们取原始图像中映射 x 和 y 周围的四个像素。例如,如果映射的 x,y 在 (17.3,25.7) 中,我们将在像素中取原始图像的四个值:(17,(17,26),(18,26)。然后我们将应用您带来的等式。

注意:
我添加了一个 try-except 因为我不想处理边界,但您可以编辑代码来做到这一点。