1.MRML
1.1 Introduction
- MRML用来描述Slicer中的场景并映射到他的数据模型。MRML库提供了一个API用于管理医学图像数据类型(体数据、模型、变换、基准点、相机等)和可视化;
- 每种数据类型都以一个特殊的MRML node(节点)来呈现;MRML Scene就是所有MRML nodes的集合;Slicer MRML数据模型不依赖于系统的可视化组建和算法组件;
1.2 MRML Scene
- MRML Scene管理MRML nodes(增加、删除、寻找、按类寻找);
- MRML Scene 提供了MRML nodes的可持续性(从XML文件中读取、写入到XML文件);
- MRML Scene提供了 Undo/Redo 机制;
1.3 MRML Nodes
- MRML nodes存储Slicer应用的状态,包括原始数据和可视化参数;下面是关键MRML nodes的集合,他们存储着核心Slicer模块的状态:
- 所有的MRML nodes必须应用某种标准的API:ReadAttributes/WriteAttributes/Copy等;
MRML nodes采用C++类等级进行管理,都继承于vtkMRMLNode 类。例如,vtkMRMLTransformableNode是体数据Volume、模型Model、基准点Fiducial和变换Transformation nodes的父类。vtkVolumeNode是vtkMRMLScalarVolumeNode和vtkMRMLVectorVolumeNode的父类。MRML nodes的类等级如下图所示:
1.4 引用MRML 节点
一些MRML nodes 也会引用其他 nodes。例如,Transformable Node 引用了Transformation Node。Transformation Node引用了父级的Transformation Node。引用通过 Node ID存储。
- 使用VTKSetReferenceStringMacro设置引用ID(场景中注册过程);
- 访问方法在访问之前应该通过ID检查引用节点是否仍然在MRML场景中;
1.5 MRML事件与观察者
MRML场景和每个节点的改变将会通过vtk事件和命令-观察者机制传递给其他的观测节点,GUI对象和Logic对象。一些经验规则如下:
- Use vtk AddObserver() and InvokeEvent() methods. vtk SetMacro generates ModifiedEvent.
- The command-observer mechanism for MRML is implemented using helper vtkObserverManager, class, MRML Observer macros, and ProcessMRMLEvents method.
- Observers should store a registered pointer to a MRML node to prevent callbacks on a deleted object.
1.6 如何添加一个MRML node到场景中?
1 vtkNew<vtkMRML???Node> nodeToAdd;
2 ...
3 mrmlScene->AddNode(nodeToAdd.GetPointer());
1 vtkNew<vtkMRMLModelNode> modelNode;
2 modelNode->SetPolyData(polyData);
3 mrmlScene->AddNode(modelNode.GetPointer());
1 vtkSlicerModelsLogic* modelsLogic = ...;
2 //modelsLogic->SetMRMLScene(mrmlScene);
3 modelsLogic->AddModel(polyDataFileName);
1.7当载入MRML场景时遇到如下错误怎么办?
1 ERROR: In /path/to/VTK/Imaging/vtkImageMapToColors.cxx, line 153
2 vtkImageMapToColors (0x268f190): RequestInformation: No LookupTable was set but number of components in input doesn't match OutputFormat, therefore input can't be passed through!
3
4 ERROR: In /path/to/VTK/Imaging/vtkImageExtractComponents.cxx, line 239
5 vtkImageExtractComponents (0x26947e0): Execute: Component 1 is not in input.
6
7 ERROR: In /path/to/VTK/Imaging/vtkImageExtractComponents.cxx, line 239
8 vtkImageExtractComponents (0x26947e0): Execute: Component 1 is not in input.
9
10 [...]
要确定每一个colorNodeRef属性设置在每一个VolumeDisplay节点上。
1.8 如何在2D视窗中更改体数据?
1 appLogic = slicer.app.applicationLogic()
2 selectionNode = appLogic.GetSelectionNode()
3 selectionNode.SetReferenceActiveVolumeID(bg)
4 selectionNode.SetReferenceSecondaryVolumeID(fg)
5 appLogic.PropagateVolumeSelection()
2.IO
为什么我的节点Writer没有出现在保存的对话框中?
- 需要在qSlicerIOManager中注册我们的Writer 用qSlicerYourModule::Setup();
资料: SlicerIOManager= http://apidocs.slicer.org/master/classqSlicerIOManager.html 示例: https://github.com/Slicer/Slicer/blob/3dd75da/Modules/Loadable/Markups/qSlicerMarkupsModule.cxx
- 你的节点需要成为vtkMRMLStorableNode的子类;
3.Modules
3.1 在Slicer的build-tree中,Slicer的模块位于哪里?
Slicer模块和库位于Slicer主构建目录:
~/Slicer-Superbuild/Slicer-build
3.2 如何从C++可加载模块调用一个CLI模块?
问题描述:http://slicer-devel-archive.65872.n3.nabble.com/Calling-CLI-module-from-a-C-loadable-module-tt4031930.html
实例分析:https://github.com/Slicer/Slicer/blob/master/Modules/Loadable/CropVolume/Logic/vtkSlicerCropVolumeLogic.cxx#L318-351
3.3 如何从命令行调用一个CLI模块?
示例:
Slicer.exe --launch CastScalarVolume input.mha output.mha
在Windows中使用要注意:
- 需要使用Slicer应用程序的全名,即Slicer.exe而不是Slicer;
- 为了获得CLI模块支持的命令行参数的帮助,可以运行下面语句:
Slicer.exe --launch CastScalarVolume 2>c:\SomeWriteAbleDirectory\usage.txt