1

这是此解决方案引起的后续问题。除非数组中有多个补丁,否则计算相邻单元格的解决方案效果很好。

所以这次数组例如看起来像这样。

import numpy
from scipy import ndimage

s = ndimage.generate_binary_structure(2,2)
a = numpy.zeros((6,6), dtype=numpy.int) # example array
a[1:3, 1:3] = 1;a[2:4,4:5] = 1
print a
[0 0 0 0 0 0]
[0 1 1 0 0 0]
[0 1 1 0 1 0]
[0 0 0 0 1 0]
[0 0 0 0 0 0]
[0 0 0 0 0 0]

# Number of nonoverlapping cells
c = ndimage.binary_dilation(a,s).astype(a.dtype)
b = c - a
numpy.sum(b) # returns 19
# However the correct number of non overlapping cells should be 22 (12+10)

是否有任何聪明的解决方案来解决这个困境而不使用任何循环或遍历数组?原因是数组可能非常大。

想法1:

仔细考虑一下,一种方法可能是检查迭代结构中的多个补丁。为了使总计数正确,下面的这些单元格在膨胀中必须等于 2(或更多)。有人知道如何将这个想法变成代码吗?

[1 1 1 1 0 0]
[1 0 0 2 1 1]
[1 0 0 2 0 1]
[1 1 1 2 0 1]
[0 0 0 1 1 1]
[0 0 0 0 0 0]
4

1 回答 1

4

您可以使用labelfromndimage来分割每个补丁。

然后,您只需询问返回的数组在哪里等于 1、2、3 等并对其执行您的算法(或者您只需使用ndimage.distance_transform_cdt但为每个标记的段反转您的前景/背景。

编辑1:

此代码将获取您的数组a并执行您的要求:

b, c = ndimage.label(a)
e = numpy.zeros(a.shape)
for i in xrange(c):

    e += ndimage.distance_transform_cdt((b == i + 1) == 0) == 1

print e

我意识到那里的所有平等有点难看,但它输出:

In [41]: print e
[[ 1.  1.  1.  1.  0.  0.]
 [ 1.  0.  0.  2.  1.  1.]
 [ 1.  0.  0.  2.  0.  1.]
 [ 1.  1.  1.  2.  0.  1.]
 [ 0.  0.  0.  1.  1.  1.]
 [ 0.  0.  0.  0.  0.  0.]]

编辑 2(替代解决方案):

这段代码应该做同样的事情并且希望更快(但是它不会找到两个补丁只接触角落的地方)。

b = ndimage.binary_closing(a) - a
b = ndimage.binary_dilation(b.astype(bool))

c = ndimage.distance_transform_cdt(a == 0) == 1

e = c.astype(numpy.int) * b + c

print e
于 2012-10-12T19:16:48.137 回答