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

jw1400: <p>Hello all,</p>
<p>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.</p>
<p>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?</p>
<p>Best regards</p>

Matias_Vasquez: <p>Hi,</p>
<p>in your description of the problem and your approached solution you have two different things.</p>
<h2><a name="h-0-255-1" class="anchor" href="#h-0-255-1"></a>0 → 255</h2>
<aside class="quote no-group" data-username="jw1400" data-post="1" data-topic="150565">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/jw1400/48/45317_2.png" class="avatar"> jw1400:</div>
<blockquote>
<p>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</p>
</blockquote>
</aside>
<pre data-code-wrap="python"><code class="lang-python"># 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.]])
</code></pre>
<h2><a name="h-255-0-2" class="anchor" href="#h-255-0-2"></a>255 → 0</h2>
<aside class="quote no-group" data-username="jw1400" data-post="1" data-topic="150565">
<div class="title">
<div class="quote-controls"></div>
<img loading="lazy" alt="" width="24" height="24" src="https://discuss.pytorch.org/user_avatar/discuss.pytorch.org/jw1400/48/45317_2.png" class="avatar"> jw1400:</div>
<blockquote>
<p>That way the result would be 0 if atleast one of the pixels value in the 3x3 neighborhood was 0</p>
</blockquote>
</aside>
<pre data-code-wrap="python"><code class="lang-python"># 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.]])
</code></pre>
<h2><a name="if-you-mean-the-first-approach-0-255-3" class="anchor" href="#if-you-mean-the-first-approach-0-255-3"></a>If you mean the first approach 0 → 255</h2>
<p>You can do something like this</p>
<pre data-code-wrap="python"><code class="lang-python"># 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)
</code></pre>
<pre data-code-wrap="python"><code class="lang-python"># 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&gt;0] = value
</code></pre>
<p>Please let me know if what you want is actually the other thing <code>255 -&gt; 0</code><br>
Hope this helps <img src="https://discuss.pytorch.org/images/emoji/apple/smile.png?v=12" title=":smile:" class="emoji" alt=":smile:" loading="lazy" width="20" height="20"></p>

jw1400: <p>The first approach was what I was looking for. I should have explained that a little bit better.</p>
<p>Thanks for your work, that’s exactly what I needed!</p>