3D标签图是矩阵,其中每个像素(体素)具有整数标签。这些值预计是连续的,这意味着标签k
的段不会被分段。
鉴于此类标签贴图(细分),在Python中获取每个细分周围最小边界框坐标的最快方法是什么?
我尝试了以下内容:
numpy.nditer
)遍历矩阵并构造反向索引字典。这意味着对于每个标签,您将获得标签所在的每个体素的3个坐标。 好处是你可以在一次O(N)传球中获得所有位置信息。不好的是,我不需要这些详细信息。我只需要四肢,所以可能有一种更快的方法来实现这一点,使用一些比这么多列表追加更快的numpy函数。有什么建议吗?
在我的机器上通过矩阵大约需要8秒钟,所以摆脱它会很棒。为了了解数据,标签贴图中有几百个标签。标签贴图的大小可以是700x300x30或300x300x200或类似的东西。
编辑:现在每个标签只存储更新的最大和最小坐标。这消除了维护和存储所有这些大型列表(追加)的需要。
答案 0 :(得分:3)
如果我正确理解你的问题,你就有了一组体素,你希望每个轴都有一个组的极值。
让我们定义:
arr
:整数标签的3D数组
labels
:标签列表(整数0..labmax)
代码:
import numpy as np
# number of highest label:
labmax = np.max(labels)
# maximum and minimum positions along each axis (initialized to very low and high values)
b_first = np.iinfo('int32').max * np.ones((3, labmax + 1), dtype='int32')
b_last = np.iinfo('int32').max * np.ones((3, labmax + 1), dtype='int32')
# run through all dimensions making 2D slices and marking all existing labels to b
for dim in range(3):
# create a generic slice object to make the slices
sl = [slice(None), slice(None), slice(None)]
bf = b_first[dim]
bl = b_last[dim]
# go through all slices in this dimension
for k in range(arr.shape[dim]):
# create the slice object
sl[dim] = k
# update the last "seen" vector
bl[arr[sl].flatten()] = k
# if we have smaller values in "last" than in "first", update
bf[:] = np.clip(bf, None, bl)
在此操作之后,我们有六个向量,为每个轴提供最小和最大的索引。例如,标签13
的第二轴上的边界值为b_first[1][13]
和b_last[1][13]
。如果缺少某些标签,则所有相应的b_first
和b_last
都将是最大int32
值。
我在计算机上尝试了这个,对于(300,300,200)阵列,需要大约1秒才能找到值。