python - 如何在Python中找到3D数组的局部最大值?

标签 python numpy scipy

嗨,我正在尝试在 3D numpy 数组中找到局部最大值,但我似乎找不到使用 numpy、scipy 或其他任何东西来实现这一点的简单方法。

现在我使用scipy.signal.argrelexrema实现了它。但处理大数组的时间很长,而且只能在分离轴上工作。

import numpy as np
from scipy.signal import argrelextrema


def local_maxima_3D(data, order=1):
    """Detects local maxima in a 3D array

    Parameters
    ---------
    data : 3d ndarray
    order : int
        How many points on each side to use for the comparison

    Returns
    -------
    coords : ndarray
        coordinates of the local maxima
    values : ndarray
        values of the local maxima
    """
    # Coordinates of local maxima along each axis
    peaks0 = np.array(argrelextrema(data, np.greater, axis=0, order=order))
    peaks1 = np.array(argrelextrema(data, np.greater, axis=1, order=order))
    peaks2 = np.array(argrelextrema(data, np.greater, axis=2, order=order))

    # Stack all coordinates 
    stacked = np.vstack((peaks0.transpose(), peaks1.transpose(),
                         peaks2.transpose()))

    # We keep coordinates that appear three times (once for each axis)
    elements, counts = np.unique(stacked, axis=0, return_counts=True)
    coords = elements[np.where(counts == 3)[0]]

    # Compute values at filtered coordinates
    values = data[coords[:, 0], coords[:, 1], coords[:, 2]]

    return coords, values

我知道这个解决方案远非最佳,并且仅适用于 order=1。有没有更好的方法在 python 中找到 3D 数组中的局部最大值?

编辑:

我现在使用以下方法,实际上速度更快,并且在 order > 1 时也有效:

import numpy as np
from scipy import ndimage as ndi


def local_maxima_3D(data, order=1):
    """Detects local maxima in a 3D array

    Parameters
    ---------
    data : 3d ndarray
    order : int
        How many points on each side to use for the comparison

    Returns
    -------
    coords : ndarray
        coordinates of the local maxima
    values : ndarray
        values of the local maxima
    """
    size = 1 + 2 * order
    footprint = np.ones((size, size, size))
    footprint[order, order, order] = 0

    filtered = ndi.maximum_filter(data, footprint=footprint)
    mask_local_maxima = data > filtered
    coords = np.asarray(np.where(mask_local_maxima)).T
    values = data[mask_local_maxima]

    return coords, values

最佳答案

假设您的数据有某种统计表示,您应该能够执行这样的 3D 局部最大值。希望这能回答您的问题。

import numpy as np
import scipy.ndimage as ndimage

img = np.random.normal(size=(100, 256, 256))

# Get local maximum values of desired neighborhood
# I'll be looking in a 5x5x5 area
img2 = ndimage.maximum_filter(img, size=(5, 5, 5))

# Threshold the image to find locations of interest
# I'm assuming 6 standard deviations above the mean for the threshold
img_thresh = img2.mean() + img2.std() * 6

# Since we're looking for maxima find areas greater than img_thresh

labels, num_labels = ndimage.label(img2 > img_thresh)

# Get the positions of the maxima
coords = ndimage.measurements.center_of_mass(img, labels=labels, index=np.arange(1, num_labels + 1))

# Get the maximum value in the labels
values = ndimage.measurements.maximum(img, labels=labels, index=np.arange(1, num_labels + 1))

关于python - 如何在Python中找到3D数组的局部最大值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55453110/

相关文章:

python - 数字处理二维数组 : dataframe vs series vs array vs numba 的最快方法

python - Python Numpy 中的 Data.Frames

python - 问题导入 scikit-learn : module 'scipy' has no attribute '_lib'

python - Numpy/Scipy 稀疏与密集乘法

python - Telnet 到 Python 服务器卡住

python - 使用 Python 的 Google Kubernetes Engine 中的 OpenCensus 错误

python - 在没有循环的情况下在 numpy 中计算 xi-xj 矩阵(通过 api 调用)

python - ipython 不工作

python - 将输出转换为 numpy 数组

python - 使用 scipy.io savemat 将多个 Python 字典转换为 MATLAB 结构数组