3d 坐标 x,y,z 到 3d numpy 数组

3d coordinates x,y,z to 3d numpy array

我有一个椭圆形的 3d 蒙版。我使用 np.argwhere 提取了掩码的坐标。在示例代码中,坐标可以指定为 x、y、z。我的问题是如何从坐标 x、y、z 取回我的掩码(以相同形状的 3d numpy 或布尔数组的形式)?

import numpy as np
import scipy
import skimage
from skimage import draw

mask = skimage.draw.ellipsoid(10,12,18)
print mask.shape 

coord = np.argwhere(mask)

x = coord[:,0]
y = coord[:,1]
z = coord[:,2]

上面的代码为我提供了形状 (23, 27, 39) 的布尔掩码,现在我想使用 x、y、z 坐标构造完全相同形状的相同掩码。怎么做到的?

我想稍微修改一下上面的问题。现在,如果我使用四元数旋转我的坐标,这将给我新的坐标集,然后使用新坐标 x1,y1,z1 我想构建形状为 (23,27,39) 的布尔掩码作为原始掩码?怎么办?

import quaternion
angle1 = 90
rotation = np.exp(quaternion.quaternion(0,0, 1) * angle1*(np.pi/180) / 2)
coord_rotd = quaternion.rotate_vectors(rotation, coord)
x1 = coord_rotd[:,0]
y1 = coord_rotd[:,1]
z1 = coord_rotd[:,2]

您可以直接使用 x、y 和 z 来重建您的蒙版。首先,使用一个与您的面具形状相同的新阵列。我预先用零填充了所有内容(即 False)。接下来,将 x、y 和 z 定义的每个坐标设置为 True:

new_mask = np.zeros_like(mask)
new_mask[x,y,z] = True

# Check if mask and new_mask is the same
np.allclose(mask, new_mask)
# True

如果你问,如果你能知道 x、y 和 z 来重建你的掩码,这是不可能的。因为你丢失了 not 填充的信息。想象一下,将椭圆体放在一个巨大立方体的一角。你怎么知道(只知道椭圆体的样子)立方体有多大?

关于你的第二个问题:

你必须确定你的坐标,因为它们可能会超出你的风景。所以我定义了一个函数来处理这个:

def fixCoordinates(coord, shape):
    # move to the positive edge
    #  remove negative indices
    #  you can also add now +1 to 
    #  have a margin around your ellipse
    coord -= coord.min(0)

    # trim coordinates outside of scene
    for i, s in enumerate(shape):
        coord[coord[:,i] >= s] = s-1

    # Return coordinates and change dtype
    return coord.astype(np.int)

如果你稍微修改你的代码,你可以使用与以前相同的策略:

# your code
import quaternion
angle1 = 90
rotation = np.exp(quaternion.quaternion(0,0, 1) * angle1*(np.pi/180) / 2)
coord_rotd = quaternion.rotate_vectors(rotation, coord_rotd)

# Create new mask
new_mask2 = np.zeros_like(new_mask)
# Fix coordinates
coord_rotd = fixCoordinates(coord_rotd, mask.shape)

x1 = coord_rotd[:,0]
y1 = coord_rotd[:,1]
z1 = coord_rotd[:,2]

# create new mask, similar as before
new_mask2[x1, y1, z1] = True

鉴于您的示例旋转,您现在可以并排绘制两个蒙版(具有相同形状):

如果您知道旧面具的形状,试试这个:

new_mask = np.full(old_mask_shape, True) # Fill new_mask with True everywhere
new_mask[x,y,z] = False                  # Set False for the ellipsoid part alone

注:

  1. old_mask_shape 应与您打算应用蒙版的 图像的形状相同
  2. 如果您想要 True 掩码而不是 False 掩码(如果您希望椭圆体部分为 True 以及其他任何地方 False),只需互换 TrueFalse在上面两行代码中。