我想计算给定numpy数组结构的周长。周长是指numpy数组中结构的精确周长。结构可能包括洞。
我目前的方法是这样的:
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
如您所见,它显示所有相邻的单元格,但它们的总和不等于修补程序的周长。示例数组中的孔计算为1,尽管它正确地有4个边。有类似的问题,不同形状的孔更大。
我过去曾问过类似的问题,但所有提供的解决方案最终都无法以正确的输出值解决。 有人知道如何做到这一点? 除了numpy,scipy和基础包之外,没有别的包。
答案 0 :(得分:5)
计算内部和边缘的边数(假设是二进制图像):
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
如果图像填充正确,则可以省略n_boundary。
答案 1 :(得分:4)
在图像中,您的意思是将蓝色与红色瓷砖分开的长度为1的边缘的总数?在上面的图片中,这个数字将是28.在示例中,您提供的代码(略有不同,没有4个角与其他边框图块不同),它将是20。
如果这是您想要计算的内容,您可以执行以下操作:
numpy.sum(a[:,1:] != a[:,:-1]) + numpy.sum(a[1:,:] != a[:-1,:])
答案 2 :(得分:0)
我要添加我的答案,因为现有的答案存在相同的问题: 如果一个像素与上面的像素和左边的像素都不相同,那么您将被计数两次:
numpy.sum(a[:,1:] != a[:,:-1]) + numpy.sum(a[1:,:] != a[:-1,:])
这可以通过使用元素方式或在进行求和之前解决:
np.logical_or(
(a[:,1:] != a[:,:-1])[1:,:],
(a[1:,:] != a[:-1,:])[:,1:]).sum()