我有2张等尺寸的3D灰度图像。
第一张图像(img
)是3D体积的原始数据(使用显微镜获得),并且包含各种单元格。 Example slice of raw 3d image
第二张图像(imglab
)是原始图像的蒙版,其中每个标识的单元格都填充有一个唯一的值(即,单元格1 =所有1,单元格2 =所有2s)。所有非单元格区域均为零。 Example slice of masked 3d image
我现在正尝试从与标记的掩码数组相对应的原始数据中找到每个单元格最大值的坐标。
当前,我有一个效率极低的循环。我怀疑有一种方法可以使用单个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)
答案 0 :(得分:0)
当很难找到一种有效的编码方式并与numpy兼容时,但是如果使用for
循环的代码很琐碎,则可以使用njit
中的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]
在我的计算机上,具有3个单元格的100 x 100 x 100
图像,这比您的方法快50倍。