如何使ndimage.filters.maximum_filter像MATLAB的imregionalmax函数一样工作?

时间:2019-05-14 15:34:30

标签: python matlab image-processing scikit-image ndimage

在阅读this post之后,并且还使用了SciKit图像,我发现与MATLAB函数imregionalmax相比,Python有所不同。

我有以下几行代码:

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)

我希望2D数组的变量Truegiannis只有一个giorgos值([2,4]),就像我在MATLAB中得到的那样。相反,我最多只能考虑一个。

有人知道为什么这样工作,以及如何使其像在MATLAB中那样工作吗?

1 个答案:

答案 0 :(得分:2)

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()

A 1D "image" with plateaus, and the regions identified by the code above

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

相比之下,MATLAB函数imregionalmax可以识别被较低像素所包围的所有平稳段。执行此操作所需的算法与上述算法完全不同。可以使用Union-Find算法有效地完成此操作,也可以使用Flood-fill-type算法效率较低地完成操作。主要思想是找到一个不低于任何邻域的像素,然后从其扩展到其等值邻域,直到对整个高原进行了探索,或者直到找到高原中具有更高邻域值的像素之一

我知道的该算法的唯一实现 Python中的一种实现是在PyDIP中(注意:我是作者;还请注意:您还不能通过{ {1}},您需要从源代码进行编译):

pip

Same 1D image with correctly identified local maxima

另一种实现是in SciKit-Image(感谢Juanpointing this out):

import PyDIP as dip

nikos = dip.Maxima(manos)

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