grid_sample()函数及双线性采样
1. grid_sample函数的接口声明
torch.nn.functional.grid_sample(input, grid, mode='bilinear', padding_mode='zeros', align_corners=None)
在官方文档里面关于该函数的作用是这样描述的:
Given an input and a flow-field grid, computes the output using input values and pixel locations from grid.
关于 input、grid 以及 output 的尺寸如下所示:
input: (N, C, $H_{in}$, $W_{in}$)
grid : (N, $H_{out}$, $W_{out}$, 2)
outinput: (N, C, $H_{out}$, $W_{out}$)
2. grid和input坐标转换
根据 grid 中每个位置提供的坐标信息 (grid的位置转换为 input 中 pixel 的坐标),将 input 中对应位置的像素值填充到 grid 指定的位置,得到最终的输出。关键的处理过程在于 grid,grid 的最后一维的大小为 2,即表示 input 中 pixel 的位置信息 (x,y), 这里一般会将 x 和 y 的取值范围归一化到 [-1,1] 之间,那如何对应在 input 上呢。这个来看一下 pytorch 的底层源码。
第 66 行到 71 行,获取到了 grid 的 x 和 y,之后对其做了新的变换,变到 input 的坐标系下了。IW 和 IH 是 input 的宽和高。
real ix = THTensor_fastGet4d(grid, n, h, w, 0);
real iy = THTensor_fastGet4d(grid, n, h, w, 1);
// normalize ix, iy from [-1, 1] to [0, IH-1] & [0, IW-1]
ix = ((ix + 1) / 2) * (IW-1);
iy = ((iy + 1) / 2) * (IH-1);
3. 线性插值
ix和iy有可能是小数那么函数将会根据参数_padding_mode_的设定进行不同的处理。
- padding_mode='zeros': 对于越界的位置在网格中采用 pixel value=0 进行填充。
- padding_mode='border': 对于越界的位置在网格中采用边界的 pixel value 进行填充。
- padding_mode='reflection': 对于越界的位置在网格中采用关于边界的对称值进行填充。
对于 mode='bilinear'参数,则定义了在 input 中指定位置的 pixel value 中进行插值的方法,为什么需要插值呢?因为前面我们说了,grid 中表示的位置信息 x 和 y 的取值范围在 [-1,1]之间,这就意味着我们要根据一个浮点型的坐标值在 input 中对 pixel value 进行采样,mode 有nearest和bilinear两种模式。 nearest 就是直接采用与 (x,y)距离最近处的像素值来填充 grid,而 bilinear 则是采用双线性插值的方法来进行填充,总之其与 nearest 的区别就是 nearest 只考虑最近点的 pixel value,而 bilinear 则采用(x,y)周围的四个 pixel value 进行加权平均值来填充 grid。
参考资料
https://zhuanlan.zhihu.com/p/112030273
https://blog.csdn.net/qq_34914551/article/details/107559031

浙公网安备 33010602011771号