3

在阅读了这篇文章并玩了 SciKit-image 之后,我发现 Python 与 MATLAB 的函数相比有所不同imregionalmax

我有这些代码行:

from skimage.feature import peak_local_max

manos = np.ones([5,5])
manos[2,2] = 0.
manos[2,4] = 2.

giannis = peak_local_max(manos,min_distance=1, indices=False, exclude_border=False)

giorgos = ndimage.filters.maximum_filter(manos, footprint=np.ones([3,3]))
giorgos = (giorgos == manos)

我希望一个二维数组只有一个True变量值 ([2,4])giannisgiorgos我在 MATLAB 中得到的值。相反,我最多取一个以上。

知道为什么会这样工作以及如何使它像在 MATLAB 中一样工作吗?

4

1 回答 1

4

两者giannisgiorgos的相似之处在于它们发现像素等于或大于 3x3 邻域中的其他像素。我相信giannis会有一些额外的阈值。

这些方法都不能保证找到的像素实际上是局部最大值。请注意我在上面所说的“更大或相等”。图像中任何足够大的高原(所有像素具有相同值的区域)都将被算法标记,无论它们是局部最大值、局部最小值还是介于两者之间。

例如:

import numpy as np
import matplotlib.pyplot as pp
import scipy.ndimage as ndimage

manos = np.sin(np.arange(100)/10)
manos = np.round(30*manos)/30     # Rounding to create plateaus

giorgos = ndimage.filters.maximum_filter(manos, footprint=np.ones([3]))
giorgos = (giorgos == manos)

pp.plot(manos);
pp.plot(giorgos);
pp.show()

一维

请注意滤波器如何识别正弦曲线局部最小值附近的三个点。其中中间的一个是实际的局部最小值,另外两个是既不是局部最大值也不是最小值的高原。

相比之下,MATLAB 函数imregionalmax会识别出由具有较低值的像素包围的所有平台。执行此操作所需的算法与上述算法非常不同。它可以使用联合查找算法有效地完成,或者使用洪水填充型算法效率较低。主要思想是找到一个不低于任何邻居的像素,然后从它扩展到它的等值邻居,直到探索了整个高原或直到找到高原中具有更高值邻居的像素之一.

Python 提供的一种实现是在DIPlib中(注意:我是作者):

import diplib as dip

nikos = dip.Maxima(manos)

pp.plot(manos);
pp.plot(nikos);
pp.show()

具有正确识别的局部最大值的同一 1D 图像

另一个实现是在 SciKit-Image 中(感谢Juan指出这一点):

nikos = skimage.morphology.local_maxima(manos)
于 2019-05-14T17:26:54.913 回答