Skip to content
Advertisement

Removing pixels surrounded by white pixels OpenCV

I have a black and white image which has a lot of noise. I would like to remove only black pixels that are completely surrounded by white ones. I tried doing so with Filter2d, but I could not achieve it.

Advertisement

Answer

I’d use a convolution (again) 1:

>>> import numpy as np
>>> from scipy.signal import convolve2d
>>> 
>>> kernel = np.ones((3,3))
>>> kernel[1,1] = 0
>>> print(kernel)
[[ 1.  1.  1.]
 [ 1.  0.  1.]
 [ 1.  1.  1.]]
>>> # Create a decent test array that shows the features
... test = np.array(
...     [[0,1,1,0,1,1],
...      [1,1,1,1,1,0],
...      [1,0,1,1,0,1],
...      [1,1,1,0,0,0],
...      [1,1,1,0,1,0],
...      [1,1,1,0,0,0]])
>>> 
>>> mask = convolve2d(test, kernel, mode='same', fillvalue=1)
>>> print(mask)
[[ 8.  7.  7.  8.  6.  7.]
 [ 6.  6.  6.  6.  5.  7.]
 [ 7.  8.  6.  5.  4.  4.]
 [ 7.  7.  5.  5.  3.  5.]
 [ 8.  8.  5.  4.  0.  4.]
 [ 8.  8.  6.  6.  4.  6.]]
>>> result = test.copy()
>>> result[np.logical_and(mask==8, test==0)] = 1
>>> print(result)
[[1 1 1 1 1 1]
 [1 1 1 1 1 0]
 [1 1 1 1 0 1]
 [1 1 1 0 0 0]
 [1 1 1 0 1 0]
 [1 1 1 0 0 0]]

As you can see, the result array has changed all “black” pixels (here represented by the value of 0) that were completely surrounded by white (represented by ones) on all 8 sides, even in the corners and on the edges.

Edit: Hugo Rune’s answer is better though if you have “pepper” noise, which means you’d have small groups of black pixels that are surrounded by white pixels and not just single pixels. For single pixels, which is how I interpreted your question, the above will work fine.

Footnote:

1: Actually you’d need a correlation, but in this case it is the same, because the kernel is symmetric.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement