由于二者有一定共通之处,因此放在一篇文章内介绍。
该函数的作用是在图像/体素空间中采样特征。
变量名 | 数据类型 | 默认值 | 含义 | 备注 |
---|---|---|---|---|
input | Tensor | - | 原始图像/体素空间的特征 | 形状需为(B,C,H,W)(B,C,H,W)(B,C,H,W)或(B,C,D,H,W)(B,C,D,H,W)(B,C,D,H,W),分别表示在图像中采样特征和在3D体素空间中采样特征 |
grid | Tensor | - | 采样图像/体素空间的归一化坐标 | 形状需为(B,h,w,2)(B,h,w,2)(B,h,w,2)(对应4维input的情况)或(B,d,h,w,3)(B,d,h,w,3)(B,d,h,w,3)(对应5维input的情况),具体见1.2节 |
mode | str | ‘bilinear’ | 采样特征的插值方式 | 可为’bilinear’(双线性插值)、‘nearest’(最近邻插值)、‘bicubic’(双三次插值) |
padding_mode | str | ‘zeros’ | 图像/体素空间外侧填充方式 | 可为’zeros’(零填充)、‘border’(边界值填充)或’reflection’(反射填充,详见官方介绍) |
align_corners | bool | False | 是否将像素看作点而非方块 | False表示将像素看作方块,而True表示将像素看作点(具体见1.2节) |
返回值 | Tensor | 返回值 | 采样得到的特征图 | 形状为(B,C,h,w)(B,C,h,w)(B,C,h,w)(对应4维input的情况)或(B,C,d,h,w)(B,C,d,h,w)(B,C,d,h,w)(对应5维input的情况) |
以4维输入(即从图像采样特征)为例,设图像的大小为(H,W)(H,W)(H,W)。
a = torch.arange(12, dtype=torch.float).reshape(3,4).unsqueeze(0).unsqueeze(0) # (1,1,3,4)
grid = torch.tensor([[[-0.25,-1.0], [1.0,-1.0]],[[-1.0, 1.0], [1.0, 1.0]]]).unsqueeze(0) # (1,2,2,2)
out = F.grid_sample(a, grid=grid, padding_mode='border') # (1,1,2,2)
# 输出a:
# tensor([[[[ 0., 1., 2., 3.],
# [ 4., 5., 6., 7.],
# [ 8., 9., 10., 11.]]]])
# 输出out:
# tensor([[[[ 1., 3.],
# [ 8., 11.]]]])
# 我们只关注采样的左上角元素,坐标为(-0.25,-1.0),对应上左图中的第一行第二个格子的顶部中心,
# 在双线性插值、边界值填充的情况下采样特征就是该像素的特征1。
a = torch.arange(12, dtype=torch.float).reshape(3,4).unsqueeze(0).unsqueeze(0) # (1,1,3,4)
grid = torch.tensor([[[[-0.25, -1.0, -1.0], [1.0, -1.0, -1.0]],[[ -1.0, 1.0, 1.0], [1.0, 1.0, 1.0]]]]).unsqueeze(0) # (1,1,2,2,3)
out = F.grid_sample(a, grid=grid, padding_mode='border') # (1,1,1,2,2)
# 输出a:
# tensor([[[[[ 0., 1., 2., 3.],
# [ 4., 5., 6., 7.],
# [ 8., 9., 10., 11.]], # 第一层
#
# [[12., 13., 14., 15.],
# [16., 17., 18., 19.],
# [20., 21., 22., 23.]]]]]) # 第二层
# 输出out:
# tensor([[[[[ 1., 3.],
# [20., 23.]]]]])
# 我们只关注采样的左上角元素,前两个维度的坐标为(-0.25,-1.0),对应上左图中的第一行第二个格子的顶部中心;
# 而第三个维度的坐标为-1.0,对应最上层的最上部(自行想象3D体素空间)。在双线性插值、边界值填充的情况下,
# 采样特征就是该体素(最上层、第一行第二个体素)的特征1。
设图像的内参矩阵(3×43\times43×4)扩维为4×44\times44×4后的矩阵为I\textbf{I}I,相机坐标系中的点(3维)扩维到4维后的向量为p=(x,y,z,1)T\textbf{p}=(x,y,z,1)^Tp=(x,y,z,1)T,图像坐标系下的像素索引(可为小数)为(u,v)(u,v)(u,v),深度为ddd,则(ud,vd,d,1)T=I⋅p(ud,vd,d,1)^T=\textbf{I}\cdot\textbf{p}(ud,vd,d,1)T=I⋅p
下图所示为上述(u,v)(u,v)(u,v)被定义的坐标系以及像素的整数索引。
可见,应该对小数索引进行floor()操作,以找到其对应像素的整数索引。