计算 3D 球面掩膜的直径线
Computing diameter-lines of a 3D spherical mask
背景
对于我正在研究的算法,我目前使用 3D 球体作为二进制掩码,NxNxN
数组在半径为 N//2
的球体中具有体素作为 True
.进一步处理对每个体素进行计算,设置为 True
.
随着 N
变大 = O(N^3),事实证明它对我的特定任务来说是计算密集型的,所以我现在想将我的二进制掩码减少为从阵列中心在半径内辐射的线的子样本。
Objective
我想要图像中灰色线条的 3D 二值掩码。
为了稍微控制体素的数量,我将有一个参数(比如 l
)调节每个 2D 圆中采样的线数,也许还有第二个参数(k
?) 为 z 旋转的次数。
我试过的
我正在使用 numpy 和 scipy,我认为我可以使用 scipy.ndimage.interpolation.rotate 方法在平面上旋转一条线,然后使用完整的 2D 蒙版围绕z 轴。
这被证明是困难的,因为插值使用了一些关于样条的深层魔法,这些样条在旋转时丢弃了我的真值。
我想我可以通过遵循一些线性方程从数学上计算出哪个体素应该设置为 True,但我找不到它们。
知道怎么去吗?
更新:解决方案!
感谢 jkalden 帮助我思考了这个问题并提供了代码示例,我得到了这个 :
rmax
是球体的半径,n_theta
和 n_phi
要使用的极线和方位角线的数量。
out_mask = np.zeros((rmax*2,) * 3, dtype=bool)
# for each phi = one circle in azimutal circles
for phi in np.linspace(0, np.deg2rad(360), n_phi,endpoint=False):
# for all lines in polar circle of this azimutal circle
for theta in np.linspace(0, np.deg2rad(360), n_theta,endpoint=False):
# for all distances (0-rmax) in these lines
for r in range(rmax):
coords = spherical_to_cartesian([r, theta, phi]) + rmax
out_mask[tuple(coords)] = True
来自 this code sample 的 spherical_to_cartesian
。
这给了我这个(rmax = 50
和 n_theta = n_phi = 8
):
(中心区域被我选择调出了功能)
我建议将坐标系改为spherical coordinates。因此,您将通过方位角选择 2D 圆,然后通过另外选择极角来定义一条线。沿线的变量就是半径,您可以使用“numpy.linspace”来离散化它。这样做还可以节省计算时间。
您可以随时使用实现的双射关系切换坐标系,例如here or here.
背景
对于我正在研究的算法,我目前使用 3D 球体作为二进制掩码,NxNxN
数组在半径为 N//2
的球体中具有体素作为 True
.进一步处理对每个体素进行计算,设置为 True
.
随着 N
变大 = O(N^3),事实证明它对我的特定任务来说是计算密集型的,所以我现在想将我的二进制掩码减少为从阵列中心在半径内辐射的线的子样本。
Objective
我想要图像中灰色线条的 3D 二值掩码。
为了稍微控制体素的数量,我将有一个参数(比如 l
)调节每个 2D 圆中采样的线数,也许还有第二个参数(k
?) 为 z 旋转的次数。
我试过的
我正在使用 numpy 和 scipy,我认为我可以使用 scipy.ndimage.interpolation.rotate 方法在平面上旋转一条线,然后使用完整的 2D 蒙版围绕z 轴。 这被证明是困难的,因为插值使用了一些关于样条的深层魔法,这些样条在旋转时丢弃了我的真值。
我想我可以通过遵循一些线性方程从数学上计算出哪个体素应该设置为 True,但我找不到它们。
知道怎么去吗?
更新:解决方案!
感谢 jkalden 帮助我思考了这个问题并提供了代码示例,我得到了这个 :
rmax
是球体的半径,n_theta
和 n_phi
要使用的极线和方位角线的数量。
out_mask = np.zeros((rmax*2,) * 3, dtype=bool)
# for each phi = one circle in azimutal circles
for phi in np.linspace(0, np.deg2rad(360), n_phi,endpoint=False):
# for all lines in polar circle of this azimutal circle
for theta in np.linspace(0, np.deg2rad(360), n_theta,endpoint=False):
# for all distances (0-rmax) in these lines
for r in range(rmax):
coords = spherical_to_cartesian([r, theta, phi]) + rmax
out_mask[tuple(coords)] = True
来自 this code sample 的 spherical_to_cartesian
。
这给了我这个(rmax = 50
和 n_theta = n_phi = 8
):
我建议将坐标系改为spherical coordinates。因此,您将通过方位角选择 2D 圆,然后通过另外选择极角来定义一条线。沿线的变量就是半径,您可以使用“numpy.linspace”来离散化它。这样做还可以节省计算时间。
您可以随时使用实现的双射关系切换坐标系,例如here or here.