我有一个数据框 df,代表一个相关矩阵,这个热图带有示例极值。显然,每个点都有 (x,y,value):
我正在研究获取局部极值。我查看了argrelextrema
,我在各个行上进行了尝试,结果符合预期,但这不适用于 2D。我也研究过scipy.signal.find_peaks
,但这是针对一维数组的。
Python中是否有任何东西会返回超过/低于某些值(阈值)的局部极值?类似于 (x, y, value) 的数组?如果没有,那么你能指出我正确的方向吗?
这是一个棘手的问题,因为您需要仔细定义最大值或最小值在相关之前需要多大“大”的概念。例如,假设您有一个包含以下 5x5 像素网格的补丁:
im = np.array([[ 0 0 0 0 0
0 5 5 5 0
0 5 4 5 0
0 5 5 5 0
0 0 0 0 0. ]])
这可能被视为局部最小值,因为 4 小于周围的 5s。OTOH,它可能被视为局部最大值,其中单个孤立的 4 像素只是“噪声”,平均 4.89 强度像素的 3x3 补丁实际上是单个局部最大值。这通常称为您查看图像的“比例”。
在任何情况下,您都可以通过使用该方向上的有限差分来估计一个方向上的局部导数。x
方向可能是这样的:
k = np.array([[ -1 0 1
-1 0 1
-1 0 1. ]])
将此过滤器应用于上面定义的图像补丁给出:
>>> cv2.filter2D(im, cv2.CV_64F, k)[1:-1,1:-1]
array([[ 9., 0., -9.],
[ 14., 0., -14.],
[ 9., 0., -9.]])
在 y 方向应用类似的过滤器将转置它。这里唯一在 x 和 y 方向上都为 0 的点是最中间的点,也就是我们认为是局部最小值的 4。这相当于检查 x 和 y 的梯度是否为 0。
整个过程可以扩展到找到我们已经确定的更大的单个局部最大值。您将使用更大的过滤器,例如
k = np.array([[ -2, -1, 0, 1, 2],
[ -2, -1, 0, 1, 2], ...
由于 4 使局部最大值成为近似值,因此您需要使用一些“近似”逻辑。即,您将寻找“接近” 0 的值。接近的程度取决于您愿意允许局部极值的模糊程度。综上所述,这里的两个 fudge 因子是 1. filter size 和 2. ~=0 fudge factor。