I have a numpy array (data) consisting of 0 and 1.
import numpy as np
data = np.array([[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0],
[1, 1, **1**, 1, 1, 0],
[1, 1, 1, 1, 1, 1],
[1, 1, 1, 1, 1, 0],
[1, 1, 1, 1, 1, 1]])
I want to extract the indices where '1' is surrounded by neighboring 5*5 elements consisting of 1s.
The expected index is shown by asterisks, i.e, (3,3). An answer in the form of a boolean array is also okay.
[[False False False False False False]
[False False False False False False]
[False False **True** False False False]
[False False False False False False]
[False False False False False False]
[False False False False False False]]
I tried as
from scipy.ndimage.morphology import binary_erosion
kernel = np.ones((5,5))
result = binary_erosion(data, kernel)
print result
[[False False False False False False]
[False False False False False False]
[False False True False False False]
[False False True False False False]
[False False False False False False]
[False False False False False False]]
It produced two 'True' positions but I want only one at (3,3).
How to do it?
EDIT: The solution shown in the linked question too gives the unexpected answer.
Alternatively to
binary_erosion
, you could use thescipy.ndimage.generic_filter
to achieve this,However you would obtain the same results as above,
because it is the correct answer to your question. The 6 rows in your example matrix are symmetric, and with the given kernel, there would be 2 symmetric
True
element in the result.If you want to avoid this, you could use a non symmetric-kernel size:
size=(6,5)
, although this produces one true element in row 3 not row 2. This could be fixed, manually padding thekernel
array with zeros when usingbinary_erosion
.