I have a 2-d array for which I want to detect all locally maximal array indices. That is, given an index (i, j), its maximum gradient is the largest absolute change from any of its 8 neighboring values:
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)|)
The index is said to be locally maximal if its MaxGradient is at least as large as any of its neighbors’ own MaxGradients.
The output of the algorithm should be a 2-d array of tuples, or a 3-d array, where for each index in the original array, the output array contains a value indicating if that index was locally maximal and, if so, the angle of the gradient.
My initial implementation simply passed over the array twice, once to calculate the max gradients (stored in a temporary array) and then once over the temp array to determine the locally maximal indices. Each time, I did this via for loops, looking at each index individually.
Is there some more efficient way to do this in numpy?
As Cyborg pointed out, there are only four differences which need to be computed to complete your calculation (note that there really should be a factor of 1/sqrt(2) for the diagonal and antidiagonal calculations if this really is a spatial gradient calculation on a uniform grid). If I have understood your question, the implementation with numpy could be something like this:
That will leave your with the maximum difference in each of the 4 directions of the input A in M. A similar idea can be used for labelling the locally maximal values, culminating in something like
which would give you an array contained the coordinates of locally maximal values in M