How to find exact displacement of each pixel after using torch.nn.functional.grid_sample()

Viewed 190

I have input image and grid passed in torch.nn.functional.grid_sample(). Now if I have a random pixel location (x, y) from the input image, how can I find out its location in the output of grid_sample(). To be precise I am looking for the delta of each pixel in terms of coordinates.

Would this be sufficient for finding new location of pixel: ix = ((ix + 1) / 2) * (IW-1); iy = ((iy + 1) / 2) * (IH-1); as mentioned in https://github.com/pytorch/pytorch/blob/f064c5aa33483061a48994608d890b968ae53fb5/aten/src/THNN/generic/SpatialGridSamplerBilinear.c

1 Answers

How did you compute the grid? It must be based on some transform. Often, the affine_grid function is used. And this function takes the transformation matrix as input. Given this transformation matrix (and its inverse), you can go in both directions: from input image pixel location to output image pixel location, and the other way round.

Here a sample code showing how to compute the transforms both for forward and backward direction. In the last line you see how to map a pixel location in both directions.

import torch
import torch.nn.functional as F

# given a transform mapping from output to input, create the sample grid
input_tensor = torch.zeros([1, 1, 2, 2])  # batch x channels x height x width
transform = torch.tensor([[[0.5, 0, 0], [0, 1, 3]]]).float()
grid = F.affine_grid(transform, input_tensor.size(), align_corners=True)

# show the grid
print('GRID')
print('y', grid[0, ..., 0])
print('x', grid[0, ..., 1])

# compute both transformation matrices (forward and backward) with shape 3x3
print('TRANSFORM AND INVERSE')
transform_full = torch.zeros([1, 3, 3])
transform_full[0, 2, 2] = 1
transform_full[0, :2, :3] = transform
transform_inv_full = torch.inverse(transform_full)
print(transform_full)
print(transform_inv_full)

# map pixel location x=2, y=3 in both directions (forward and backward)
print('TRANSFORMED PIXEL LOCATIONS')
print(transform_full@torch.tensor([[2, 3, 1]]).float().T)
print(transform_inv_full@torch.tensor([[2, 3, 1]]).float().T)
Related