找到相邻最大值的numpy数组坐标

15 浏览
0 Comments

找到相邻最大值的numpy数组坐标

我使用了这个问题中的被接受的答案,来找出numpy数组中的局部最大值,并为它们分配了标签。现在我还想根据梯度将这些标签分配给数组中的相邻单元格,即一个单元格与具有最高值的相邻单元格获得相同的标签。这样我就可以迭代地为整个数组分配标签。\n假设我有一个名为A的数组,如下所示:\nA = np.array([[ 1. , 2. , 2.2, 3.5],\n [ 2.1, 2.4, 3. , 3.3],\n [ 1. , 3. , 3.2, 3. ],\n [ 2. , 4.1, 4. , 2. ]])\n应用maximum_filter后,我得到:\nscipy.ndimage.filters.maximum_filter(A, size=3)\narray([[ 2.4, 3. , 3.5, 3.5],\n [ 3. , 3.2, 3.5, 3.5],\n [ 4.1, 4.1, 4.1, 4. ],\n [ 4.1, 4.1, 4.1, 4. ]])\n现在,对于这个数组中的每个单元格,我想要获得过滤器找到的最大值的坐标,即:\narray([[[1,1],[1,2],[0,3],[0,3]],\n [[2,1],[2,2],[0,3],[0,3]],\n [[3,1],[3,1],[3,1],[3,2]],\n [[3,1],[3,1],[3,1],[3,2]]])\n然后,我将使用这些坐标来迭代地分配我的标签。\n对于二维情况,我可以使用循环来完成,忽略边界:\nhighest_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)])\n但是在看到scipy.ndimage中的许多滤波函数之后,我希望能有一个更加优雅和可扩展(适用于>=3维)的解决方案。

0
0 Comments

找到numpy数组中相邻最大值的坐标

问题出现的原因:

要找到numpy数组中每个元素的相邻最大值的坐标。

解决方法:

可以使用pad函数和反射元素来模拟max-filter操作,并使用scikit-image的view_as_windows函数在其上获取滑动窗口,计算扁平化的argmax索引,使用范围值偏移这些索引以将其转换为全局尺度。

以下是解决方法的代码示例:

from skimage.util import view_as_windows as viewW
def window_argmax_global2D(A, size):
    hsize = (size-1)//2 # 期望size为奇数
    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 

运行示例:

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. ]])
rows, cols = window_argmax_global2D(A, size=3)
print(rows)
print(cols)

输出结果:

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

扩展到n维:

我们可以使用np.ogrid来进行扩展:

def window_argmax_global(A, size):
    hsize = (size-1)//2 # 期望size为奇数
    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)的工作方式,它们包括边界单元格并仍然返回原始数组的正确索引。

0