news 2026/6/23 15:55:07

MeshLabelImageColor 读取医学标签图像数据(MetaImage 格式)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
MeshLabelImageColor 读取医学标签图像数据(MetaImage 格式)

一:主要的知识点

1、说明

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

2、知识点纪要

本段代码主要涉及的有①vtkColorTransferFunction颜色映射,②vtkExtractVOI裁剪体素数据,③vtkLODActor的作用


二:代码及注释

from vtkmodules.vtkCommonColor import vtkNamedColors import vtkmodules.vtkRenderingOpenGL2 from vtkmodules.vtkCommonCore import vtkLookupTable from vtkmodules.vtkIOImage import vtkMetaImageReader from vtkmodules.vtkImagingCore import vtkExtractVOI from vtkmodules.vtkFiltersGeneral import vtkDiscreteFlyingEdges3D, vtkDiscreteMarchingCubes from vtkmodules.vtkFiltersCore import vtkWindowedSincPolyDataFilter, vtkPolyDataNormals from vtkmodules.vtkRenderingCore import vtkColorTransferFunction, vtkPolyDataMapper, vtkRenderWindow, \ vtkRenderWindowInteractor, vtkRenderer from vtkmodules.vtkRenderingLOD import vtkLODActor def get_diverging_lut(ct): # 构建颜色查找表 cm = {} """ cm中存储了五种预定义的发散颜色方案 每种方案由一个包含三个点的列表定义:起点 (0.0)、中点 (0.5) 和 终点 (1.0) 每个点是一个列表 [Value, R, G, B],其中 Value 是数据范围中的归一化位置,R, G, B 是该位置的颜色值(范围 0.0 到 1.0) 发散特性:所有方案的中点(0.5)都被设置为一个中性色(如浅灰色 [0.865, 0.865, 0.865]), 这使得数据零点或中心值能被中性地表示,而正负或高低极端值则被不同的饱和色(如蓝色和红色)突出显示 """ cm[0] = [[0.0, 0.230, 0.299, 0.754], [0.5, 0.865, 0.865, 0.865], [1.0, 0.706, 0.016, 0.150]] cm[1] = [[0.0, 0.436, 0.308, 0.631], [0.5, 0.865, 0.865, 0.865], [1.0, 0.759, 0.334, 0.046]] cm[2] = [[0.0, 0.085, 0.532, 0.201], [0.5, 0.865, 0.865, 0.865], [1.0, 0.436, 0.308, 0.631]] cm[3] = [[0.0, 0.217, 0.525, 0.910], [0.5, 0.865, 0.865, 0.865], [1.0, 0.677, 0.492, 0.093]] cm[4] = [[0.0, 0.085, 0.532, 0.201], [0.5, 0.865, 0.865, 0.865], [1.0, 0.758, 0.214, 0.233]] ct = abs(ct) if ct > len(cm) - 1: ct = 0 ctf = vtkColorTransferFunction() """ vtkColorTransferFunction 用于定义连续的颜色映射规则 简单来说,它是一个数学函数, 它接收一个输入标量值(比如温度、压力、或者你代码中的平滑误差),然后输出一个对应的 RGB 颜色值 核心功能:定义颜色映射的“路径” vtkColorTransferFunction 的作用是将一个一维的数据范围(例如,平滑误差从 −5.0 到 +5.0)映射到一个三维的颜色空间(R、G、B)。 它通过在数据范围内定义一系列的**关键点(Control Points)**来实现颜色映射的精确控制。 1. AddRGBPoint(value, R, G, B) 这是定义颜色映射路径的主要方法: value: 输入数据空间中的一个特定数值(例如,如果你想让误差为 0.0 的地方显示为白色,value 就是 0.0)。 R, G, B: 对应这个 value 应该具有的颜色。 当你添加了多个关键点后,vtkColorTransferFunction 就会在这些关键点之间自动进行插值(Interpolation),从而形成一条平滑的颜色路径。 示例: AddRGBPoint(0.0, 0.0, 0.0, 1.0): 数据为 0.0 时是蓝色。 AddRGBPoint(1.0, 1.0, 0.0, 0.0): 数据为 1.0 时是红色。 那么,数据为 0.5 时,函数会插值得到一个接近紫色的颜色。 2. SetColorSpaceToDiverging() 这是在你的 get_diverging_lut 函数中使用的关键设置: 它告诉函数,颜色变化应该遵循一个**发散(Diverging)**的颜色模型。 作用:它优化了颜色空间中的插值,特别是确保在中心值(通常是 0.5 或数据中心)附近的颜色变化更加平滑和中性,从而更好地可视化具有正负意义或围绕中心点变化的数据(如平滑误差)。 3. 与 vtkLookupTable 的关系 vtkColorTransferFunction 定义了连续的颜色规则,而 vtkLookupTable (LUT) 是一个离散的颜色表(通常是 256 个颜色)。 LUT 是渲染器实际使用的对象,因为它速度更快。 vtkColorTransferFunction 用于生成高质量的 LUT。在你的代码中,正是通过循环调用 ctf.GetColor(i / table_size),将连续的颜色函数采样,并填充到 vtkLookupTable 中。 """ ctf.SetColorSpaceToDiverging() for scheme in cm[ct]: ctf.AddRGBPoint(*scheme) table_size = 256 lut = vtkLookupTable() lut.SetNumberOfColors(table_size) lut.Build() for i in range(0, table_size): rgba = list(ctf.GetColor(float(i) / table_size)) rgba.append(1) lut.SetTableValue(i, rgba) return lut def main(): colors = vtkNamedColors() use_flying_edges = True ifn = "Data/labels.mhd" index = 31 # 读取相关文件 reader_volume = vtkMetaImageReader() reader_volume.SetFileName(ifn) reader_volume.Update() """ vtkExtractVOI 作用是从一个体数据(Volume Data)或图像数据(Image Data)中提取一个指定子区域(子集) 可用于裁剪和降采样 """ voi = vtkExtractVOI() voi.SetInputConnection(reader_volume.GetOutputPort()) voi.SetVOI(0, 517, 0, 228, 0, 392) # 裁剪范围 voi.SetSampleRate(1, 1, 1) # 表示不降采样,保留原始分辨率 voi.SetSampleRate(2, 2, 2) # 表示每隔一个体素取一个,这将把数据的分辨率减半 voi.Update() srange = voi.GetOutput().GetScalarRange() # 获取体素数值大小的范围(0.0, 705.0) print("Range: ", srange) # 体素模型的表面重建 contour = vtkDiscreteFlyingEdges3D() contour.SetInputConnection(voi.GetOutputPort()) contour.SetValue(0, index) contour.Update() smoother = vtkWindowedSincPolyDataFilter() smoother.SetInputConnection(contour.GetOutputPort()) smoother.SetNumberOfIterations(30) smoother.NonManifoldSmoothingOn() smoother.NormalizeCoordinatesOn() # 启用坐标归一化,在应用 Sinc 滤波器之前执行的预处理步骤,对平滑过程的稳定性和结果质量至关重要 smoother.GenerateErrorScalarsOn() # 计算并输出一个表示“几何误差”的标量数组 """ GenerateErrorScalarsOn 启用这个功能后,平滑器在移动网格上的每个顶点时,会记录该顶点相对于其原始位置的距离 这个误差值(一个浮点数)被存储为新的输出网格(vtkPolyData)的点数据(Point Data)中的一个标量数组 """ smoother.Update() se_range = smoother.GetOutput().GetPointData().GetScalars().GetRange() print('Smoother error range:', se_range) if se_range[1] > 1: print('Big smoother error: min/max:', se_range[0], se_range[1]) lut = get_diverging_lut(4) normals = vtkPolyDataNormals() """ vtkPolyDataNormals 是一个 滤波器(filter)根据几何形状(顶点和面)计算法向量(normals),并把它们添加到 vtkPolyData 的点或面上 """ normals.SetInputConnection(smoother.GetOutputPort()) normals.ComputeCellNormalsOn() normals.ComputePointNormalsOff() normals.ConsistencyOn() # 尝试保持法向一致(方向不乱) normals.AutoOrientNormalsOn() # 根据整体外形自动确定法向朝外或朝内 normals.SetFeatureAngle(60.0) # 当两面夹角大于该角度时,不平均法线,保留边缘 normals.Update() mapper = vtkPolyDataMapper() # mapper.SetInputConnection(smoother.GetOutputPort()) mapper.SetInputConnection(normals.GetOutputPort()) # 使用含有法线的数据,渲染效果会更好 mapper.ScalarVisibilityOn() # 使用模型的标量数据进行着色,而非统一颜色 mapper.SetScalarRange(se_range) # mapper.SetScalarModeToUseCellData() # Contains the label eg. 31 mapper.SetScalarModeToUsePointData() # The smoother error relates to the verts. mapper.SetLookupTable(lut) """ vtkLODActor vtkLODActor 和 vtkActor 的关系非常紧密,但它多了一个关键功能 —— “LOD(Level of Detail,细节层次)控制” vtkActor 只显示一种模型; vtkLODActor 能同时保存多种简化版本的模型,并根据渲染速度自动选择合适的那个来绘制。 在 VTK 的早期(还没有 GPU 硬件加速的时代),如果场景中包含 大量复杂几何体(例如几万个多边形),实时旋转或交互就会非常卡。 于是 VTK 提供了 vtkLODActor,它能在: 你静止观察模型时 用高精度几何; 你旋转/缩放时 自动切换到低精度版本(比如抽稀点或包围盒); 从而保持交互流畅 """ actor = vtkLODActor() """ SetNumberOfCloudPoints vtkLODActor 会在交互(比如拖动、旋转)时自动切换到“低分辨率”的显示模式,以保证流畅性。 在这种低分辨率模式下,它可能用以下几种方式来替代原几何: 用 点云(Point Cloud) 表示原模型; 用 抽稀网格; 用 包围盒 或其他简化几何。 而这其中的“点云模式”,就是通过本行代码控制的 意思是:当 vtkLODActor 进入“点云模式(Point Cloud Mode)”时,最多使用 100,000 个点 来代表整个模型。 """ actor.SetNumberOfCloudPoints(100000) actor.SetMapper(mapper) # Create the renderer. ren = vtkRenderer() ren.SetBackground(colors.GetColor3d('DimGray')) ren.AddActor(actor) # Create a window for the renderer of size 600X600 ren_win = vtkRenderWindow() ren_win.AddRenderer(ren) ren_win.SetSize(600, 600) ren_win.SetWindowName('MeshLabelImageColor') ren_win.Render() # Set a user interface interactor for the render window. iren = vtkRenderWindowInteractor() iren.SetRenderWindow(ren_win) # Start the initialization and rendering. iren.Initialize() iren.Start() if __name__ == '__main__': main()
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/6/21 23:04:23

61、SQL 中的抽象数据类型与继承机制

SQL 中的抽象数据类型与继承机制 1. 操作 LOB 数据 在处理包含文档文本的大对象(LOB)数据时,我们可能需要检索包含 LOB 的行,并更新 LOB 数据中间的部分内容。以下是一个示例代码,展示了如何实现这一操作: declare lob CLOB; textbuf varchar(255); begin /* Put…

作者头像 李华
网站建设 2026/6/21 20:08:57

69、SQL 的现状与未来:专业数据库与市场趋势洞察

SQL 的现状与未来:专业数据库与市场趋势洞察 1. 事件处理与数据库连接 在当今的数据处理领域,企业数据库管理系统(DBMS)起着关键作用。企业 DBMS 链接能够让事件处理引擎将来自数据馈送的数据与从传统企业数据库中检索的数据进行合并。目前,所有主流产品都支持通过 JDBC…

作者头像 李华
网站建设 2026/6/22 17:41:42

68、专业数据库:低延迟、内存与流处理的应用与发展

专业数据库:低延迟、内存与流处理的应用与发展 在当今的数据库市场中,大型企业数据库管理系统占据着主导地位。像Oracle、IBM、Microsoft、Sybase等公司的旗舰产品,都是功能强大且复杂的软件,采用了“一刀切”的通用解决方案。大型企业可以使用Oracle数据库或IBM的DB2的最…

作者头像 李华
网站建设 2026/6/23 13:53:07

eRPC数据中心网络高效RPC终极配置指南

eRPC数据中心网络高效RPC终极配置指南 【免费下载链接】eRPC Efficient RPCs for datacenter networks 项目地址: https://gitcode.com/gh_mirrors/erp/eRPC 想要在数据中心网络中实现极速RPC通信?eRPC正是你需要的解决方案!这个专为现代数据中心…

作者头像 李华
网站建设 2026/6/22 22:09:58

零基础玩转Moondream2:智能看图说话神器快速上手指南

零基础玩转Moondream2:智能看图说话神器快速上手指南 【免费下载链接】moondream2 项目地址: https://ai.gitcode.com/hf_mirrors/ai-gitcode/moondream2 还在为复杂的AI模型部署而头疼吗?🤔 Moondream2作为一款专为边缘设备优化的智…

作者头像 李华
网站建设 2026/6/22 4:55:16

Hasklig编程字体:用连字技术彻底改变你的代码阅读体验

Hasklig编程字体:用连字技术彻底改变你的代码阅读体验 【免费下载链接】Hasklig Hasklig - a code font with monospaced ligatures 项目地址: https://gitcode.com/gh_mirrors/ha/Hasklig 作为一名开发者,你是否曾经在深夜编程时感到眼睛疲劳&am…

作者头像 李华