首页 > 解决方案 > 找到分割区域的最大值

问题描述

我有 2 个相同尺寸的 3D 灰度图像。

第一个图像 ( img) 是 3D 体积的原始数据(使用显微镜获得)并包含各种细胞。原始 3d 图像的示例切片

第二个图像 ( imglab) 是原始图像的蒙版版本,其中每个识别的单元格都填充有一个唯一的值(即单元格 1 = 全 1,单元格 2 = 全 2)。所有非单元区域都是零。蒙版 3d 图像的示例切片

我现在试图从与标记的掩码数组对应的原始数据中找到每个单元格的最大值的坐标。

目前,我有一个效率极低的循环。我怀疑有一种方法可以使用单个np.where调用设置多个条件,但我不知道如何做到这一点。电流for循环方法如下:

coordinates = []
for i in range(1, int(imglab.max())): # Number of cells = max value of label image
    max_val = np.max(img[imglab == i])
    max_coord = np.where((img == max_val) & (imglab == i))
    coordinates.append(max_coord)

标签: pythonnumpyimage-processing

解决方案


当很难找到一种高效且兼容 numpy 的编码方式,但是当带有for循环的代码很琐碎时,您可以使用njitfrom numba

它最适合处理平面数组,所以首先让我们在 numba 中编写一个函数,它可以满足您的要求,但在 1d 中:

from numba import njit, int64

@njit
def fast_max_flat(img_flat, imglab_flat):
    n_cells =int(imglab_flat.max())  # number of cells
    max_values = np.full(n_cells, - np.inf)  # stores the n_cells max values seen so far
    max_coords = np.zeros(n_cells, dtype=int64)  # stores the corresponding coordinate
    n_pixels = len(img)
    for i in range(n_pixels):
        label = imglab_flat[i]
        value = img_flat[i]
        if max_values[label] < value:
            max_values[label] = value
            max_coords[label] = i
    return max_coords

然后编写一个 python 包装器来分解数组,应用前面的函数,并以列表的形式检索坐标:

def wrapper(img, imglab):
    dim = img.shape
    coords = fast_max_flat(img.ravel(), imglab.ravel())
    return [np.unravel_index(coord, dim) for coord in coords]

在我的机器上,使用100 x 100 x 1003 个单元格的图像,这比您的方法快约 50 倍。


推荐阅读