通过血管树的STL模型进行Python-VTK 3D样条回归

som*_*141 5 python graphics regression vtk stl-format

我需要创建维管树模型的样条线或折线表示(请参见下文)。

整个血管树

该模型采用STL格式,因此我具有所有顶点的xyz坐标。这些线应该穿过血管网格的中心,因此我认为最好的方法是通过顶点云进行样条回归另外,如果我可以在给定的点(例如,折线的坐标)上获得容器的半径,那将是很好的。

显示为网格的树的一部分

我浏览了这个论坛和VTK网站(假设他们对这种事情有一个简单的实现),但是到目前为止,我还没有找到可以使用的东西。有谁知道可以做到这一点的Python模块或VTK类(我会从Python调用它)?我在此找到的python模块全部用于2D数据。

非常感谢!

编辑:我遇到了一个名为VMTK的库,该库几乎专门处理血管分割,并具有所谓的“ 中心线计算 ”功能。但是,它们通常要求在其末端“切割”船只并定义“源点”。但是,在我的模型中,可以看到端点被“封顶”,这使事情变得更加复杂。如果找到解决方案,请在此处发布

小智 2

我不知道任何软件或 python 类完全可以解决你的问题。也许 python interpolate.splev 会帮助您处理单个容器。您可以尝试以下代码作为示例:

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

# 3D example
total_rad = 10
z_factor = 3
noise = 0.1

num_true_pts = 200
s_true = np.linspace(0, total_rad, num_true_pts)
x_true = np.cos(s_true)
y_true = np.sin(s_true)
z_true = s_true/z_factor

num_sample_pts = 100
s_sample = np.linspace(0, total_rad, num_sample_pts)
x_sample = np.cos(s_sample) + noise * np.random.randn(num_sample_pts)
y_sample = np.sin(s_sample) + noise * np.random.randn(num_sample_pts)
z_sample = s_sample/z_factor + noise * np.random.randn(num_sample_pts)

tck, u = interpolate.splprep([x_sample,y_sample,z_sample], s=2)
x_knots, y_knots, z_knots = interpolate.splev(tck[0], tck)
u_fine = np.linspace(0,1,num_true_pts)
x_fine, y_fine, z_fine = interpolate.splev(u_fine, tck)

fig2 = plt.figure(2)
ax3d = fig2.add_subplot(111, projection='3d')
# blue line shows true helix
ax3d.plot(x_true, y_true, z_true, 'b')
# red stars show distorted sample around a blue line
ax3d.plot(x_sample, y_sample, z_sample, 'r*')
# green line and dots show fitted curve
ax3d.plot(x_knots, y_knots, z_knots, 'go')
ax3d.plot(x_fine, y_fine, z_fine, 'g')
plt.show()
Run Code Online (Sandbox Code Playgroud)

此代码使用单个容器的嘈杂中心线路径并用平滑曲线对其进行拟合(请参见下面的结果):

插值结果

通常,在 VMTK 中的中心线表示情况下,使用两个用户种子来标记中心线末端。

自动获取中心线的另一种方法是对 stl 网格体进行体素化,构建体素骨架,并分离骨架段来表示每个血管。然后您可以对每条中心线进行插值以获得平滑的曲线。未加工的骨骼片段通常呈锯齿状。