author:张一极
date:2024年01月08日20:27:05
图像处理中,双线性插值是一种常见的像素值推断方法。它在图像缩放、旋转、变换以及图像重构等领域有着广泛的应用。本文将深入探讨双线性插值的计算原理以及其优缺点。
双线性插值是一种基于局部像素邻域的插值方法,用于估算在离散网格上某一处的像素值。它利用了最接近目标位置的四个邻近像素的信息进行估算。
插值的计算步骤如下:
举个例子:
我们要计算,下列像素中,坐标为[0.5,0.5]的双线性插值
则计算为x 方向做线性插值,再做 y 方向的线性插值,由于0.5 介于 0 和 1 之间,[0.5,0.5]处于四个颜色的正中心,所以他的计算为:
四个颜色相加,并除以 4,得到中心插值颜色。
code:
def bilinear_sampler(imgs, coords):
coords_x, coords_y = torch.split(coords, [1, 1], dim=3)
inp_size = imgs.size()
coord_size = coords.size()
out_size = list(coord_size)
out_size[3] = imgs.size()[3]
coords_x = coords_x.float()
coords_y = coords_y.float()
x0 = torch.floor(coords_x)
x1 = x0 + 1
y0 = torch.floor(coords_y)
y1 = y0 + 1
y_max = torch.tensor([imgs.size()[1] - 1], dtype=torch.float32).to(coords.device) # y_max as tensor
x_max = torch.tensor([imgs.size()[2] - 1], dtype=torch.float32).to(coords.device) # x_max as tensor
zero = torch.tensor([0.0], dtype=torch.float32).to(coords.device) # zero as tensor
x0_safe = torch.clamp(x0, zero, x_max)
y0_safe = torch.clamp(y0, zero, y_max)
x1_safe = torch.clamp(x1, zero, x_max)
y1_safe = torch.clamp(y1, zero, y_max)
wt_x0 = x1_safe - coords_x
wt_x1 = coords_x - x0_safe
wt_y0 = y1_safe - coords_y
wt_y1 = coords_y - y0_safe
dim2 = imgs.size()[2]
dim1 = imgs.size()[2] * imgs.size()[1]
base = _repeat(torch.arange(coord_size[0]).float() * dim1, coord_size[1] * coord_size[2]).view(out_size[0], out_size[1], out_size[2], 1)
base_y0 = base + y0_safe * dim2
base_y1 = base + y1_safe * dim2
idx00 = (x0_safe + base_y0).view(-1).long()
idx01 = (x0_safe + base_y1).view(-1).long()
idx10 = (x1_safe + base_y0).view(-1).long()
idx11 = (x1_safe + base_y1).view(-1).long()
imgs_flat = imgs.view(-1, inp_size[3]).float()
im00 = imgs_flat[idx00].view(out_size)
im01 = imgs_flat[idx01].view(out_size)
im10 = imgs_flat[idx10].view(out_size)
im11 = imgs_flat[idx11].view(out_size)
w00 = wt_x0 * wt_y0
w01 = wt_x0 * wt_y1
w10 = wt_x1 * wt_y0
w11 = wt_x1 * wt_y1
output = w00 * im00 + w01 * im01 + w10 * im10 + w11 * im11
return output