Python 三维坐标x、y、z到三维numpy阵列

Python 三维坐标x、y、z到三维numpy阵列,python,numpy,mask,quaternions,scikit-image,Python,Numpy,Mask,Quaternions,Scikit Image,我有一个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

我有一个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就可以重建你的面具,这是不可能的。因为您丢失了未填充内容的信息。想象一下,你的椭球体位于一个巨大立方体的一角。你怎么知道(只知道椭球的外观),立方体有多大

关于你的第二个问题:

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

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
根据旋转示例,现在可以并排打印两个遮罩(具有相同形状):


您可以直接使用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就可以重建你的面具,这是不可能的。因为您丢失了未填充内容的信息。想象一下,你的椭球体位于一个巨大立方体的一角。你怎么知道(只知道椭球的外观),立方体有多大

关于你的第二个问题:

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

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
注意:

  • 旧的遮罩\u形状
    应与要应用遮罩的图像的形状相同
  • 如果您想要一个
    True
    掩码而不是
    False
    掩码(如果您想要椭球体部分为
    True
    和其他任何
    False
    ),只需在上述两行代码中交换
    True
    False

  • 如果您知道旧面具的形状,请尝试以下方法:

    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
    
    注意:

  • 旧的遮罩\u形状
    应与要应用遮罩的图像的形状相同
  • 如果您想要一个
    True
    掩码而不是
    False
    掩码(如果您想要椭球体部分为
    True
    和其他任何
    False
    ),只需在上述两行代码中交换
    True
    False

  • 请删除字体的粗体:-)请删除字体的粗体:-)感谢您的回答,该方法仅在知道x、y、z时工作良好。但我想旋转坐标,这将给我一组新的坐标x1,y1,z1,并根据我在问题中编辑的坐标构建新的_掩码。这给了我一个你解释的错误。@Astro,我回答了你的第二个问题。也许代码还不够完美,因为你们可以在角落里看到一些工件,所以你们可以稍微调整一下。和我的原始数据集成时可能会出现一些问题。例如,椭球体的形状看起来不像预期的完整椭球体(在副视图中进行视觉观察)。但我认为上述问题得到了很好的回答。我可以试着修改它。再次感谢。谢谢你的回答,这个方法只有在知道x,y,z的情况下才有效。但我想旋转坐标,这将给我一组新的坐标x1,y1,z1,并根据我在问题中编辑的坐标构建新的_掩码。这给了我一个你解释的错误。@Astro,我回答了你的第二个问题。也许代码还不够完美,因为你们可以在角落里看到一些工件,所以你们可以稍微调整一下。和我的原始数据集成时可能会出现一些问题。例如,椭球体的形状看起来不像预期的完整椭球体(在副视图中进行视觉观察)。但我认为上述问题得到了很好的回答。我可以试着修改它。再次感谢。这确实适用于遮罩的x,y,z坐标。实际上我想要x1,y1,z1,它们是旋转x,y,z 90度的坐标,正如我在问题中编辑的。因此,该方法仅适用于x,y,z,但不适用于x1,y1,z1。好吧,您在问题中添加了第二部分,但第二部分面临的要求或问题不清楚。你有什么错误吗?您是否尝试在旋转后绘制椭球体(我不确定是否可能,如果可能,与您面临的实际问题/错误相关),这确实适用于遮罩的x、y、z坐标。实际上我想要x1,y1,z1,它们是旋转x,y,z 90度的坐标,正如我在问题中编辑的。因此,方法o