我在使用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()
该图给出了下图:
这是一个好的开始,但现在我想要一种方法只检索位于由圆圈定义的光盘中的space
像素的值:下图中粉红色区域中的值(在我的应用程序中,space
将是一个3D二进制图像,这里是numpy.zeros()只是为了能够绘制并显示我想要的光盘):
我该怎么办? 我想有一些numpy masking涉及,我理解你将如何在2D中做到这一点(如this question),但我在将此应用于3D时遇到了麻烦。
答案 0 :(得分:1)
这是数学问题,您应该在Mathematics Stack Exchange网站上提问。
从我的角度来看,您应首先找到光盘所在的表面,然后在该表面内进行面积计算,例如,您在链接问题中提到的方法。
numpy
或matplotlib
这里肯定不对投影负责。
如果没有明确指出它们所处的(或哪种)表面,并且该等式不能保证它是一个平面,则该区域并不意味着什么。
答案 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,如前所述。