Reputation: 4944
I am starting with a nxm boolean array, that defines regions- true if it is in the region, false if not. For example:
r = np.array([[ 0, 0, 1, 1, 1],
[ 0, 1, 1, 0, 0],
[ 0, 1, 1, 1, 0],
[ 1, 1, 1, 0, 0],
[ 1, 1, 0, 0, 0]])
The line between regions can be defined as an n-1 x m-1 array, which would represent a 'point' in between each set of four values. If all 4 surrounding values are the same, you are not on the edge between regions. If any of the 4 values are different, you are. For r above:
l = np.array([[ 1, 1, 1, 1],
[ 1, 0, 1, 1],
[ 1, 0, 1, 1],
[ 0, 1, 1, 0]])
Any thoughts on how this can be done efficiently? I have tried doing a diff in both directions, but this doubles up. Is there a 2D diff function? Some other way of doing this?
Upvotes: 2
Views: 2134
Reputation: 69182
An good answer's already selected, but I like solutions that are easy to write and understand so I'll still post this:
from scipy.signal import convolve2d
kernel = np.array(((1, 1), (1, 1)))
x = convolve2d(r, kernel, mode="valid") # sum all the neighboring values (and mode handles the boundary issues)
x[x==4] = 0 # set the elements that sum to 4 to zero (the ones that sum to 0 are already 0)
x[x>0] = 1 # anything greater than one is set to 1
[[1 1 1 1]
[1 0 1 1]
[1 0 1 1]
[0 1 1 0]]
Upvotes: 2
Reputation: 10781
This will do the test for points surrounded by True
,
tmp = r[1:] & r[:-1]
l = np.logical_not(tmp[:, 1:] & tmp[:, :-1])
Then you can do the test for points surrounded by False
the same way and combine them,
r = np.logical_not(r)
tmp = r[1:] & r[:-1]
l &= np.logical_not(tmp[:, 1:] & tmp[:, :-1])
print l.astype(int)
# [[1 1 1 1]
# [1 0 1 1]
# [1 0 1 1]
# [0 1 1 0]]
Upvotes: 6