简体   繁体   English

numpy从3d数组中提取3d多维数据集

[英]numpy extract 3d cubes from 3d array

I would like to extract the 3D cubes (3x3x3) from a boolean 3D array of (180x180x197). 我想从(180x180x197)的布尔3D数组中提取3D多维数据集(3x3x3)。 This is similar to scipy.ndimage.measurements.label but need to fixed size of (3x3x3). 这类似于scipy.ndimage.measurements.label,但需要固定大小(3x3x3)。 Is there a fast way of doing this than using for loops. 是否有比使用for循环更快速的方法。

In your special case, I suggest to use ndimage.minimum_filter Let's say your array is called ``a''. 在您的特殊情况下,我建议使用ndimage.minimum_filter假设您的数组名为``a''。 The following: 下列:

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

will only contain ones where your array contained such box of True's Then you can use scipy.ndimage.measurements.label with the default structure to classify the boxes and maybe identify connected boxs. 将只包含那些数组中包含True框的数组。然后,您可以使用具有默认结构的scipy.ndimage.measurements.label对该框进行分类,并可能识别连接的框。 To locate them you can use ndimage.measurements.find_objects 要找到它们,您可以使用ndimage.measurements.find_objects

edit: 编辑:

The way above, you will correctly get the centers of all cubes in the array. 通过上面的方法,您将正确获得数组中所有多维数据集的中心。 To be clear, I think that is the answer to your initial question. 明确地说,我认为这是您最初的问题的答案。 In the comments, it turned out, that indeed only non-overlapping cubes are needed. 结果表明,实际上只需要不重叠的多维数据集。 Therefore, one needs to analyze the output of minimum_filter, where I can imagine many approaches. 因此,需要分析minimum_filter的输出,在这里我可以想象很多方法。

One can use the following to obtain only one cube per cluster: 每个群集只能使用以下内容获取一个多维数据集:

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)

Now the problem occurs that cubes are lost which are not overlapping but share a face. 现在出现的问题是丢失了不重叠但共享一个面的多维数据集。 Actually one can imagine quite complicated structures of non-overlapping, facesharing cubes. 实际上,可以想象到非常复杂的非重叠面共享立方体结构。 Certainly, there are several solutions (sets of non-overlapping cubes) that can be found for this problem. 当然,可以找到针对此问题的几种解决方案(一组非重叠的多维数据集)。 So it is a completely new task to choose a set of cubes from the found centers and I think you will have to find one which is ideal for you. 因此,从发现的中心中选择一组多维数据集是一项全新的任务,我认为您将必须找到一个最适合您的多维数据集。

One way could be to iterate through all solutions and set each found cube to False: 一种方法可能是遍历所有解决方案并将每个找到的多维数据集设置为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)

I guess only very few iterations will be necessary. 我猜只需要很少的迭代。

I hope this is what you were looking for 我希望这就是你想要的

Final solution with help from dnalow 在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)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM