【问题标题】:Find numpy array coordinates of neighboring maximum查找相邻最大值的numpy数组坐标
【发布时间】:2018-06-27 22:18:06
【问题描述】:

我使用接受的答案in this question 来获取 2 维或更多维的 numpy 数组中的局部最大值,以便为它们分配标签。现在我还想根据梯度将这些标签分配给数组中的相邻单元格——即一个单元格与具有最高值的相邻单元格获得相同的标签。这样我可以迭代地将标签分配给我的整个数组。

假设我有一个数组 A like

>>> A = np.array([[ 1. ,  2. ,  2.2,  3.5],
                  [ 2.1,  2.4,  3. ,  3.3],
                  [ 1. ,  3. ,  3.2,  3. ],
                  [ 2. ,  4.1,  4. ,  2. ]])

应用maximum_filter 我得到

>>> scipy.ndimage.filters.maximum_filter(A, size=3)
array([[ 2.4,  3. ,  3.5,  3.5],
       [ 3. ,  3.2,  3.5,  3.5],
       [ 4.1,  4.1,  4.1,  4. ],
       [ 4.1,  4.1,  4.1,  4. ]])

现在,对于这个数组中的每个单元格,我希望得到过滤器找到的最大值的坐标,即

array([[[1,1],[1,2],[0,3],[0,3]],
       [[2,1],[2,2],[0,3],[0,3]],
       [[3,1],[3,1],[3,1],[3,2]],
       [[3,1],[3,1],[3,1],[3,2]]])

然后我会使用这些坐标迭代地分配我的标签。

我可以使用循环在二维上做到这一点,忽略边框

highest_neighbor_coordinates = np.array([[(argmax2D(A[i-1:i+2, j-1:j+2])+np.array([i-1, j-1])) for j in range(1, A.shape[1]-1)] for i in range(1, A.shape[0]-1)])

但在看到scipy.ndimage 中的许多过滤器功能后,我希望有一个更优雅和可扩展(>=3 维)的解决方案。

【问题讨论】:

    标签: python numpy multidimensional-array


    【解决方案1】:

    我们可以使用带有反射元素的 pad 来模拟 max-filter 操作并使用 scikit-image's view_as_windows 在其上获得滑动窗口,计算扁平的 argmax 索引,偏移具有范围值的那些以转换为 global规模 -

    from skimage.util import view_as_windows as viewW
    
    def window_argmax_global2D(A, size):
        hsize = (size-1)//2 # expects size as odd number
        m,n = A.shape
        A1 = np.pad(A, (hsize,hsize), mode='reflect')
        idx = viewW(A1, (size,size)).reshape(-1,size**2).argmax(-1).reshape(m,n)
    
        r,c = np.unravel_index(idx, (size,size))
        rows = np.abs(r + np.arange(-hsize,m-hsize)[:,None])
        cols = np.abs(c + np.arange(-hsize,n-hsize))
        return rows, cols    
    

    示例运行 -

    In [201]: A
    Out[201]: 
    array([[1. , 2. , 2.2, 3.5],
           [2.1, 2.4, 3. , 3.3],
           [1. , 3. , 3.2, 3. ],
           [2. , 4.1, 4. , 2. ]])
    
    In [202]: rows, cols = window_argmax_global2D(A, size=3)
    
    In [203]: rows
    Out[203]: 
    array([[1, 1, 0, 0],
           [2, 2, 0, 0],
           [3, 3, 3, 3],
           [3, 3, 3, 3]])
    
    In [204]: cols
    Out[204]: 
    array([[1, 2, 3, 3],
           [1, 2, 3, 3],
           [1, 1, 1, 2],
           [1, 1, 1, 2]])
    

    扩展到n-dim

    我们将使用np.ogrid 作为这个扩展部分:

    def window_argmax_global(A, size):
        hsize = (size-1)//2 # expects size as odd number
        shp = A.shape
        N = A.ndim
        A1 = np.pad(A, (hsize,hsize), mode='reflect')
        idx = viewW(A1, ([size]*N)).reshape(-1,size**N).argmax(-1).reshape(shp)
    
        offsets = np.ogrid[tuple(map(slice, shp))]
        out = np.unravel_index(idx, ([size]*N))
        return [np.abs(i+j-hsize) for i,j in zip(out,offsets)]
    

    【讨论】:

    • 太棒了!我喜欢 'reflect'np.abs(i+j+hsize) 如何工作以包含边框单元格并仍然为原始数组返回正确的索引。
    猜你喜欢
    • 2020-08-23
    • 2021-05-22
    • 2020-06-23
    • 2015-05-09
    • 2019-02-01
    • 1970-01-01
    • 2017-12-07
    • 1970-01-01
    • 2018-04-10
    相关资源
    最近更新 更多