Calculate perimeter of numpy array

2019-02-10 02:32发布

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

enter image description here

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.

2条回答
混吃等死
2楼-- · 2019-02-10 02:39

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,:])

查看更多
别忘想泡老子
3楼-- · 2019-02-10 03:01

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.

查看更多
登录 后发表回答