Быстрый способ найти локально максимальные значения градиента в массиве NumPy? - PullRequest
2 голосов
/ 18 ноября 2011

У меня есть двумерный массив, для которого я хочу определить все локально максимальные индексы массива.То есть, учитывая индекс (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)|)

Индекс называется локально максимальным если его MaxGradient, по крайней мере, такой же, как любой из собственных MaxGradients своих соседей.

Выходные данные алгоритма должны быть массивом двумерных кортежей или трехмерным массивом, где для каждого индексав исходном массиве выходной массив содержит значение, указывающее, был ли этот индекс локально максимальным, и, если это так, угол наклона.

Моя первоначальная реализация просто дважды передавала массив, один раз для вычисления максимального значения.градиенты (хранящиеся во временном массиве), а затем один раз над временным массивом, чтобы определить локально максимальные индексы.Каждый раз я делал это с помощью циклов for, просматривая каждый индекс по отдельности.

Есть ли более эффективный способ сделать это в numpy?

Ответы [ 2 ]

2 голосов
/ 18 ноября 2011

Рассмотрим эти 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). Вам не нужно вычислять другие различия, потому что они являются зеркалами первых четырех. Чтобы вычислить различия, вы можете дополнить изображение строкой и столбцом нулей и вычесть.

1 голос
/ 19 ноября 2011

Как указал Киборг, есть только четыре различия, которые необходимо вычислить для завершения вашего вычисления (обратите внимание, что для диагональных и антидиагональных вычислений действительно должен быть коэффициент 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)

Это оставит вас с максимальной разницей в каждом из 4 направлений ввода A в M. Аналогичная идеяможет использоваться для маркировки локально максимальных значений, завершаясь чем-то вроде

T=np.where((M==np.max(np.dstack([Ma,Mb,Mc,Md,Me,Mf,Mg,Mh]),axis=2)))

, что даст вам массив, содержащий координаты локально максимальных значений в M

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...