【问题标题】:Adjacent cells of multiple cell patches in a numpy arraynumpy数组中多个单元格补丁的相邻单元格
【发布时间】:2012-10-12 18:02:52
【问题描述】:

这是来自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]

【问题讨论】:

  • 你得到的是不重叠的单元格?您是否真的希望每个补丁都单独使用它们? IE。如果您将a[1,3:5] = 1 添加到您的a,您甚至想要什么?
  • 查看其他问题的答案。上面的数组 a 只是一个例子。我的真实数组非常大,包含许多值的单元格补丁
  • 我很困惑,因为您表示scipy.signal.convolve2d 解决了您之前的问题——但这会计算所有重叠值。现在看来您希望 计算重叠,except 当这些重叠来自1s 的非连续块时。那是完全不同的要求。所以你之前的问题并不能真正帮助解释你现在想要什么。
  • 真的很大意味着你有很多补丁或大补丁吗?如果他们很少,我认为我的解决方案应该很好用
  • 哦,对不起,当时我计算了重叠单元格的数量,这也是最初的问题。因此,这是正确的答案。不,我想用数组中的多个值块计算不重叠的相邻单元格。巨大的意思是数组很大,有很多不同的结构化补丁

标签: python multidimensional-array numpy scipy


【解决方案1】:

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

然后您只需询问返回的数组等于 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

【讨论】:

  • 你想要距离变换的棋盘设置(默认)。
  • 嗯,我知道标签功能。我只是在阅读ndimage.distance_transform_cdt 的文档。你能举例说明你的意思吗?我现在的问题是numpy.sum 对值的计数并没有按补丁计算相邻的单元格
  • 是的,这完全符合我的要求。谢谢。虽然我仍然不知道distance_transform_cdt 做了什么:-)
  • distance_transform_cdt 是一个非常漂亮的算法,它可以为所有非对象位置提供到对象的距离。距离可以通过多种方式测量,棋盘意味着它会给出国王的移动次数,就像你在下国际象棋一样。所以这就是为什么我要求返回 1 的位置。(出租车需要走两个街区才能找到拐角处的位置(因为它不能走对角线))
  • 如果我在第二个解决方案中设置的限制对您的应用程序来说是可以的,那么我认为它应该是一个更快的算法。
猜你喜欢
  • 2019-03-29
  • 2012-09-18
  • 2016-07-21
  • 1970-01-01
  • 2016-07-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多