从3d阵列的numpy萃取物3d立方体

时间:2016-09-11 15:40:07

标签: python numpy multidimensional-array scipy

我想从(180x180x197)的布尔3D数组中提取3D立方体(3x3x3)。这类似于scipy.ndimage.measurements.label但需要固定大小(3x3x3)。 有没有比使用for循环更快的方法。

2 个答案:

答案 0 :(得分:2)

在您的特殊情况下,我建议使用ndimage.minimum_filter 假设你的数组叫做“a”。以下内容:

centers = ndimage.minimum_filter(a, 3, mode="constant")

只会包含数组中包含True的框 然后你可以使用scipy.ndimage.measurements.label和默认结构对盒子进行分类,也可以识别连接的盒子。要找到它们,您可以使用ndimage.measurements.find_objects

编辑:

通过上述方法,您将正确获得数组中所有多维数据集的中心。要清楚,我认为这是你最初问题的答案。事实证明,在评论中,确实只需要非重叠的立方体。因此,需要分析minimum_filter的输出,我可以想象很多方法。

可以使用以下内容仅为每个群集获取一个多维数据集:

s = ndimage.generate_binary_structure(3,3)
labels, num = ndimage.measurements.label(centers, s)
locations = ndimage.measurements.find_objects(labels)
locations = map(lambda slices: [slices[i].start for i in xrange(3)], locations)

现在出现的问题是多维数据集丢失但不重叠但共享一个面。实际上,人们可以想象非重叠的,面对面的立方体非常复杂的结构。当然,可以找到针对此问题的几种解决方案(非重叠立方体集)。因此,从找到的中心选择一组立方体是一项全新的任务,我认为您必须找到一个适合您的立方体。

一种方法是迭代所有解决方案并将每个找到的多维数据集设置为False:

get_starting_point = numpy.vectorize(lambda sl: sl.start) #to be applied on slices
s = ndimage.generate_binary_structure(3,3)
result = []

while True:
    labels, num = ndimage.measurements.label(centers, s)
    if not num:
        break
    locations = ndimage.measurements.find_objects(labels)
    sp = get_starting_point(locations)
    result.append(sp)
    for p in sp:
        centers[p[0]-1:p[0]+2, p[1]-1:p[1]+2, p[2]-1:p[2]+2] = False

numiter = len(results)
results = numpy.vstack(results)

我想只需要很少的迭代。

我希望这就是你要找的东西

答案 1 :(得分:0)

dnalow帮助下的最终解决方案

get_starting_point = numpy.vectorize(lambda sl: sl.start)
s = ndimage.generate_binary_structure(3,3)
result = []

while True:
    centers = ndimage.minimum_filter(b, 3, mode="constant")
    labels, num = ndimage.measurements.label(centers, s)
    if not num:
        break
    locations = ndimage.measurements.find_objects(labels)
    sp = get_starting_point(locations)
    for p in sp:
        if numpy.all(a[p[0]-1:p[0]+2, p[1]-1:p[1]+2, p[2]-1:p[2]+2]):
            result.append(p) 
        b[p[0]-1:p[0]+2, p[1]-1:p[1]+2, p[2]-1:p[2]+2] = False

numiter = len(result)
results = numpy.vstack(result)