How can I calculate the abs of the difference between one value and its 8 surrounding values?

To be specific, I have a tensor of shape (300,300). I want to calculate the sum of the abs of difference of the current pixel and its surrounding 8 pixels.For example, if in the tensor T, T[1,2] = 1 and its surrounding 8 pixels are 0.8, 0.9, 1.0, 1.1, 1.2, 1.3, 1.4, 1.5, and the sum value should be 1.8. So there can be another (300,300) tensor according to it. For loop can be used, but it’s way too slow. Any help would be greatly appreciated!!

You can use torch fold function (https://pytorch.org/docs/stable/nn.html?highlight=fold#torch.nn.Fold) which allows you to slide a window with a custom function.

Thank you. I will try it!

The nn.Fold functions as conv2d, but I want the absolute difference value of each position. For example, [1, 2, 3] * [-1,2,-1].t() =0, but I want this to be 2. Is there any solution to it?

Say your tensor x is of shape [batch, 1, 300, 300]
You can do it by dividing the task in a few steps : difference, then abs, then sum

  1. Compute the differences, using a custom kernel that outputs the 8 differences, on 8 channels. This kernel would be of shape [8, 1, 3, 3] and would look something like this:

w = torch.FloatTensor([
[[-1, 0, 0], [0, 1, 0], [0, 0, 0]],
[[0, -1, 0], [0, 1, 0], [0, 0, 0]],
[[0, 0, -1], [0, 1, 0], [0, 0, 0]],
[[0, 0, 0], [-1, 1, 0], [0, 0, 0]],
[[0, 0, 0], [0, 1, -1], [0, 0, 0]],
[[0, 0, 0], [0, 1, 0], [-1, 0, 0]],
[[0, 0, 0], [0, 1, 0], [0, -1, 0]],
[[0, 0, 0], [0, 1, 0], [0, 0, -1]]
]).unsqueeze(1)

You can see that each of the 8 “filters” will compute the difference with one neighbor.
And with y = torch.nn.functional.conv2d(x, w), the tensor y is of shape [batch, 8, 298, 298].

  1. You want the absolute, so y = y.abs()

  2. Do the sum over the channels dimension : y = y.sum(dim=1, keepdim=True)

You get the desired y with the shape [batch, 1, 298, 298]

I’m not sure if using Unfold / Fold instead would be relevant.

It works! Thanks!!!