我有两个相同尺寸的三维灰度图像。
第一幅图像(img
)是3D体积(使用显微镜获得)的原始数据,包含各种细胞。Example slice of raw 3d image
第二个图像(imglab
)是原始图像的遮罩版本,其中每个标识的单元格都填充一个唯一的值(即单元格1=所有1,单元格2=所有2)。所有非单元区域都是零。Example slice of masked 3d image
现在,我试图从对应于标记的掩码阵列的原始数据中找到每个单元的最大值的坐标。
目前,我有一个非常低效的循环。我怀疑有一种方法可以使用一个np.where
调用设置多个条件,但我不知道如何做到这一点。电流回路法如下:
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)
最佳答案
当很难找到一种高效且与numpy兼容的编码方式时,但是当带有for
循环的代码微不足道时,可以使用njit
fromnumba
。
处理平面数组最有效,所以首先让我们用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]
在我的机器上,有3个细胞的图像,这比你的方法快50倍。
关于python - 查找分段区域的最大值,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52291284/