numpy数组中多个细胞贴片的相邻细胞

时间:2012-10-12 18:02:53

标签: python multidimensional-array numpy scipy

这是由solution引起的后续问题。 计算相邻单元格的解决方案非常有效,除非阵列中有多个补丁。

所以这次数组就像这样。

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]

1 个答案:

答案 0 :(得分:4)

您可以使用label中的ndimage来细分每个补丁。

然后你只要问返回的数组在哪里等于1,2,3等并在其上执行你的算法(或者你只是使用ndimage.distance_transform_cdt但是为每个标记的段反转你的forground / background。

修改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