news 2026/2/19 1:31:01

AnatomicalOrientation 3D人体模型及三个人体标准解剖学平面展示

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
AnatomicalOrientation 3D人体模型及三个人体标准解剖学平面展示

一:主要的知识点

1、说明

本文只是教程内容的一小段,因博客字数限制,故进行拆分。主教程链接:vtk教程——逐行解析官网所有Python示例-CSDN博客

2、知识点纪要

本段代码主要涉及的有①vtkOrientationMarkerWidget控制相机的小部件


二:代码及注释

import vtkmodules.vtkRenderingOpenGL2 import vtkmodules.vtkInteractionStyle from vtkmodules.vtkCommonColor import vtkNamedColors from vtkmodules.vtkRenderingCore import vtkActor, vtkRenderWindow, vtkRenderWindowInteractor, vtkRenderer, \ vtkPolyDataMapper, vtkPropAssembly from vtkmodules.vtkRenderingAnnotation import vtkAnnotatedCubeActor, vtkAxesActor from vtkmodules.vtkInteractionWidgets import vtkOrientationMarkerWidget from vtkmodules.vtkIOXML import vtkXMLPolyDataReader from vtkmodules.vtkFiltersSources import vtkPlaneSource from vtkmodules.vtkCommonTransforms import vtkTransform from vtkmodules.vtkFiltersGeneral import vtkTransformPolyDataFilter from vtkmodules.vtkRenderingFreeType import vtkVectorText def main(): colors = vtkNamedColors() fileName = "Data/Human.vtp" ren = vtkRenderer() renWin = vtkRenderWindow() renWin.SetSize(780, 780) renWin.AddRenderer(ren) iren = vtkRenderWindowInteractor() iren.SetRenderWindow(renWin) xyzLabels = ['X', 'Y', 'Z'] scale = [1.5, -1.5, 1.5] axes = MakeCubeActor(scale, xyzLabels, colors) """ vtkOrientationMarkerWidget 一个可以显示在渲染窗口角落的小部件,可以用来指示当前相机的方向 典型用法是在屏幕右下角显示一个小的三维坐标轴(X、Y、Z) 也可以自定义设置方向标识,如在本案例中是设置了cube与axes的结合体作为方向标识 """ om = vtkOrientationMarkerWidget() om.SetOrientationMarker(axes) # 设置方向标识(可以是任何 vtkProp) om.SetViewport(0.0, 0.8, 0.2, 1.0) # 设置小部件的显示区域,Xmin, Ymin, Xmax, Ymax om.SetInteractor(iren) om.EnabledOn() # 启用 om.InteractiveOn() # 允许被用户拖动 scale = [1.5, 1.5, 1.5] axes1 = MakeCubeActor(scale, xyzLabels, colors) om1 = vtkOrientationMarkerWidget() om1.SetOrientationMarker(axes1) om1.SetViewport(0, 0, 0.2, 0.2) om1.SetInteractor(iren) om1.EnabledOn() om1.InteractiveOn() scale = (-1.5, -1.5, 1.5) axes2 = MakeCubeActor(scale, xyzLabels, colors) om2 = vtkOrientationMarkerWidget() om2.SetOrientationMarker(axes2) # Position lower right in the viewport. om2.SetViewport(0.8, 0, 1.0, 0.2) om2.SetInteractor(iren) om2.EnabledOn() om2.InteractiveOn() axes3 = MakeAnnotatedCubeActor(colors) om3 = vtkOrientationMarkerWidget() om3.SetOrientationMarker(axes3) # Position upper right in the viewport. om3.SetViewport(0.8, 0.8, 1.0, 1.0) om3.SetInteractor(iren) om3.EnabledOn() om3.InteractiveOn() reader = vtkXMLPolyDataReader() reader.SetFileName(fileName) reader.Update() huamnMapper = vtkPolyDataMapper() huamnMapper.SetInputConnection(reader.GetOutputPort()) huamnMapper.SetScalarModeToUsePointFieldData() huamnMapper.SelectColorArray("Color") huamnMapper.SetColorModeToDirectScalars() humanActor = vtkActor() humanActor.SetMapper(huamnMapper) bounds = humanActor.GetBounds() # Scale the actor humanActor.SetScale(1.0 / max(bounds)) ren.AddActor(humanActor) # 三个界面的actor actors = MakePlanesActors(colors) for actor in actors: ren.AddViewProp(actor) # 给每个平面添加一个标签 textActors = AddTextToPlanes() for actor in textActors: ren.AddViewProp(actor) ren.SetBackground2(colors.GetColor3d('OldLace')) ren.SetBackground(colors.GetColor3d('MistyRose')) ren.GradientBackgroundOn() ren.ResetCamera() ren.GetActiveCamera().Zoom(1.6) ren.GetActiveCamera().SetPosition(-2.3, 4.1, 4.2) ren.GetActiveCamera().SetViewUp(0.0, 0.0, 1.0) ren.ResetCameraClippingRange() renWin.Render() renWin.SetWindowName('AnatomicalOrientation') iren.Initialize() iren.Start() def AddTextToPlanes(): textActors = [] scale = [0.04, 0.04, 0.04] text1 = vtkVectorText() text1.SetText('Transverse\nPlane\n\nSuperior\nCranial') trnf1 = vtkTransform() trnf1.RotateZ(-90) tpdPlane1 = vtkTransformPolyDataFilter() tpdPlane1.SetTransform(trnf1) tpdPlane1.SetInputConnection(text1.GetOutputPort()) textMapper1 = vtkPolyDataMapper() textMapper1.SetInputConnection(tpdPlane1.GetOutputPort()) textActor1 = vtkActor() textActor1.SetMapper(textMapper1) textActor1.SetScale(scale) textActor1.AddPosition(0.4, 0.49, 0.01) textActors.append(textActor1) text2 = vtkVectorText() text2.SetText('Transverse\nPlane\n\nInferior\n(Caudal)') trnf2 = vtkTransform() trnf2.RotateZ(270) trnf2.RotateWXYZ(*[180, 0, 1, 0]) tpdPlane2 = vtkTransformPolyDataFilter() tpdPlane2.SetTransform(trnf2) tpdPlane2.SetInputConnection(text2.GetOutputPort()) textMapper2 = vtkPolyDataMapper() textMapper2.SetInputConnection(tpdPlane2.GetOutputPort()) textActor2 = vtkActor() textActor2.SetMapper(textMapper2) textActor2.SetScale(scale) textActor2.AddPosition(0.4, -0.49, -0.01) textActors.append(textActor2) text3 = vtkVectorText() text3.SetText('Sagittal\nPlane\n\nLeft') trnf3 = vtkTransform() trnf3.RotateX(90) trnf3.RotateWXYZ(*[-90, 0, 1, 0]) tpdPlane3 = vtkTransformPolyDataFilter() tpdPlane3.SetTransform(trnf3) tpdPlane3.SetInputConnection(text3.GetOutputPort()) textMapper3 = vtkPolyDataMapper() textMapper3.SetInputConnection(tpdPlane3.GetOutputPort()) textActor3 = vtkActor() textActor3.SetMapper(textMapper3) textActor3.SetScale(scale) textActor3.AddPosition(-0.01, 0.49, 0.4) textActors.append(textActor3) text4 = vtkVectorText() text4.SetText('Sagittal\nPlane\n\nRight') trnf4 = vtkTransform() trnf4.RotateX(90) trnf4.RotateWXYZ(*[-270, 0, 1, 0]) tpdPlane4 = vtkTransformPolyDataFilter() tpdPlane4.SetTransform(trnf4) tpdPlane4.SetInputConnection(text4.GetOutputPort()) textMapper4 = vtkPolyDataMapper() textMapper4.SetInputConnection(tpdPlane4.GetOutputPort()) textActor4 = vtkActor() textActor4.SetMapper(textMapper4) textActor4.SetScale(scale) textActor4.AddPosition(0.01, -0.49, 0.4) textActors.append(textActor4) text5 = vtkVectorText() text5.SetText('Coronal\nPlane\n\nAnterior') trnf5 = vtkTransform() trnf5.RotateY(-180) trnf5.RotateWXYZ(*[-90, 1, 0, 0]) tpdPlane5 = vtkTransformPolyDataFilter() tpdPlane5.SetTransform(trnf5) tpdPlane5.SetInputConnection(text5.GetOutputPort()) textMapper5 = vtkPolyDataMapper() textMapper5.SetInputConnection(tpdPlane5.GetOutputPort()) textActor5 = vtkActor() textActor5.SetMapper(textMapper5) textActor5.SetScale(scale) textActor5.AddPosition(0.49, 0.01, 0.20) textActors.append(textActor5) text6 = vtkVectorText() text6.SetText('Coronal\nPlane\n\nPosterior') trnf6 = vtkTransform() trnf6.RotateWXYZ(*[90, 1, 0, 0]) tpdPlane6 = vtkTransformPolyDataFilter() tpdPlane6.SetTransform(trnf6) tpdPlane6.SetInputConnection(text6.GetOutputPort()) textMapper6 = vtkPolyDataMapper() textMapper6.SetInputConnection(tpdPlane6.GetOutputPort()) textActor6 = vtkActor() textActor6.SetMapper(textMapper6) textActor6.SetScale(scale) textActor6.AddPosition(-0.49, -0.01, 0.3) textActors.append(textActor6) return textActors def MakePlanesActors(colors): planes = [] mappers = [] actors = [] resolution = [10, 10] origin = [0.0, 0.0, 0.0] point1 = [1, 0, 0] point2 = [0, 1, 0] planes.append(MakePlane(resolution, origin, point1, point2, [0, 0, 0, 0], [-0.5, -0.5, 0])) # x-y plane planes.append(MakePlane(resolution, origin, point1, point2, [-90, 1, 0, 0], [-0.5, -0.5, 0.0])) # x-z plane planes.append(MakePlane(resolution, origin, point1, point2, [-90, 0, 1, 0], [-0.5, -0.5, 0.0])) # y-z plane for plane in planes: mapper = vtkPolyDataMapper() mapper.SetInputConnection(plane.GetOutputPort()) actor = vtkActor() actor.SetMapper(mapper) mappers.append(mapper) actors.append(actor) actors[0].GetProperty().SetColor(colors.GetColor3d('SeaGreen')) # Transverse plane actors[1].GetProperty().SetColor(colors.GetColor3d('DeepSkyBlue')) # Coronal plane actors[2].GetProperty().SetColor(colors.GetColor3d('Tomato')) # Saggital plane return actors def MakePlane(resolution, origin, point1, point2, wxyz, translate): plane = vtkPlaneSource() plane.SetResolution(*resolution) plane.SetOrigin(origin) plane.SetPoint1(point1) plane.SetPoint2(point2) trnf = vtkTransform() trnf.RotateWXYZ(*wxyz) trnf.Translate(translate) tpdPlane = vtkTransformPolyDataFilter() tpdPlane.SetTransform(trnf) tpdPlane.SetInputConnection(plane.GetOutputPort()) return tpdPlane def MakeCubeActor(scale, xyzLabels, colors): cube = MakeAnnotatedCubeActor(colors) # 生成一个vtkAnnotatedCubeActor对象 axes = MakeAxesActor(scale, xyzLabels) # 生成一个vtkAxesActor对象 """ vtkPropAssembly 用来组织和管理多个可渲染对象(actors),作用非常类似于“父节点 / 组(Group or Hierarchy Node)” 概念 可以把多个 vtkProp(比如 vtkActor, vtkVolume, vtkAxesActor 等)组合在一起,当作一个整体来操作 它本身继承自 vtkProp3D,所以可以像单个 vtkActor 一样被渲染、平移、旋转、缩放 """ assembly = vtkPropAssembly() assembly.AddPart(axes) assembly.AddPart(cube) return assembly def MakeAxesActor(scale, xyzLabels): axes = vtkAxesActor() axes.SetScale(scale) axes.SetShaftTypeToCylinder() # 设置坐标轴主体(轴身)的几何形状 axes.SetXAxisLabelText(xyzLabels[0]) # 设置X轴末端显示的文字标签 axes.SetYAxisLabelText(xyzLabels[1]) axes.SetZAxisLabelText(xyzLabels[2]) axes.SetCylinderRadius(0.5 * axes.GetCylinderRadius()) # 设置轴身半径 axes.SetConeRadius(1.025 * axes.GetConeRadius()) # 设置轴尖半径 axes.SetSphereRadius(1.5 * axes.GetSphereRadius()) # 设置中心点的球体半径 tprop = axes.GetXAxisCaptionActor2D().GetCaptionTextProperty() # 提取出控制X轴标签外观的属性对象 tprop.ItalicOn() # 设置为斜体 tprop.ShadowOn() # 开启阴影功能 tprop.SetFontFamilyToTimes() # 设置字体为Times字体 axes.GetYAxisCaptionActor2D().GetCaptionTextProperty().ShallowCopy(tprop) axes.GetZAxisCaptionActor2D().GetCaptionTextProperty().ShallowCopy(tprop) return axes def MakeAnnotatedCubeActor(colors): """ vtkAnnotatedCubeActor 在三维场景中显示方向表示的类。 每个面上都带有文字标签(Annotation),通常用于显示 坐标方向(如 +X、-Y、+Z) 功能: 显示立方体六个面,模拟坐标方位 每个面都有文字,默认是 X, Y, Z, -X, -Y, -Z 可交互显示,一般固定在角落(不随模型旋转) """ cube = vtkAnnotatedCubeActor() cube.SetXPlusFaceText("R") cube.SetXMinusFaceText("L") cube.SetYPlusFaceText('A') # 前部 cube.SetYMinusFaceText('P') # 后部 cube.SetZPlusFaceText('S') # 上面/头部 cube.SetZMinusFaceText('I') # 下面/尾部 cube.SetFaceTextScale(0.5) # 设置字体大小 cube.GetCubeProperty().SetColor(colors.GetColor3d("Gainsboro")) cube.GetTextEdgesProperty().SetColor(colors.GetColor3d("LightSlateGray")) cube.GetXPlusFaceProperty().SetColor(colors.GetColor3d('Tomato')) cube.GetXMinusFaceProperty().SetColor(colors.GetColor3d('Tomato')) cube.GetYPlusFaceProperty().SetColor(colors.GetColor3d('DeepSkyBlue')) cube.GetYMinusFaceProperty().SetColor(colors.GetColor3d('DeepSkyBlue')) cube.GetZPlusFaceProperty().SetColor(colors.GetColor3d('SeaGreen')) cube.GetZMinusFaceProperty().SetColor(colors.GetColor3d('SeaGreen')) return cube if __name__ == '__main__': main()
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/2/16 10:12:12

新思考电机冲刺港股:前9个月营收14.6亿利润9706万 估值24亿

雷递网 雷建平 1月16日新思考电机日前递交招股书,准备在港交所上市。新思考电机最近一次融资是2023年,当时募资1亿,投后估值24亿。前9个月营收14.57亿 期内利润9706万新思考电机成立于2014年,是一家微型精密马达制造商&#xff0c…

作者头像 李华
网站建设 2026/2/18 12:26:40

AI如何赋能SIOT开发:从代码生成到智能优化

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 创建一个基于AI的SIOT设备管理系统原型,要求包含以下功能:1. 通过自然语言描述自动生成设备连接代码(MQTT/CoAP协议)2. 智能诊断设备…

作者头像 李华
网站建设 2026/2/15 11:23:37

交通运输十五五规划专题汇总(2026-01-05更新)

交通运输 “十五五” 规划(2026-2030 年)是我国构建现代化综合交通运输体系的中长期战略部署,聚焦 “安全、便捷、高效、绿色、经济” 目标,涵盖以下核心专题:一是基础设施网络优化,包括高铁主通道贯通、国…

作者头像 李华
网站建设 2026/2/17 1:48:18

Charles抓包零基础入门:从安装到第一个抓包

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 创建一个面向初学者的Charles入门交互教程,包含:1. 分步安装指南(Windows/Mac) 2. 基础界面导览 3. 第一个HTTP抓包演示 4. 常见术语解释 5. 简单问题排查。…

作者头像 李华
网站建设 2026/2/10 18:14:21

在AI技术能快速实现想法的时代,挖掘潜在需求成为关键——某知名深度学习论文实现库的需求分析

a. 内容描述 核心功能定位:该项目是一个简单、清晰且带有详细解释的PyTorch神经网络及相关算法的实现集合。其核心定位在于通过代码实现与并排展示的解释说明,帮助学习者更好地理解和掌握各类深度学习算法。关键应用场景:主要服务于希望深入理…

作者头像 李华
网站建设 2026/2/18 7:50:43

零信任时代下MCP架构重构指南:90天完成安全转型路径

第一章:MCP架构与零信任融合的核心理念在现代企业安全体系中,MCP(Multi-Cloud Platform)架构与零信任安全模型的深度融合已成为应对复杂网络威胁的关键路径。传统边界防御机制在多云环境中逐渐失效,资源动态分布、身份…

作者头像 李华