pythonnumpypytorchpaddingcrop

How can I crop away a tensor’s constant value padding (padding height and width are the same) with an unknown value and size?


How can I crop away a tensor’s constant value padding (padding height and width are the same) with an unknown value and size?

I would think that because the padding surrounding my tensor has a constant value, and the same height / width, that it should be possible to know where to crop the tensor to remove the padding.

import torch

# Test tensor with NCHW dimensions
a = torch.randn(1,4,5,5) # Can have any H & W size

# Create padding for testing
b = torch.nn.functional.pad(a, (2,2,2,2), 'constant', value=1.2) # Value can be any number

c = # equal to a, without being able to use the variables a or b (or their argument values)

NumPy solutions are acceptable as I can easily convert them to PyTorch.

Edit:

pad = torch.where(b[0, 0] - b[0, 0, 0, 0] != 0)[0][0]

x_pad, y_pad = 0, 0
if (b.size(3) % 2) == 0:
    x_pad = 1
if (b.size(2) % 2) == 0:
    y_pad = 1
c = b[:, :, pad : -(pad + y_pad), pad : -(pad + x_pad)]

assert c == a

Solution

  • You can get an idea of the content of a feature map by taking its middle row and measure the padding by looking for the first element change:

    midrow = b[0, 0, b.shape[3]//2, :]
    pad = (midrow[:-1] == midrow[:1])[:midrow.shape[0]//2].sum()
    

    Alternatively you could substract one of the feature maps with the padding value and find the first non zero value, which would be the padding size:

    pad = torch.where(b[0,0] - b[0,0,0,0] != 0)[0][0]
    

    Having the padding, we can discard the right amount of values around the feature maps for all batch elements and all channels:

    a = b[:, :, pad:-pad, pad:-pad]