Get Coordinates Of Squares In Numpy Matrix
Given the following numpy matrix import numpy as np np_matrix = np.array([[0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0] ,[0,0,0,0,0,
Solution 1:
Your output format is frankly pretty bizarre and requires reversing the order of indices a lot, (and makes the output fairly useless for indexing the original array) but this works:
def find_boxes(np_matrix):
np_mat = np_matrix[::-1, :] # reversed in expected output
def find_extent(arr, val):
xn = arr.size
x0 = np.flatnonzero(arr == 1)
xi = np.searchsorted(x0, val, side = 'right')
if xi == x0.size:
x1 = x0[xi-1]
x2 = xn - 1
elif xi == 0:
x1 = 0
x2 = x0[xi]
else:
x1 = x0[xi-1]
x2 = x0[xi]
return np.array([x1, x2])
green = np.where(np_mat == 2)
green = tuple(g[np.argsort(green[-1])] for g in green)
coords = np.empty((green[0].size, 2, 4))
for i, (x, y) in enumerate(zip(*green)):
coords[i, 0] = np.tile(find_extent(np_mat[x, :], y), 2)
coords[i, 1] = np.repeat(find_extent(np_mat[:, y], x)[::-1], 2) # reversed again
return np.stack(green)[::-1].T, coords.swapaxes(1,2).astype(int)
# reversed again and transposed
Testing:
find_boxes(np_matrix)
Out:
(array([[ 0, 0],
[ 7, 12],
[16, 27],
[29, 21],
[34, 7]], dtype=int32),
array([[[ 0, 6],
[ 2, 6],
[ 0, 0],
[ 2, 0]],
[[ 3, 14],
[ 9, 14],
[ 3, 7],
[ 9, 7]],
[[12, 31],
[23, 31],
[12, 24],
[23, 24]],
[[25, 22],
[32, 22],
[25, 15],
[32, 15]],
[[33, 13],
[35, 13],
[33, 0],
[35, 0]]]))
Solution 2:
Another method, which makes the four directions symetric :
rm = m[::-1].T # (j,-i) to (x,y)
green = np.where(rm==2) # the costly operation
centers = np.vstack(green).T
rm[green] = 0
res = []
for x,y in centers:
for s in (-1,1): # rear/frontfor t in range(2) : # vertical/horizontal
v = *_,save = rm[x,y::s]
v[-1] = 1 # sentinel
res.append(y + s*v.argmax()) # find the first 1
v[-1] = save
x,y,rm = y,x,rm.T # turn rm[green] = 2
coordinates = np.array(res).reshape(-1,4)
corners = coordinates.take([[1,2],[3,2],[1,0],[3,0]],axis=1)
This avoids to deal with the included/excluded behavior of Python slices, and manages borders with a sentinel system.
print(centers);print(corners)
[[ 0 0]
[ 7 12]
[16 27]
[29 21]
[34 7]]-----------[[[ 0 6]
[ 2 6]
[ 0 0]
[ 2 0]][[ 3 14]
[ 9 14]
[ 3 7]
[ 9 7]][[12 31]
[23 31]
[12 24]
[23 24]][[25 22]
[32 22]
[25 15]
[32 15]][[33 13]
[35 13]
[33 0]
[35 0]]]
Post a Comment for "Get Coordinates Of Squares In Numpy Matrix"