我找到了这个解决方案,但它可能是 O(N^2):
import numpy as np
# generate test data
n = 10
foo = np.random.rand(n,n)
# fixed test data for visual back-checking
# foo = np.array([[ 0.12439309, 0.88878825, 0.21675684, 0.21422532, 0.7016789 ],
# [ 0.14486462, 0.40642871, 0.4898418 , 0.41611303, 0.12764404],
# [ 0.41853585, 0.22216484, 0.36113181, 0.5708699 , 0.3874901 ],
# [ 0.24314391, 0.22488507, 0.22054467, 0.25387521, 0.46272496],
# [ 0.99097341, 0.76083447, 0.37941783, 0.932519 , 0.9668254 ]])
# list to collect local maxima
local_maxima = []
# distance in x / y to define region of interest around current center coordinate
# roi = 1 corresponds to a region of interest of 3x3 (except at borders)
roi = 1
# give pseudo-coordinates
x,y = np.meshgrid(range(foo.shape[0]), range(foo.shape[1]))
for i in range(foo.shape[0]):
for j in range(foo.shape[1]):
x0 = x[i,j]
y0 = y[i,j]
z0 = foo[i,j]
# index calculation to avoid out-of-bounds error when taking sub-matrix
mask_x = abs(x - x0) <= roi
mask_y = abs(y - y0) <= roi
mask = mask_x & mask_y
if np.max(foo[mask]) == z0:
local_maxima.append((i, j))
print local_maxima
这一切都是关于在矩阵上定义滑动窗口/过滤器。我想到的所有其他解决方案都指向绝对最大值(例如直方图)......
但是我希望我的 ansatz 在某种程度上有用......
编辑:这里的另一个解决方案应该比第一个更快,但仍然是 O(N^2),它不依赖于直线网格数据:
import numpy as np
# generate test data
# points = np.random.rand(10,3)
points = np.array([[ 0.08198248, 0.25999721, 0.07041999],
[ 0.19091977, 0.05404123, 0.25826508],
[ 0.8842875 , 0.90132467, 0.50512316],
[ 0.33320528, 0.74069399, 0.36643752],
[ 0.27789568, 0.14381512, 0.13405309],
[ 0.73586202, 0.4406952 , 0.52345838],
[ 0.76639731, 0.70796547, 0.70692905],
[ 0.09164532, 0.53234394, 0.88298593],
[ 0.96164975, 0.60700481, 0.22605181],
[ 0.53892635, 0.95173308, 0.22371167]])
# list to collect local maxima
local_maxima = []
# distance in x / y to define region of interest around current center coordinate
radius = 0.25
for i in range(points.shape[0]):
# radial mask with radius radius, could be beautified via numpy.linalg
mask = np.sqrt((points[:,0] - points[i,0])**2 + (points[:,1] - points[i,1])**2) <= radius
# if current z value equals z_max in current region of interest, append to result list
if points[i,2] == np.max(points[mask], axis = 0)[2]:
local_maxima.append(tuple(points[i]))
结果:
local_maxima = [
(0.19091976999999999, 0.054041230000000003, 0.25826507999999998),
(0.33320527999999999, 0.74069399000000002, 0.36643752000000002),
(0.73586202000000001, 0.44069520000000001, 0.52345838),
(0.76639731, 0.70796546999999999, 0.70692904999999995),
(0.091645320000000002, 0.53234393999999996, 0.88298593000000003),
(0.53892635, 0.95173308000000001, 0.22371167)
]