1.Slicer MRML数据类型综述

  • MRML提供API(应用程序接口)管理医学图像数据类型(Volume、Model、Transform、Fiducial、Camera等)和它们的可视化;
  • 每种数据类型都用一个特定的MRML节点表示;
  • MRML场景就是MRML节点的集合;
  • Slicer的MRML数据模型(data Model)独立于Slicer系统的可视化组件Visualization和算法组件Algorithm;
  • 其他的Slicer组件,Logic和Qt Widget观测MRML场景和每个节点的变化。

2.MRML 场景

  • MRML场景管理MRML节点:添加、删除、寻找等;
  • MRML Scene provides persistence of MRML nodes (reading/writing to/from XML file)

3.MRML 节点

  • MRML节点用于存贮Slicer应用的状态,包括原始数据和可视化、参数。一组存储核心Slicer Module状态的的核心MRML节点如下所示:

  • MRML节点以C++类等级的形式被组织,所有的子类均继承vtkMRMLNode;
  • 所有的MRML节点必须应用某种标准的API:ReadAttributes、WriteAttributes、Copy等;
  • 相同的数据可以用不同的方式进行可视化,并储存成不同的类型。因此,信息分别以三种不同节点类型进行存储:
    • 数据节点:存储原始数据,例如vtkMRMLScalarVolumeNode存储体素、spacing、位置、方向
    • 显示节点:描述了数据怎么样被可视化,对于相同的原始数据可能会有很多的显示节点,例如一个节点进行体绘制、另外一个节点用于显示一张图像
    • 存储节点:描述数据应该如何永久性存储到磁盘中,文件格式、文件名
  • 当一个数据节点被创建的时候,我们必须创建相应的显示节点与数据存储节点,方便进行合理的可视化和保存文件。MRMLLogic会提供函数——创建一个节点并与显示节点&数据节点关联。注意:在一些情况下,Slicer会检测是否显示节点与存储节点遗失,并尝试创建默认节点,但是作为开发人员我们不应该依赖这种错误校正机制。

4.MRML节点属性

MRML节点可以成对存储自定义属性:属性名+属性值。
To avoid name clashes custom modules that adds attributes to nodes should prefix the attribute name with the module's name and the '.' character. Example: the DoseVolumeHistogram module can use attribute names such as DoseVolumeHistogram.StructureSetName, DoseVolumeHistogram.Unit, DoseVolumeHistogram.LineStyle.

5.MRML节点引用

这里有两种机制来指定节点间是相关的:层次结构节点&节点引用。相比之下,节点引用更简单。
MRML节点可以利用节点引用API引用或者观测其他的MRML节点。这个框架会自动处理:
  • 节点引用的读、写、复制
  • 场景导入更新引用
  • 增加或删除节点

一个节点可能引用很多节点,每个节点都扮演了不同的角色,并且每个节点都有唯一的字符串进行处理。

数据节点可以选择性地应用接口:如Displayable、Storable、Transformable。每一个接口都有自己的需求。例如,变换模块接口期待与变换节点相关联。这种关联就是通过创建MRML Reference完成的。

5.1 MRML Reference:API描述

上面的节点应用API功能是在vtkMRMLNote基类中实现的。
The only thing that needs to happen in thederived MRML node class(usually in the constructor of the class) is a call tovtkMRMLNode::AddNodeReferenceRole(const char *referenceRole, const char *mrmlAttributeName) that takes a unique string defining the reference role between this node and the referenced node, and a MRML attribute name for storing the reference in the .mrml file.
The only other call that is needed is either:
vtkMRMLNode* SetAndObserveNodeReferenceID(const char* referenceRole , const char* referencedNodeID, vtkIntArray *events=0);
or
vtkMRMLNode* AddAndObserveNodeReferenceID(const char* referenceRole , const char* referencedNodeID, vtkIntArray *events=0);
vtkMRMLNode也提供了虚回调函数,可以在继承类中拓展:
OnNodeReferenceAdded(vtkMRMLNodeReference *reference)
OnNodeReferenceRemoved(vtkMRMLNodeReference *reference)
OnNodeReferenceModified(vtkMRMLNodeReference *reference)

默认情况下,这些方法生成一下事件:

vtkMRMLNode::ReferenceAddedEvent
vtkMRMLNode::ReferenceRemovedEvent
vtkMRMLNode::ReferenceModifiedEvent

在继承类中,这些方法可以采用VTKMRMLNode拓展,以允许查询节点的引用。

vtkMRMLNode成员的完整列表参考如下网址,包括所有继承的成员:
http://apidocs.slicer.org/master/classvtkMRMLNode-members.html
目前,下述的几个MRML节点是采用MRML节点引用API实现的:
  • vtkMRMLStorableNode
  • vtkMRMLTransformableNode
  • vtkMRMLDisplayableNode

其他引用MRML节点,例如vtkMRMLColorTableNode, vtkMRMLDiffusionTensorDisplayPropertiesNode,目前还没有只用这种API。

5.2 MRML Reference:示例

vtkMRMLTransformableNode implementation:
http://viewvc.slicer.org/viewvc.cgi/Slicer4/trunk/Libs/MRML/Core/vtkMRMLTransformableNode.h?view=log
vtkMRMLDisplayableNodeimplementation:
http://viewvc.slicer.org/viewvc.cgi/Slicer4/trunk/Libs/MRML/Core/vtkMRMLDisplayableNode.h?view=log
vtkMRMLStorableNodeimplementation:
http://viewvc.slicer.org/viewvc.cgi/Slicer4/trunk/Libs/MRML/Core/vtkMRMLStorableNode.h?view=log

6.MRML事件与观测者Event-Observe

  • MRML场景和各个节点的改变会传递给其他观测者节点,GUI和Logic对象通过vtk事件、命令-观测者机制。
  • 使用vtkAddObserver()和InvokeEvent()方法。vtkSetMicro生成ModifiedEvent。
  • 对于MRML,命令-观测者机制采用助手vtkObserverManager、类、MRML观测者宏、ProcessMRMLEvent方法实现。
  • 观测者应该存储一个注册的指针,该指针指向MRML节点,防止一个已经删除对象的回调函数。

  • MRML 观察者宏定义位于 Libs/MRML/vtkMRMLNode.h
  • vtkSetMRMLObjectMacro - 注册 MRML节点
  • vtkSetAndObserveMRMLObjectMacro - 注册 MRML 节点,并为vtkCommand::ModifyEvent增加一个观察者
  • vtkSetAndObserveMRMLObjectEventsMacro - 注册MRML节点并为一个指定的事件集合设置观测者
  • SetAndObserveMRMLScene[Events]() 方法在GUI/Logic中使用,用于观察变化、新场景、增加节点等事件
  • ProcessMRMLEvents method在MRML节点、Logic、GUI类中实现,在观察节点中处理事件

7.创建自定义的MRML节点类

  • 自定义MRML节点为模块参数提供了永久性存储
  • 自定义MRML节点应该使用RegistraterNodeClass()在MRML场景中注册,因此他们可以从一个场景文件中恢复或者保存
  • 这个类应该实现以下方法:
    • CreatNodeInstance()-与VTK的New()相似,只不过不是静态的
    • GetNodeTagName()-为这个节点返回一个独一无二的XML标签
    • ReadXMLAttributes()-从XML文件中读取节点属性,如name-value
    • WriteXML()-将节点属性写入到输出流
    • Copy()-拷贝节点属性
  • 如果该节点已经引用其他的节点,那么下面的方法也应该实现:
    • UpdateReferenceID()-更新对另一个节点已经存储的应用
    • UpdataScene()-依赖这个节点更新场景中的其他节点
  • 向MRML场景中添加新的节点
一个实现自定义MRML节点的例子:
vtkMRMLGradientAnisotropicDiffusionFilterNode inModules/GradientAnisotropicDiffusionFilter directory.

8.MRML层次结构节点

http://apidocs.slicer.org/master/classvtkMRMLHierarchyNode.html

9.MRML:Developer FAQ

9.1 如何在场景中增加一个MRML节点?

  • 通用的模式
vtkNew<vtkMRML???Node> nodeToAdd;
...
mrmlScene->AddNode(nodeToAdd.GetPointer());
  • 在场景中添加一个多边形数据?
vtkNew<vtkMRMLModelNode> modelNode;
modelNode->SetPolyData(polyData);
mrmlScene->AddNode(modelNode.GetPointer());
  • 从文件中加载一个多边形数据?
vtkSlicerModelsLogic* modelsLogic = ...;
//modelsLogic->SetMRMLScene(mrmlScene);
modelsLogic->AddModel(polyDataFileName);

9.2 加载一个MRML场景时,如果碰到以下信息该怎么办?

ERROR: In /path/to/VTK/Imaging/vtkImageMapToColors.cxx, line 153
vtkImageMapToColors (0x268f190): RequestInformation: No LookupTable was set but number of components in input doesn't match OutputFormat, therefore input can't be passed through!ERROR: In /path/to/VTK/Imaging/vtkImageExtractComponents.cxx, line 239
vtkImageExtractComponents (0x26947e0): Execute: Component 1 is not in input.ERROR: In /path/to/VTK/Imaging/vtkImageExtractComponents.cxx, line 239
vtkImageExtractComponents (0x26947e0): Execute: Component 1 is not in input.[...]

确保每一个VolumeDisplay节点都设置了ColorNodeRef属性

9.3 如何在2D视窗中改变立体?

appLogic = slicer.app.applicationLogic()
selectionNode = appLogic.GetSelectionNode()
selectionNode.SetReferenceActiveVolumeID(bg)
selectionNode.SetReferenceSecondaryVolumeID(fg)
appLogic.PropagateVolumeSelection()

3DSlicer16:数据类型MRML相关推荐

  1. 3DSlicer33:Adding MRML

    1.Adding in MRML to Slicer MRML是Slicer中用到的场景描述,并映射到他的数据模型.MRML库提供了API管理医学图像数据类型和可视化,数据类型包含Volume.mod ...

  2. Postman使用Date数据类型,Postman发送Date类型数据,Postman模拟前端调用

    Postman使用Date数据类型: 在form-data数据类型下,使用 2021/7/7 11:11:00 (yyyy/MM/dd HH:mm:ss) 的数据格式即可 如下: 在json数据格式中 ...

  3. 大数据中用到的新的数据类型bigint、decimal、smallint、tinyint

    在对比oracle数据库和大数据库的时候,发现了几个用以存放数字的新的类型bigint.decimal.smallint.tinyint,为了对比之间的不同,我进行了统计 bigint 可以精确的表示 ...

  4. NumPy — 创建全零、全1、空、arange 数组,array 对象类型,astype 转换数据类型,数组和标量以及数组之间的运算,NumPy 数组共享内存

    NumPy 简介 一个用 python 实现的科学计算包.包括: 1.一个强大的 N 维数组对象 Array : 2.比较成熟的(广播)函数库: 3.用于整合 C/C++ 和 Fortran 代码的工 ...

  5. 【JavaScript总结】JavaScript语法基础:数据类型

    ------>数据类型有哪些? ->基本类型:数字类型,布尔类型,字符串类型 ->引用类型:对象类型,函数类型 ->空类型:null 和 undefined ->运算符: ...

  6. 数据类型对应的字节数

    20210622 https://www.icode9.com/content-4-421680.html 32位和64位常用数据结构所占字节数 20210126 1 2 4 8 1248 刚好都是2 ...

  7. tensorflow2.0 基础一 常用数据类型及转换

    版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/weixin_43619065/arti ...

  8. 深入浅出Redis五种基本数据类型

    文章目录 1.String SDS(Simple Dynamic String) 2.RedisDB设计 3.List 4.Hash 5.Set intset 6.ZSet skiplist 1.St ...

  9. TVM自定义数据类型

    TVM自定义数据类型 本文将介绍"自定义数据类型"框架,该框架可在TVM中使用自定义数据类型. 介绍 在设计加速器时,关键是如何近似地表示硬件中的实数.这个问题具有长期的行业标准解 ...

最新文章

  1. 推荐8个非常有逼格的实用软件,让你的办公更高效
  2. 什么是COM与DCOM
  3. Python之几种常用模块
  4. EasyUI-datagrid 对于展示数据进行处理(formatter)
  5. flex的12个属性
  6. vue中文件上传方法
  7. 小程序正式发布后,打开白屏(已解决)
  8. Java前端Rsa公钥加密,后端Rsa私钥解密(支持字符和中文)
  9. 16.看板方法---三类改进机会
  10. .gen格式文件读取,完成兰伯特和墨卡托投影转换
  11. Axure share 二三事
  12. 网易云信浏览器WebRTC视频聊天集成
  13. 数据挖掘项目---航空公司客户价值分析
  14. 人民币兑换菲律宾比索去哪些银行?
  15. wii手柄_Wii时代的隐藏宝石
  16. 三国志战略版:Daniel_张角分析
  17. 为什么需要制定计划?
  18. 阵列卡u盘安装系统步骤_最简单实用的raid重装系统图文教程
  19. Uber 四年时间增长近 40 倍,背后架构揭秘
  20. 2021语言与智能技术竞赛:机器阅读理解任务 实验报告

热门文章

  1. 细说Sql Server中的视图(下)转载
  2. Java基础 之软引用、弱引用、虚引用
  3. 配置单节点伪分布式Hadoop
  4. Linux常用命令笔记---故障排除
  5. hdu 1516(编辑距离+记录路径)
  6. hdu 3577(线段树区间更新)
  7. input标签加disabled属性后无法获得其value值
  8. NYOJ 56 阶乘因式分解(一)
  9. hdu 1722 Cake 数学题
  10. Aspose.Words提示The document appears to be corrupted and cannot be loaded.