[[ 0, 0, 0, 0, 255, 0, 0, 0, 0],
[ 0, 0, 255, 255, 255, 255, 255, 0, 0],
[ 0, 255, 255, 255, 255, 255, 255, 255, 0],
[ 0, 255, 255, 255, 255, 255, 255, 255, 0],
[255, 255, 255, 255, 255, 255, 255, 255, 255],
[ 0, 255, 255, 255, 255, 255, 255, 255, 0],
[ 0, 255, 255, 255, 255, 255, 255, 255, 0],
[ 0, 0, 255, 255, 255, 255, 255, 0, 0],
[ 0, 0, 0, 0, 255, 0, 0, 0, 0]]
I have a mask array like the one above. I would like to get the x and y coordinates belonging to the perimeter of the mask. The perimeter points are the ones shown in the array below:
[[ 0, 0, 0, 0, 255, 0, 0, 0, 0],
[ 0, 0, 255, 255, 0, 255, 255, 0, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[255, 0, 0, 0, 0, 0, 0, 0, 255],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 255, 0, 0, 0, 0, 0, 255, 0],
[ 0, 0, 255, 255, 0, 255, 255, 0, 0],
[ 0, 0, 0, 0, 255, 0, 0, 0, 0]]
In the array above, I could just use numpy.nonzero() but I was unable to apply this logic to the original array because it returns a tuple of arrays each containing all the x or y values of all non zero elements without partitioning by row.
I wrote the code below which works but seems inefficient:
height = mask.shape[0]
width = mask.shape[1]
y_coords = []
x_coords = []
for y in range(1,height-1,1):
for x in range(0,width-1,1):
val = mask[y,x]
prev_val = mask[y,(x-1)]
next_val = mask[y, (x+1)]
top_val = mask[y-1, x]
bot_val = mask[y+1, x]
if (val != 0 and prev_val == 0) or (val != 0 and next_val == 0) or (val != 0 and top_val == 0) or (val != 0 and bot_val == 0):
y_coords.append(y)
x_coords.append(x)
I am new to python and would like to learn a better way to do this. Perhaps using Numpy?