python使⽤vtk库⽣成三维模型
最近在学习python的vtk库,发现相关资料还是⽐较少的,在这⾥总结⼀下本⼈最近学习的⼀些经验
使⽤了The Cancer Imaging Archived的医学图像数据集的标签⽂件
代码参考了下⾯的链接
⾸先读取nii⽂件
def read_nii(filename):
'''
读取nii⽂件,输⼊⽂件路径
'''
reader = vtk.vtkNIFTIImageReader()
reader.SetFileName(filename)
reader.Update()
return reader
然后⽣成三维模型,注意这⾥要⽤ vtkDiscreteMarchingCubes,不能⽤vtkMarchingCubes,后者⽣成的模型不连续,是⼀层⼀层的
def get_mc_contour(file, tvalue):
'''
计算轮廓的⽅法
手机指令>六年级语文下册教学计划
file:读取的vtk类
tvalue:要得到的轮廓的值
'''
contour = vtk.vtkDiscreteMarchingCubes()
contour.SetInputConnection(file.GetOutputPort())
contour.ComputeNormalsOn()
contour.SetValue(0, tvalue)
return contour
然后对模型进⾏平滑
def smoothing(smoothing_iterations, pass_band, feature_angle, contour): '''
使轮廓变平滑
smoothing_iterations:迭代次数
pass_band:值越⼩单次平滑效果越明显
feature_angle:暂时不知道作⽤
为什么离职'''
中长发烫发图片# vtk有两种平滑函数,效果类似
# vtk.vtkSmoothPolyDataFilter()
# smoother = vtk.vtkSmoothPolyDataFilter()
# smoother.SetInputConnection(contour.GetOutputPort())
# smoother.SetNumberOfIterations(50)
# smoother.SetRelaxationFactor(0.6) # 越⼤效果越明显
# vtk.vtkWindowedSincPolyDataFilter()
陶瓷电热水壶
smoother = vtk.vtkWindowedSincPolyDataFilter()
smoother.SetInputConnection(contour.GetOutputPort())
smoother.SetNumberOfIterations(smoothing_iterations)
铁观音属于红茶吗smoother.BoundarySmoothingOff()
smoother.FeatureEdgeSmoothingOff()
smoother.SetFeatureAngle(feature_angle)
smoother.SetPassBand(pass_band)
smoother.NonManifoldSmoothingOn()
王建林smoother.NormalizeCoordinatesOn()
smoother.Update()
return smoother
可视化模型
def singledisplay(obj):
mapper = vtk.vtkPolyDataMapper()
mapper.SetInputConnection(obj.GetOutputPort())
mapper.ScalarVisibilityOff()
actor = vtk.vtkActor()
actor.SetMapper(mapper)
renderer = vtk.vtkRenderer()
renderer.SetBackground([0.1, 0.1, 0.5])
renderer.AddActor(actor)
window = vtk.vtkRenderWindow()
window.SetSize(512, 512)
pu皮质window.AddRenderer(renderer)
interactor = vtk.vtkRenderWindowInteractor()
interactor.SetRenderWindow(window)
# 开始显⽰
window.Render()
interactor.Initialize()
interactor.Start()
export_obj(window)
return window
def multidisplay(obj):
# This ts the block at flat index 3 red
# Note that the index is the flat index in the tree, so the whole multiblock # is index 0 and the blocks are flat indexes 1, 2 and 3. This affects
# the block returned by mbds.GetBlock(2).
colors = vtk.vtkNamedColors()
mapper = vtk.vtkCompositePolyDataMapper2()
mapper.SetInputDataObject(obj)
cdsa = vtk.vtkCompositeDataDisplayAttributes()
mapper.SetCompositeDataDisplayAttributes(cdsa)
# 上⾊
mapper.SetBlockColor(3, colors.GetColor3d('Red'))
mapper.SetBlockColor(1, colors.GetColor3d('LavenderBlush'))
mapper.SetBlockColor(2, colors.GetColor3d('Lavender'))
mapper.SetBlockColor(4, colors.GetColor3d('Green'))
mapper.SetBlockColor(5, colors.GetColor3d('Yellow'))
actor = vtk.vtkActor()
actor.SetMapper(mapper)
# Create the Renderer, RenderWindow, and RenderWindowInteractor. renderer = vtk.vtkRenderer()
renderWindow = vtk.vtkRenderWindow()
renderWindow.AddRenderer(renderer)
renderWindowInteractor = vtk.vtkRenderWindowInteractor()
renderWindowInteractor.SetRenderWindow(renderWindow)
# Enable ur interface interactor.
renderer.AddActor(actor)
renderer.SetBackground(colors.GetColor3d('SteelBlue'))
renderWindow.SetWindowName('CompositePolyDataMapper')
renderWindow.Render()
renderWindowInteractor.Start()
最后,主函数,设置⼀下各参数
def write_ply(obj, save_dir, color):
'''
输⼊必须是单个模型,vtkMultiBlockDataSet没有GetOutputPort()类 '''
plyWriter = vtk.vtkPLYWriter()
plyWriter.SetFileName(save_dir)
plyWriter.SetColorModeToUniformCellColor()
plyWriter.SetColor(color[0], color[1], color[2])
plyWriter.SetInputConnection(obj.GetOutputPort())
plyWriter.Write()