双线性插值处理对图像进行上采样。它试图估计已知值之间的数组(例如图像)的值。例如,如果我有一张图像并且我想估计它在位置 (10.5, 24.5) 中的值,则该值将是四个邻居中的值的加权平均值:(10,24), (10,25) , (11,24), (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, 1, 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, 1, new_shape[1]), np.linspace(0, 1, new_shape[0]))
grid_mapping = [i * s for i, s in zip(grid, shape[::-1])]
- 生成 ax,y 网格,当 x 从 0 变为调整大小图像的宽度并且 y 从 0 变为新图像的高度时。现在,我们有了从新图像到原始图像的逆映射。
在 for 循环中,我们查看调整大小的图像中的每个像素,以及原始图像中它的来源。源不是整数而是浮点数(分数)。
现在我们取原始图像中映射的 x 和 y 周围的四个像素。例如,如果映射的 x,y 在 (17.3, 25.7) 中,我们将在像素中取原始图像的四个值:(17, 25), (17, 26), (18, 25), (18 , 26)。然后我们将应用您带来的方程式。
注意:
我添加了一个 try-except 因为我不想处理边界,但是您可以编辑代码来完成它。