【问题标题】:Quickly find the min and max coordinates of connected component in a large image快速找到大图像中连通分量的最小和最大坐标
【发布时间】:2017-07-18 20:07:41
【问题描述】:

我有一个大小为50000x50000 的图像。它有大约25000 连接不同的连接组件。我使用ndimage.label 标记它们中的每一个,然后找到非零点,最后得到最小 x、最大 x、最小 y 和最大 y 值。但是,我必须为每个25000 连接的组件找到这些坐标。这很昂贵,因为我必须在50000x50000 图像25000 次上运行np.nonzero。这是我刚才提到的代码的 sn-p。

im, _ = ndimage.label(im)
num_instances = np.max(np.max(im))
for instance_id in range(1,num_instances+1):
    im_inst = im == instance_id 
    points = np.nonzero(im_inst) # running this is expensive as im is 50000x50000

    cropped_min_x_1 = np.min(points[0])
    cropped_min_y_1 = np.min(points[1]) 
    cropped_max_x_1 = np.max(points[0])+1 
    cropped_max_y_1 = np.max(points[1])+1

有谁知道我可以做些什么来显着加快这个过程?

【问题讨论】:

    标签: python image performance numpy matrix


    【解决方案1】:

    如果标记像素的比例不是太大:

    nz = np.flatnonzero(im)
    order = np.argsort(im.ravel()[nz])
    nz = nz[order]
    blocks = np.searchsorted(im.ravel()[nz], np.arange(2, num_instances+1))
    # or (which is faster will depend on numbers)
    blocks = 1 + np.where(np.diff(im.ravel()[nz]))[0]
    coords = np.array(np.unravel_index(nz, (50000, 50000)))
    groups = np.split(coords, blocks, axis=-1)
    

    groups 将是一个 2xn_i 坐标列表,其中 n_i 是组件 i 的大小。

    【讨论】:

    • 我们不想生成一个 4xn_i 数组,因为有 4 个坐标,最小 x,最小 y,最大 x,最大 y?
    • 该段所有点的坐标。我把提取最小值/最大值作为练习 ;-) 我只是看到这有点令人困惑。输出列表的每个元素都是一个 2xn_i 数组。每个段都有一个元素 i
    • 啊,所以在您的代码中,我们应该将im 替换为im_inst 对吧?而groups 在我的代码中或多或少只是points
    • 不,诀窍是只做一次非零,所以它绝对应该在im上。这意味着我们从一大堆混合在一起的所有段开始,所以做一个间接排序,然后在段索引发生变化的地方进行 nsplit。当我们间接地这样做时,即使用索引,它仍然会将这些平面索引转换回坐标,这或多或少是这样。它应该比做非零 25,000x 更有效。不过,内存可能是个问题。你有多少?不能太少,因为您可以存储 50,000x50,000 像素的图像。
    • 请问您是怎么​​想到这个的?我的第一个问题,您是否决定使用np.flatnonzero(),这样使用其他 numpy 函数会更容易操作。这样我们就不必处​​理轴了?我有一种预感,这是一个巧妙的技巧,可以用于解决各种问题。
    猜你喜欢
    • 2014-07-10
    • 1970-01-01
    • 1970-01-01
    • 2012-05-10
    • 2013-10-22
    • 2010-11-25
    • 2014-02-02
    • 2012-02-10
    • 2022-01-01
    相关资源
    最近更新 更多