Python中的2D局部最大值和最小值

4
我有一个数据框df,代表一个相关矩阵,带有这个示例极值的热图。每个点显然都有(x,y,value): Heatmap 我正在寻找获取局部极值的方法。我尝试了argrelextrema在单个行上的结果符合预期,但在2D上无效。我还尝试了scipy.signal.find_peaks,但这是针对1D数组的。
在Python中是否有任何返回特定值(阈值)上/下的局部极值的方法?类似于一个包含(x, y, value)的数组?如果没有,您能指导我正确的方向吗?
1个回答

1
这是一个棘手的问题,因为您需要仔细定义最大值或最小值在何时才算是相关的“大”。例如,想象一下,您有一个包含以下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比周围的5要小。另一方面,它也可能被看作是局部最大值,其中单独的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的值。接近程度取决于您愿意允许局部极值有多少模糊性。总之,在这里有两个模糊因素:1.过滤器大小和2.~=0的模糊因素。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接