添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接
相关文章推荐
睡不着的山楂  ·  TortoiseGit ...·  8 月前    · 
近视的烈马  ·  JDO持久 (jdbc ejb) - ...·  1 年前    · 

本文介绍了Python VTK映射三维模型表面距离,通过如何使用VTK计算两个三维模型(stl)的表面距离,并将其距离值以颜色映射到模型,可用于对比 两相模型的相似度;

我使用同一个stl 模型,旋转了一点,进行对比,原点是黄色,旋转最少:

实现步骤:

数据准备: 需要准备两个stl文件、Python需要安装vtk库

步骤一:数据读取 首先通过 vtk.vtkSTLReader() 定义stl文件读取接口,再通过 reader1.GetOutput() 就可以获得stl在vtk工作流的数据。

步骤二:去除重复点 通过 vtk.vtkCleanPolyData() 可以去除模型中的重复点

步骤三:计算距离 使用 vtk.vtkDistancePolyDataFilter() ,使用上一步中过滤掉重复点后的数据作为输入。如 distanceFilter.SetInputConnection(1, clean1.GetOutputPort()) , 其中第一个参数就是输入数据的标号,从0开始计数;第二个参数就是输入的数据。我们将vtkDistancePolyDataFilter的输出到mapper就完成距离映射了。

步骤四:颜色配置 lut = vtk.vtkLookupTable() 相当于一个调色盘函数,通过对其参数改变可以,调整最终映射的颜色范围。 scalarBar = vtk.vtkScalarBarActor() 就是颜色条,按照前面的调色盘的结果将距离数值映射成颜色。

Code:

import vtk
input1 = vtk.vtkPolyData()
reader1 = vtk.vtkSTLReader()
reader1.SetFileName('leftlumen.stl')
reader1.Update()
input1 = reader1.GetOutput()  # 读取模型A
input2 = vtk.vtkPolyData()
input2.DeepCopy(input1)
pTransformSTL = vtk.vtkTransform()
pTransformSTL.RotateY(0.1)
pTransformSTL.Update()
transFilter = vtk.vtkTransformPolyDataFilter()
transFilter.SetInputData(input2)
transFilter.SetTransform(pTransformSTL)
transFilter.Update()
# 数据合并,可以合并显示两个模型
clean1 = vtk.vtkCleanPolyData()
clean1.SetInputData(input1)
clean2 = vtk.vtkCleanPolyData()
clean2.SetInputData(transFilter.GetOutput())
distanceFilter = vtk.vtkDistancePolyDataFilter()
distanceFilter.SetInputConnection(1, clean1.GetOutputPort())
distanceFilter.SetInputConnection(0, clean2.GetOutputPort())
distanceFilter.SignedDistanceOff()
distanceFilter.Update()  # 计算距离
distanceFilter.GetOutputPort()
mapper = vtk.vtkPolyDataMapper()  # 配置mapper
mapper.SetInputConnection(distanceFilter.GetOutputPort())
mapper.SetScalarRange(  # 设置颜色映射范围
    distanceFilter.GetOutput().GetPointData().GetScalars().GetRange()[0],
    distanceFilter.GetOutput().GetPointData().GetScalars().GetRange()[1])
actor = vtk.vtkActor()
actor.SetMapper(mapper)
actor1 = vtk.vtkActor()
actor1.SetMapper(mapper)
lut = vtk.vtkLookupTable()
lut.SetHueRange(0.2, 0.7)  # 映射的颜色变换参数(自己调颜色)
# lut.SetAlphaRange(1.0, 1.0)
# lut.SetValueRange(1.0, 1.0)
# lut.SetSaturationRange(1.0, 1.0)
# lut.SetNumberOfTableValues(256)
mapper.SetLookupTable(lut)
mapper2 = vtk.vtkPolyDataMapper()
mapper2.SetInputData((distanceFilter.GetSecondDistanceOutput()))
mapper2.SetScalarRange(  # 设置颜色映射范围
    distanceFilter.GetSecondDistanceOutput().GetPointData().GetScalars().GetRange()[0],
    distanceFilter.GetSecondDistanceOutput().GetPointData().GetScalars().GetRange()[1])
actor2 = vtk.vtkActor()
actor2.SetMapper(mapper2)
scalarBar = vtk.vtkScalarBarActor()  # 设置color_bar
scalarBar.SetLookupTable(mapper.GetLookupTable())
scalarBar.SetTitle("SD(mm)")
scalarBar.SetNumberOfLabels(5)  # 设置要显示的刻度标签数。自己设定色带的位置
scalarBar.SetMaximumNumberOfColors(10)
# scalarBar.GetPositionCoordinate().SetCoordinateSystemToNormalizedViewport()
# scalarBar.GetPositionCoordinate().SetValue(0.01, 0.49)  # 参数越小越靠左,第二个参数越大越往上
# scalarBar.SetWidth(0.16)
# scalarBar.SetHeight(0.5)
# scalarBar.SetTextPositionToPrecedeScalarBar()  # 标题和刻度标记是否应在标量栏之前(文字会出现在条形左边)
# # 设置标题和条形之间的边距
# scalarBar.SetVerticalTitleSeparation(10)
# # 设置标题颜色
scalarBar.DrawTickLabelsOn()
scalarBar.GetTitleTextProperty().SetColor(0, 0, 0)
scalarBar.GetLabelTextProperty().SetColor(0, 0, 0)
arender = vtk.vtkRenderer()
arender.SetViewport(0, 0.0, 1, 1.0)
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(arender)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)
style = vtk.vtkInteractorStyleTrackballActor()
iren.SetInteractorStyle(style)
aCamera = vtk.vtkCamera()
aCamera.SetViewUp(0, 0, -1)
aCamera.SetPosition(0, -1, 0)
aCamera.ComputeViewPlaneNormal()
aCamera.Azimuth(30.0)
aCamera.Elevation(30.0)
aCamera.Dolly(1.5)
arender.AddActor(actor)
# arender.AddActor(actor1)
arender.SetActiveCamera(aCamera)
arender.ResetCamera()
arender.SetBackground(1, 1, 1)
arender.ResetCameraClippingRange()
arender.AddActor2D(scalarBar)
renWin.Render()
iren.Initialize()
iren.Start()
				
三维可视化系统的建立依赖于三维图形平台, 如 OpenGL、VTK、OGRE、OSG等, 传统的方法多采用OpenGL进行底层编程,即对其特有的函数进行定量操作, 需要开发人员熟悉相关函数, 从而造成了开发难度大、 周期长等问题。VTK、 ORGE、OSG等平台使用封装更好的函数简化了开发过程。下面将使用PythonVTK进行机器人上位机监控界面的快速原型开发。   完整的上位机程序需要有三维显示模块、机器人信息监测模块(位置/角度/速度/电量/温度/错误信息…)、通信模块(串口/USB/WIFI/蓝牙…)、控制模块等功能模块。三维显示模块主要用于实时显示机器人的姿态(或位置)信息。比如机器
pySlice Matthew Else用Python编写的3D模型切片算法。 书面形式,首先是因为我需要使用Python编写的漂亮算法,其次是因为替代解决方案均已获得AGPL的许可,并且我需要一种自己的解决方案,该解决方案可以在没有其他任何源代码的情况下用于商业用途。 该代码当前仅支持以下文件格式: 我计划可能支持其他格式,例如OBJ,但是目前STL还不错。 它当前无法生成G代码,它所需要的只是for循环以生成所有层。 如果您成功或不成功地测试pySlice,请在Github的问题部分中告诉我。 pySlice.py已获得MIT许可。
VTK在Java, Tcl, Python中都有接口 ,本文介绍VTKPython中的接口。 VTK (The Visualization Toolkit) 是一款用于计算机3D成像、构建模型、图像处理、容积渲染、科学数据可视化等方面的免费软件系统,支持Linux, Windows, Mac, Web, mobile devices等平台; 一些使用场景????????
virtual int IsA(const char * type) 如果此类与指定类的类型(或子类)相同,则返回1。 void PrintSelf(ostream&os,vtkIndent indent) print调用的方法打印有关对象的信息,包括超类。 int HasTranslucentPolygonalGeometry() 这个道具有一些半透明的多边形几何形状吗? void Re...
上面4张图分别是是否使用颜色“lightgrey”和是否显示坐标系的效果。 我们使用 numpy-stl 和 matplotlib,进行加载读取和绘制保存。源码如下。 from mpl_toolkits import mplot3d from matplotlib imp
因为工作原因需要使用OCC库解析模型文件,分享下过程中遇到的知识点。 但是python OCC的资料比较少,所以一般只能参考下官方或者其他人的案例,然后浏览一些相关书籍。关于里面的API其实都可以查找OCC的C++网站查找,懂C++的很好看懂,不懂的也不会说特别难看懂,下面是API网站 OCC C++ API 好,直接进入正题,在上面那个网站搜索brep,stl,step都可以查找到对应的api。...
```python reader = vtk.vtkDICOMImageReader() reader.SetDirectoryName("Your DICOM directory path") reader.Update() 3. 设置渲染器和窗口 ```python ren = vtk.vtkRenderer() renWin = vtk.vtkRenderWindow() renWin.AddRenderer(ren) iren = vtk.vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) 4. 创建体绘制算法 ```python volumeMapper = vtk.vtkSmartVolumeMapper() volumeMapper.SetInputConnection(reader.GetOutputPort()) 5. 创建体绘制属性 ```python volumeProperty = vtk.vtkVolumeProperty() volumeProperty.SetColor(vtk.vtkColorTransferFunction()) volumeProperty.SetScalarOpacity(vtk.vtkPiecewiseFunction()) volumeProperty.ShadeOn() volumeProperty.SetInterpolationTypeToLinear() 6. 设置体绘制属性 ```python # 设置颜色和透明度 colorFunc = vtk.vtkColorTransferFunction() colorFunc.AddRGBPoint(-3024, 0.0, 0.0, 0.0) colorFunc.AddRGBPoint(-77, 0.54902, 0.25098, 0.14902) colorFunc.AddRGBPoint(94, 0.882353, 0.603922, 0.290196) colorFunc.AddRGBPoint(179, 1, 0.937033, 0.954531) colorFunc.AddRGBPoint(3071, 1, 1, 1) volumeProperty.SetColor(colorFunc) # 设置不透明度 opacityFunc = vtk.vtkPiecewiseFunction() opacityFunc.AddPoint(-3024, 0.0) opacityFunc.AddPoint(-77, 0.0) opacityFunc.AddPoint(94, 0.29) opacityFunc.AddPoint(179, 0.55) opacityFunc.AddPoint(3071, 0.55) volumeProperty.SetScalarOpacity(opacityFunc) 7. 创建体绘制Actor ```python volume = vtk.vtkVolume() volume.SetMapper(volumeMapper) volume.SetProperty(volumeProperty) ren.AddActor(volume) 8. 启动渲染器和窗口 ```python ren.SetBackground(0.1, 0.2, 0.4) renWin.SetSize(600, 600) iren.Initialize() renWin.Render() iren.Start() 以上是基本的流程,具体实现中还需根据数据类型和需求进行相应的调整。