Searching for a pixel's value in a 3v3 neighborhood

Hello all,

I would like to search for a certain value (=255) within a 3x3 neighborhood of a selected pixel. If one or more pixels in that 3x3 neighborhood have that value, the selected pixel’s value should be changed to that value (=255) as well. This needs to be done for every pixel of the image.

Currently I am indexing through every single pixel asking for the value and performing a boolean operation. However, this leads to heavy performance issues. Can you tell me if there is a layer in pytorch that I can customize to meet my needs? I’ve thought about a layer that turns all pixels with value 255 to value 0 first and then just multiplies all neighborhood pixel values. That way the result would be 0 if atleast one of the pixels value in the 3x3 neighborhood was 0. Is there a smooth way in pytorch to implement this approach?

Best regards

Hi,

in your description of the problem and your approached solution you have two different things.

0 → 255

# Input
tensor([[  0.,   0.,   0.],
        [  0.,   0.,   0.],
        [  0.,   0., 255.]])
# Has at least one 255 value, turns into
tensor([[  0.,   0.,   0.],
        [  0., 255.,   0.],
        [  0.,   0., 255.]])

255 → 0

# Input
tensor([[255., 255., 255.],
        [255., 255., 255.],
        [255., 255.,   0.]])
# Has at least one 0, turns into
tensor([[255., 255., 255.],
        [255.,   0., 255.],
        [255., 255.,   0.]])

If you mean the first approach 0 → 255

You can do something like this

# Define a conv2d with custom kernel
conv = torch.nn.Conv2d(1, 1, 3, padding=1, bias=False)
kernel = torch.ones(3, 3).unsqueeze(0).unsqueeze(0)
with torch.no_grad():
    conv.weight = torch.nn.Parameter(kernel)
# Create a copy of the image where everything that is NOT your value is 0
value = 255
masked_img = img.clone().unsqueeze(0).float()
masked_img[:, torch.logical_not(img==value)] = 0

# Pass your masked image through the conv2d
mask = conv(masked_img).squeeze()

# This new mask has 0 where every neighbor in a 3x3 window is 0 and a positive
#    value if the original value or any of the neighbors was 255.
#    If there are many 255 values inside the window, the result will be the sum.
#    We only care that it is a positive value, not how big.
img[mask>0] = value

Please let me know if what you want is actually the other thing 255 -> 0
Hope this helps :smile:

1 Like

The first approach was what I was looking for. I should have explained that a little bit better.

Thanks for your work, that’s exactly what I needed!

1 Like