I want to calculate the perimeter of a given numpy array structure. With perimeter i mean the exact perimeter of the structure in the numpy array. The structure could include holes.
My current aproach is something like this:
import numpy
a = numpy.zeros((6,6), dtype=numpy.int)
a[1:5, 1:5] = 1;a[3,3] = 0
# Way 1
s = ndimage.generate_binary_structure(2,1)
c = ndimage.binary_dilation(a,s).astype(a.dtype)
b = c - a
numpy.sum(b) # The result, however the hole is calculated as 1, although there are 4 edges
# Way 2
b = ndimage.distance_transform_cdt(a == 0,metric='taxicab') == 1
b = b.astype(int)
numpy.sum(b) # same as above
As you can see it displays all adjacent cells, however the sum of them doesn't equal the perimeter of the patch. The hole in the example array is calculated as 1 although it correctly has 4 edges. There are similar issues with greater holes of different shapes.
I have asked similar questions in the past, but all provided solutions which somehow didn't resolve in the correct output values in the end. Someone has an idea how to accomplish this? No other packages than numpy, scipy and the base packages please.
Count the number of edges in the interior and at the edges (assumes binary image):
n_interior = abs(diff(a, axis=0)).sum() + abs(diff(a, axis=1)).sum()
n_boundary = a[0,:].sum() + a[:,0].sum() + a[-1,:].sum() + a[:,-1].sum()
perimeter = n_interior + n_boundary
You can leave out n_boundary if the image is properly zero padded.
Do you mean, in the image, the total number of length-1 edges that separate blue-colored from red-colored tiles? In the picture above this number would be 28. In the example you give in code (which is slightly different, not having the 4 corners differ from the rest of the border tiles) it would be 20.
If that's what you want to compute, you can do something like:
numpy.sum(a[:,1:] != a[:,:-1]) + numpy.sum(a[1:,:] != a[:-1,:])
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With