news 2026/9/2 23:35:53

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/9/2 21:04:00

Hunyuan-MT-7B在国际志愿者培训资料翻译中的应用

Hunyuan-MT-7B在国际志愿者培训资料翻译中的应用 在全球化日益深入的今天,语言不再仅仅是交流工具,更成为连接文化、推动协作的关键桥梁。特别是在国际志愿者项目中,来自不同国家和民族背景的参与者需要共享统一的培训内容——从安全守则到活…

作者头像 李华
网站建设 2026/9/2 21:57:30

【AI时代职场通行证】:MCP AI Copilot考试内容深度拆解与实战技巧

第一章:MCP AI Copilot考试概述与认证价值MCP AI Copilot认证是面向现代软件开发人员和云解决方案架构师的重要技术资质,旨在验证考生在使用AI驱动的开发工具、自动化编程辅助以及智能云服务集成方面的专业能力。该认证由微软推出,聚焦于开发…

作者头像 李华
网站建设 2026/9/2 11:56:01

为什么你的MCP云原生项目总延期?揭晓8大常见瓶颈及破局策略

第一章:MCP云原生应用开发的本质与挑战在当前快速演进的云计算环境中,MCP(Multi-Cloud Platform)云原生应用开发已成为企业构建弹性、可扩展和高可用系统的核心路径。其本质在于利用容器化、微服务架构、持续交付和动态编排等技术…

作者头像 李华
网站建设 2026/9/2 23:04:30

AI如何帮你轻松实现红黑树?快马平台一键生成代码

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 请生成一个完整的红黑树实现代码,包含以下功能:1. 节点插入与删除操作;2. 自动平衡功能(左旋、右旋、颜色调整)&#xf…

作者头像 李华
网站建设 2026/9/2 21:45:04

Azure容器部署性能优化,90%工程师忽略的4个关键配置

第一章:Azure容器部署性能优化概述在现代云原生架构中,Azure 容器实例(ACI)与 Azure Kubernetes 服务(AKS)已成为部署容器化应用的核心平台。为确保应用具备高响应性、低延迟和资源高效利用,性能…

作者头像 李华
网站建设 2026/9/2 21:45:06

Hunyuan-MT-7B支持批量文档翻译吗?解决方案来了

Hunyuan-MT-7B支持批量文档翻译吗?解决方案来了 在企业全球化内容生产、科研文献处理和多语言客户服务的日常工作中,一个反复出现的痛点是:如何高效地将几十页的PDF报告或Word文档从中文精准翻译成英文,同时保留原有段落结构与术语…

作者头像 李华