如何使 ndimage.filters.maximum_filter 像 MATLAB 的 imregionalmax 函数一样工作?
How to make ndimage.filters.maximum_filter work like MATLAB's imregionalmax function?
阅读 this post 后,也玩了 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)
当我进入 MATLAB 时,我希望变量 giannis
或 giorgos
只有一个 True
值 ([2,4]) 的二维数组。相反,我采取了不止一个最大值。
知道为什么会这样工作以及如何让它像在 MATLAB 中一样工作吗?
giannis
和 giorgos
的相似之处在于它们在 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
识别所有被具有较低值的像素包围的高原。执行此操作所需的算法与上面的算法非常不同。它可以使用 Union-Find 算法高效地完成,或者使用 flood-fill-type 算法效率较低。主要思想是找到一个不低于任何邻居的像素,然后从它扩展到它的 equal-valued 个邻居,直到探索了整个高原或直到你在高原中找到一个具有 higher-valued 邻居.
Python 提供的一个实现在 DIPlib(注意:我是作者):
import diplib as dip
nikos = dip.Maxima(manos)
pp.plot(manos);
pp.plot(nikos);
pp.show()
另一个实现是in SciKit-Image (Thanks to Juan for ):
nikos = skimage.morphology.local_maxima(manos)
阅读 this post 后,也玩了 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)
当我进入 MATLAB 时,我希望变量 giannis
或 giorgos
只有一个 True
值 ([2,4]) 的二维数组。相反,我采取了不止一个最大值。
知道为什么会这样工作以及如何让它像在 MATLAB 中一样工作吗?
giannis
和 giorgos
的相似之处在于它们在 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
识别所有被具有较低值的像素包围的高原。执行此操作所需的算法与上面的算法非常不同。它可以使用 Union-Find 算法高效地完成,或者使用 flood-fill-type 算法效率较低。主要思想是找到一个不低于任何邻居的像素,然后从它扩展到它的 equal-valued 个邻居,直到探索了整个高原或直到你在高原中找到一个具有 higher-valued 邻居.
Python 提供的一个实现在 DIPlib(注意:我是作者):
import diplib as dip
nikos = dip.Maxima(manos)
pp.plot(manos);
pp.plot(nikos);
pp.show()
另一个实现是in SciKit-Image (Thanks to Juan for
nikos = skimage.morphology.local_maxima(manos)