news 2026/4/17 11:13:21

3D 医学扫描同时显示患者的皮肤、骨骼的 3D 模型(通过等值面提取),以及三个正交切片

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
3D 医学扫描同时显示患者的皮肤、骨骼的 3D 模型(通过等值面提取),以及三个正交切片

一:主要的知识点

1、说明

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

2、知识点纪要

本段代码主要涉及的有①vtkLookupTable颜色映射表的运用,②vtkImageMapToColors图片的标量着色


二:代码及注释

import vtkmodules.vtkInteractionStyle import vtkmodules.vtkRenderingOpenGL2 from vtkmodules.vtkIOImage import vtkMetaImageReader from vtkmodules.vtkCommonColor import vtkNamedColors from vtkmodules.vtkFiltersCore import vtkFlyingEdges3D, vtkStripper from vtkmodules.vtkRenderingCore import vtkPolyDataMapper, vtkActor, vtkRenderer, vtkRenderWindow, \ vtkRenderWindowInteractor from vtkmodules.vtkFiltersModeling import vtkOutlineFilter from vtkmodules.vtkCommonCore import vtkLookupTable from vtkmodules.vtkImagingCore import vtkImageMapToColors from vtkmodules.vtkRenderingCore import ( vtkActor, vtkCamera, vtkImageActor, vtkPolyDataMapper, vtkRenderWindow, vtkRenderWindowInteractor, vtkRenderer ) def main(): colors = vtkNamedColors() colors.SetColor('SkinColor', [240, 184, 160, 255]) colors.SetColor('BkgColor', [51, 77, 102, 255]) file_name = "Data/FullHead.mhd" reader = vtkMetaImageReader() reader.SetFileName(file_name) reader.Update() # 皮肤表面重建 skin_extractor = vtkFlyingEdges3D() skin_extractor.SetInputConnection(reader.GetOutputPort()) skin_extractor.SetValue(0, 500) skin_extractor.Update() skin_mapper = vtkPolyDataMapper() skin_mapper.SetInputConnection(skin_extractor.GetOutputPort()) skin_mapper.ScalarVisibilityOff() skin_actor = vtkActor() skin_actor.SetMapper(skin_mapper) skin_actor.GetProperty().SetDiffuseColor(colors.GetColor3d("SkinColor")) skin_actor.GetProperty().SetSpecular(0.3) skin_actor.GetProperty().SetSpecularPower(20) bone_extractor = vtkFlyingEdges3D() bone_extractor.SetInputConnection(reader.GetOutputPort()) bone_extractor.SetValue(0, 1150) bone_stripper = vtkStripper() bone_stripper.SetInputConnection(bone_extractor.GetOutputPort()) bone_mapper = vtkPolyDataMapper() bone_mapper.SetInputConnection(bone_stripper.GetOutputPort()) bone_mapper.ScalarVisibilityOff() bone_actor = vtkActor() bone_actor.SetMapper(bone_mapper) bone_actor.GetProperty().SetDiffuseColor(colors.GetColor3d("Ivory")) # outline outline_data = vtkOutlineFilter() outline_data.SetInputConnection(reader.GetOutputPort()) outline_data.Update() map_outline = vtkPolyDataMapper() map_outline.SetInputConnection(outline_data.GetOutputPort()) outline = vtkActor() outline.SetMapper(map_outline) outline.GetProperty().SetColor(colors.GetColor3d('Black')) # 切片三个方向切片的颜色映射表 bw_lut = vtkLookupTable() bw_lut.SetRange(0, 2000) # 输入的数据的灰度范围就是0~2000 bw_lut.SetSaturationRange(0, 0) # 将饱和度的范围设置为 0 到 0。饱和度为 0 意味着完全没有颜色,只有灰度 bw_lut.SetHueRange(0, 0) # 将色相(颜色类型,如红、绿、蓝)的范围设置为 0 到 0。由于饱和度为 0,色相设置在这里其实没有影响 bw_lut.SetValueRange(0, 1) # 将亮度的范围设置为 0(黑色)到 1(白色) bw_lut.Build() """ 总结上面的代码:定义了一个从黑到白的线性灰度查找表 0 黑色(0,0,0) 1000, 中灰(0.5, 0.5, 0.5) 2000, 白色(1, 1, 1) """ hue_lut = vtkLookupTable() hue_lut.SetTableRange(0, 2000) """ SetHueRange 决定颜色在色环上的位置,范围通常为 [0,1],代表一个完整的彩色循环 | Hue 值 | 代表颜色 | | ----- | ---------------- | | 0.0 | 红色 (Red) | | 0.16 | 黄色 (Yellow) | | 0.33 | 绿色 (Green) | | 0.66 | 蓝色 (Blue) | | 0.83 | 紫色 (Magenta) | | 1.0 | 回到红色 (Red again) | 所以 SetHueRange(0, 1) 表示: 标量值从 0 → 2000 时,颜色从红 → 橙 → 黄 → 绿 → 蓝 → 紫 → 红, 形成一个完整的彩虹过渡 """ hue_lut.SetHueRange(0, 1) """ SetSaturationRange 这里设置为 1, 1 表示所有颜色都保持最鲜艳,不褪色 饱和度:表示颜色的纯度或鲜艳程度 可以把颜色想象成是“纯色 + 灰色”的混合 高饱和度(1) → 纯色,非常鲜艳 低饱和度(接近 0) → 被灰色稀释的颜色,显得“灰灰的”或“褪色”。 例如粉红色(红色 + 白灰),浅蓝(蓝色 + 灰白) 两个1表示表示整个查找表中,所有颜色的饱和度都恒定为 1 不管标量值是最小的还是最大的,颜色都保持完全饱和(最纯净),不进行从“灰色 → 纯色”的渐变 如果是SetSaturationRange(0, 1)->标量小的区域 → 饱和度低(灰白、淡)标量大的区域 → 饱和度高(纯色)会出现一种“从灰到彩色”的渐变 """ hue_lut.SetSaturationRange(1, 1) hue_lut.SetValueRange(1, 1) hue_lut.Build() sat_lut = vtkLookupTable() sat_lut.SetTableRange(0, 2000) sat_lut.SetHueRange(0.6, 0.6) # 固定了某种颜色 sat_lut.SetSaturationRange(0, 1) sat_lut.SetValueRange(1, 1) sat_lut.Build() """ vtkImageMapToColors 是vtk中非常常用的图像颜色映射类,主要是把灰度图转换成彩色图 它相当于“用查找表(Lookup Table)把标量值映射成颜色”的一个过滤器 """ sagittal_colors = vtkImageMapToColors() sagittal_colors.SetInputConnection(reader.GetOutputPort()) sagittal_colors.SetLookupTable(bw_lut) sagittal_colors.Update() sagittal = vtkImageActor() sagittal.GetMapper().SetInputConnection(sagittal_colors.GetOutputPort()) sagittal.SetDisplayExtent(128, 128, 0, 255, 0, 92) # 设置展示的切片范围 """ ForceOpaqueOn 强制渲染器将这个对象(sagittal 切片)视为完全不透明(Opaque),主要目的是为了优化渲染性能 在渲染复杂的 3D 场景时,VTK 渲染器通常会检查每个物体(Actor)的透明度属性 (Opacity)。 如果一个物体是透明的(Opacity < 1.0),渲染器必须进行额外的计算, 例如深度排序(将透明物体从后往前渲染),这会消耗大量性能 """ sagittal.ForceOpaqueOn() axial_colors = vtkImageMapToColors() axial_colors.SetInputConnection(reader.GetOutputPort()) axial_colors.SetLookupTable(hue_lut) axial_colors.Update() axial = vtkImageActor() axial.GetMapper().SetInputConnection(axial_colors.GetOutputPort()) axial.SetDisplayExtent(0, 255, 0, 255, 46, 46) axial.ForceOpaqueOn() coronal_colors = vtkImageMapToColors() coronal_colors.SetInputConnection(reader.GetOutputPort()) coronal_colors.SetLookupTable(sat_lut) coronal_colors.Update() coronal = vtkImageActor() coronal.GetMapper().SetInputConnection(coronal_colors.GetOutputPort()) coronal.SetDisplayExtent(0, 255, 128, 128, 0, 92) coronal.ForceOpaqueOn() a_camera = vtkCamera() a_camera.SetViewUp(0, 0, -1) a_camera.SetPosition(0, -1, 0) a_camera.SetFocalPoint(0, 0, 0) a_camera.ComputeViewPlaneNormal() a_camera.Azimuth(30.0) a_camera.Elevation(30.0) a_renderer = vtkRenderer() ren_win = vtkRenderWindow() ren_win.AddRenderer(a_renderer) iren = vtkRenderWindowInteractor() iren.SetRenderWindow(ren_win) a_renderer.AddActor(outline) a_renderer.AddActor(sagittal) a_renderer.AddActor(axial) a_renderer.AddActor(coronal) a_renderer.AddActor(skin_actor) a_renderer.AddActor(bone_actor) bone_actor.VisibilityOff() skin_actor.GetProperty().SetOpacity(0.5) a_renderer.SetActiveCamera(a_camera) ren_win.SetWindowName('MedicalDemo3') ren_win.Render() a_renderer.ResetCamera() a_camera.Dolly(1.5) a_renderer.ResetCameraClippingRange() ren_win.Render() iren.Initialize() iren.Start() if __name__ == '__main__': main()
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/4/10 17:28:08

平台化智能:JBoltAI 构建企业自主进化的技术基石

在AI技术全面渗透产业的今天&#xff0c;企业的智能化竞争早已超越单一工具的应用层面&#xff0c;迈向体系化能力的博弈。许多Java技术团队在接入AI能力时&#xff0c;往往陷入分散化、被动化的困境&#xff1a;不同场景的AI工具各自为战&#xff0c;数据无法沉淀复用&#xf…

作者头像 李华
网站建设 2026/4/17 15:22:39

WGS84转CGCS2000坐标系转换步骤详解

WGS84转CGCS2000坐标系转换实战指南 在智慧城市、无人机航测与遥感AI建模日益普及的今天&#xff0c;地理坐标的精准对齐已成为数据预处理的关键一环。尤其在国内项目中&#xff0c;常需将全球通用的WGS84坐标&#xff08;如GPS采集点&#xff09;转换为国家大地坐标系CGCS2000…

作者头像 李华
网站建设 2026/4/18 4:14:13

揭秘Open-AutoGLM GitHub部署难题:5步完成高效本地配置

第一章&#xff1a;揭秘Open-AutoGLM项目核心架构Open-AutoGLM 是一个面向自动化自然语言任务处理的开源框架&#xff0c;旨在通过模块化设计与可扩展接口实现大语言模型&#xff08;LLM&#xff09;能力的高效集成。其核心架构围绕任务调度、模型代理、上下文管理三大组件构建…

作者头像 李华
网站建设 2026/4/16 15:36:25

大模型上下文管理秘籍:5种实用技术,轻松提升AI应用性能!

一、上下文卸载&#xff08;context offloading&#xff09; 定义&#xff1a;把那些当前不必一直塞入模型输入窗口的信息&#xff0c;挪到外部存储&#xff0c;需要时再取回来。 常见实现思路&#xff1a; 使用文件系统/数据库写出中间产物、工具输出、冗余文档等。 主上下…

作者头像 李华
网站建设 2026/4/18 7:10:55

收藏备用!一文搞懂RAG知识库:企业大模型落地必备指南

一、什么是RAG&#xff1f;新手也能理解的通俗解读 聊到AI大模型实际应用&#xff0c;技术圈绕不开RAG知识库、智能体Agent、工作流Workflow这些核心组件。如果把大模型应用场景比作一道道待做的菜品&#xff0c;开发者是厨师&#x1f9d1;&#x1f373;&#xff0c;那这些组件…

作者头像 李华