在numpy数组中寻找局部最大梯度值的快速方法?

2024-10-01 15:33:06 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个二维数组,我想检测它的所有局部最大数组索引。也就是说,给定一个指数(i,j),其最大梯度是其8个相邻值中任何一个的最大绝对变化:

Index: (i, j)

Neighbors:
(i-1,j+1)  (i,j+1)  (i+1,j+1)
(i-1,j)    [index]    (i+1,j)
(i-1,j-1)  (i,j-1)  (i+1,j-1)

Neighbor angles:
315           0            45
270        [index]         90
225          180          135

MaxGradient(i,j) = Max(|Val(index) - Val(neighbor)|)

如果索引的最大梯度至少与它的任何相邻的最大梯度一样大,则称该索引为局部极大。在

算法的输出应该是一个二维元组数组,或者一个三维数组,其中对于原始数组中的每个索引,输出数组都包含一个值,该值指示该索引是否局部最大,如果是,则表示梯度的角度。在

我最初的实现简单地传递了两次数组,一次计算最大梯度(存储在一个临时数组中),然后通过temp数组确定局部最大索引。每次,我都是通过for循环,分别查看每个索引。在

在numpy里有没有更有效的方法?在


Tags: 算法indexneighbors局部val数组指数max
2条回答

考虑这8个相关指标:

X1 X2 X3
X4 X  X5
X6 X7 X8

您可以计算每个像素X的差值D1=Val(X)-Val(X1)D2=Val(X)-Val(X2)D3=Val(X)-Val(X3)D4=Val(X)-Val(X4)。你不需要计算其他的差异,因为它们是前四个的镜像。 要计算差异,可以用一行和一列0填充图像并减去。在

正如Cyborg所指出的,只有四个差异需要计算才能完成计算(注意,如果这真的是在统一网格上进行空间梯度计算,那么对角线和反对角线的计算应该有1/sqrt(2)的因子)。如果我理解您的问题,那么numpy的实现可以是这样的:

A=np.random.random(100).reshape(10,10)

# Padded copy of A
B=np.empty((12,12))
B[1:-1,1:-1]=A
B[0,1:-1]=A[0,:]   
B[-1,1:-1]=A[-1,:]
B[1:-1,0]=A[:,0]
B[1:-1,-1]=A[:,-1]
B[0,0]=A[1,1]
B[-1,-1]=A[-1,-1]
B[-1,0]=A[-1,0]
B[0,1]=A[0,1]

# Compute 4 absolute differences
D1=np.abs(B[1:,1:-1]-B[:-1,1:-1]) # first dimension
D2=np.abs(B[1:-1,1:]-B[1:-1,:-1]) # second dimension
D3=np.abs(B[1:,1:]-B[:-1,:-1]) # Diagonal
D4=np.abs(B[1:,:-1]-B[:-1,1:]) # Antidiagonal

# Compute maxima in each direction
M1=np.maximum(D1[1:,:],D1[:-1,:])
M2=np.maximum(D2[:,1:],D2[:,:-1])
M3=np.maximum(D3[1:,1:],D3[:-1,:-1])
M4=np.maximum(D4[1:,:-1],D4[:-1,1:])

# Compute local maximum for each entry
M=np.max(np.dstack([M1,M2,M3,M4]),axis=2)

这将使你在输入A的4个方向上都有最大的差异,在M中。一个类似的想法可以用来标记局部最大值,最终达到类似的效果

^{pr2}$

这会给你一个数组包含局部极大值的坐标,单位为M

相关问题 更多 >

    热门问题