使用倾斜光盘屏蔽3D numpy阵列

时间:2017-02-17 11:27:25

标签: python numpy 3d geometry masking

我在使用3D numpy数组的Python2.7中工作,并尝试仅检索落在2D倾斜光盘上的像素。

这是我的代码,用于绘制我感兴趣的光盘边界(=圆圈)

import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D


#creating a 3d numpy array (empty in this example, but will represent a binary 3D image in my application)
space=np.zeros((40,40,20))

r = 8 #radius of the circle
theta = np.pi / 4 # "tilt" of the circle
phirange = np.linspace(0, 2 * np.pi) #to make a full circle

#center of the circle
center=[20,20,10]

#computing the values of the circle in spherical coordinates and converting them
#back to cartesian
for phi in phirange:
    x = r * np.cos(theta) * np.cos(phi) + center[0]
    y=  r*np.sin(phi)  + center[1]
    z=  r*np.sin(theta)* np.cos(phi) + center[2]
    space[int(round(x)),int(round(y)),int(round(z))]=1


x,y,z = space.nonzero()

#plotting
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.scatter(x, y, z, zdir='z', c= 'red')
plt.show()

该图给出了下图:

circle

这是一个好的开始,但现在我想要一种方法只检索位于由圆圈定义的光盘中的space像素的值:下图中粉红色区域中的值(在我的应用程序中,space将是一个3D二进制图像,这里是numpy.zeros()只是为了能够绘制并显示我想要的光盘):

disc

我该怎么办? 我想有一些numpy masking涉及,我理解你将如何在2D中做到这一点(如this question),但我在将此应用于3D时遇到了麻烦。

2 个答案:

答案 0 :(得分:1)

这是数学问题,您应该在Mathematics Stack Exchange网站上提问。

从我的角度来看,您应首先找到光盘所在的表面,然后在该表面内进行面积计算,例如,您在链接问题中提到的方法。

numpymatplotlib这里肯定不对投影负责。

如果没有明确指出它们所处的(或哪种)表面,并且该等式不能保证它是一个平面,则该区域并不意味着什么。

答案 1 :(得分:1)

一种简单的方法是计算光盘平面的法向量。您可以使用球面坐标。确保添加中心,将phi设置为零并交换cos和sin theta,同时在符号上加上减号。

让我们调用那个向量v。平面由v0 * x0 + v1 * x1 + v2 * x2 == c给出你可以通过从你的圆圈插入一个点来计算c。

接下来,您可以为x0和x1创建一个2d网格,并为x2求解。这使得高度x2成为x0,x1网格的函数。对于这些点,您可以计算距离光盘中心的距离,并丢弃距离太远的点。你确实会使用面具。

最后,根据您想要绘制的精确度,您可以将x2值四舍五入为网格单位,但是例如对于曲面图我不会这样做。

要获得一个3d掩码,如你所描述的那样你将绕x2然后从全零空间开始设置光盘像素使用空格[x0,x1,x2] = True。这假设您已经屏蔽了x0,x1,x2,如前所述。