代码之家  ›  专栏  ›  技术社区  ›  Brenlla

3d核阵列中roi的快速提取方法

  •  0
  • Brenlla  · 技术社区  · 6 年前

    我有一个1D数组,其中包含一些视频数据:

    data=np.random.randint(0,high=255,size=(500*500*100),dtype=np.uint8)
    imgs=np.reshape(data,(100, 500,500)) # 100 frames, 500x500 pixels
    

    我想沿所有帧提取特定的感兴趣区域(roi)

    idx=np.random.randint(0,high=500*500,size=(49, 300)) #300 rois, 49 points each
    rois=imgs.reshape(100, -1)[:,idx]
    

    我把每一帧都展平,然后沿着第一个维度进行roi。真实的 imgs 数组比这里所示的大,并且以前的索引操作可能有点慢。如果我重塑 IMGS公司 以不同的方式(见下文)。 rois.size 是相同的,索引快得多,但是这会检索错误的数据。

    %timeit imgs.reshape(100, -1)[:,idx] # 13 ms
    %timeit imgs.reshape(-1, 100)[idx, :] # 1.2 ms, much faster but wrong data
    

    在我的实际代码中,差异几乎是50倍。有什么方法可以索引 IMGS公司 快?

    1 回复  |  直到 6 年前
        1
  •  1
  •   Paul Panzer    6 年前

    通过对roi像素进行排序并使用转置坐标,似乎可以节省至少一点时间:

    >>> def f_pp(im2D, idx):
    ...     s = np.argsort(idx.ravel())
    ...     out = np.empty((*idx.shape, im2D.shape[0]), im2D.dtype)
    ...     out.reshape(-1, im2D.shape[0])[s] = im2D.T[idx.ravel()[s]]
    ...     return out
    ... 
    
    # results are the same:
    >>> np.all(f_pp(imgs.reshape(100, -1), idx) == np.moveaxis(imgs.reshape(100, -1)[:, idx], 0, 2))
    True
    
    >>> timeit("imgs.reshape(100, -1)[:, idx]", globals=globals(), number=100)
    1.3392871069954708
    # transposing alone is not enough:
    >>> timeit("imgs.reshape(100, -1).T[idx]", globals=globals(), number=100)
    1.3336799899989273
    # but together with sorting I see a 2x speedup
    >>> timeit("f_pp(imgs.reshape(100, -1), idx)", globals=globals(), number=100)
    0.5874412529956317
    # still much worse than if we had a more favorable memory layout in
    # the first place
    >>> timeit("imgs.reshape(-1, 100)[idx]", globals=globals(), number=100)
    0.06296327701420523