在标签图中的分段周围获取边界框的最快方法

问题描述 投票:2回答:1

3D标签图是矩阵,其中每个像素(体素)都有一个整数标签。这些值应该是连续的,这意味着标记为k的分段不会被分段。

给出这样的标签图(分段),在Python中获取围绕每个分段的最小边界框的坐标的最快方法是什么?

我尝试了以下操作:

  • 使用多索引迭代器(来自numpy.nditer)遍历矩阵并构造一个反向索引字典。这意味着对于每个标签,您将获得该标签所在的每个体素的3个坐标。
  • 对于每个标签,获取每个坐标的最大值和最小值。

好处是,您可以在一O(N)次通过中获得所有位置信息。不好的是,我不需要此详细信息。我只需要四肢,所以可能会使用一些numpy函数来执行此操作,该方法比许多附加列表要快。有什么建议吗?

一次通过矩阵在我的计算机上花费了大约8秒钟,因此摆脱它非常好。为了对数据有所了解,标签图中有数百个标签。标签图的大小可以是700x300x30或300x300x200或类似的尺寸。

编辑:现在,每个标签的每个坐标仅存储更新的最大值和最小值。这样就无需维护和存储所有这些大列表(追加)。

python performance algorithm numpy
1个回答
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').min * np.ones((3, labmax + 1), dtype='int32')
b_last = np.iinfo('int32').max * np.ones((3, labmax + 1), dtype='int32')

# run through all of the 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_firstb_last将是最大int32值。

我在计算机上尝试过,对于(300,300,200)数组,大约需要1秒钟才能找到值。

© www.soinside.com 2019 - 2024. All rights reserved.