3Dslicer_MarkupsModule

摘要:
可以使用鼠标模式工具栏在场景中交互放置基准。2、 应用程序方向此模块允许您将新的基准标签添加到活动标签基准列表中,用于选择场景中的标签基准节点,即表单列表,切换表单中标签基准的视觉状态,并将表单中标签标准的图标和文本设置为相同大小。也可以在表中的基准点上单击鼠标右键,使相切平面跳到基准点。复选框将更改表中标签基准点的显示模式。

一、模块简介

该模块是用来管理slicer中的标签(markups)的,基于Slicer 3.6中Fiducials module的功能,其中的元素从Slicer 4.2的Annotations module转移而来。目前该模块中仅支持基准点(fiducials)元素的使用。

模块的功能主要是创建、编辑场景中的标签以及一些附带信息,当前支持的标签是基准点列表(lists of fiducial points),基准点可以使用鼠标模式工具条在场景中交互式的放置。当进入到基准点放置模式时,也可以通过键盘上的P键来在鼠标位置放置一个新的基准点,单机鼠标右键可以离开连续放置模式。

二、应用方向

该模块允许你在一个激活的标签基准点列表中添加新的基准点标签,以及对它进行编辑,删除等操作,以及更改基准点的显示属性

三、界面面板

该模块的界面面板有如下及部分组成:

    1.Markups List

                                    3Dslicer_MarkupsModule第1张

        模块的顶层设置,包含一些常用设置选项:

  • List:用来选择场景中的标签基准点节点(Markups fiducial node)即表单list,并更新主面板使其处于能修改的状态,也可以用其来创建新的节点。
  • Visibility:切换表单中标签基准点的可视状态,会覆盖掉下面标签基准点自己的可视性。
  • Locked:切换表单中标签基准点的上锁状态,同样覆盖掉下面标签基准点自己的上锁性,上锁后,将不能在下面的表格中修改基准点的属性。
  • Scale:设置表单中标签基准点的图标和文字到相同的大小。
  • Click to Jump Slices:选中这个选项后,单击下面表格中列出的标签基准点使其高亮,那么会在slice二维视图窗口将切面跳转到该基准点处,下面的单选按钮可以控制在跳转后是否基准点显示在中央。即使没选中这个选项,也可以右键单击表格中基准点使切面跳转到该基准点处,选中一个基准点后也可以使用上下键来改变高亮基准点也会使切面跳转。

    2.Buttons And Checkboxes

                            3Dslicer_MarkupsModule第2张

          Buttons 可以对这个表单中的标签基准点做一些修改,Checkboxes会改变表单中标签基准点的的显示模式。

  • Toggle visibility flag:切换表单中所有标签基准点的可视性,有下拉菜单。
  • Toggle selected flag:切换表单中所有标签基准点的选择标志,有下拉菜单。只有选中的标签才可以被传递到命令行模块(command line modules)。
  • Toggle lock flag:切换表单中所有标签基准点的上锁状态,有下拉菜单。
  • Delete the highlighted markups from the active list:将被高亮选择的标签基准点的行删除。
  • Remove all markups from the active list:移除该表单中的所有标签基准点。
  • Transformed:选中的话将会在表格中显示转换坐标,这将会把转化节点应用到表单中的基准点上并显示结果。没选中则显示实际的RAS坐标值。
  • Hide RAS:选择在表格中是否隐藏坐标列,隐藏状态下也可以通过在表格的基准点上右击来获取坐标。

    3.Markups Table

                            3Dslicer_MarkupsModule第3张

      在该表格的行上右击,会弹出一个快捷菜单,其中会显示精确地坐标信息,以及同时选中多个高亮点的话显示点之间距离,菜单中还有一些功能操作包括删除高亮点,跳转二维视图中的切面,聚焦三维视图,以及在表单之间移动标签基准点。

  • Selected:这列有个选择框,它的选择状态即该标志基准点的旋转状态。可以切换基准点的选择状态,只有选中的标签才可以被传递到命令行模块(command line modules)。
  • Locked:这列的锁的状态决定了基准点的上锁状态。
  • Visibility:这列眼睛的状态决定了基准点的可视化状态。
  • Name:标志基准点的名字,较短,在视图中作为文本显示,放在图标之后。
  • Description:关于该标签的较长的描述,不会再视图中显示。
  • X, Y, Z:该标签的RAS坐标,三位有效数字。

    4.Advanced: Buttons、Naming、Conversion

                            3Dslicer_MarkupsModule第4张

  • Buttons:Move Up: 将表单中高亮的标签上一一个位置。
  • Buttons:Move Down: 下一一个位置         
  • Buttons:Add Markup:在选择的表单中添加一个标签基准点,默认在原点。
  • Naming:Name Format:为新创建的标签设置名字格式,使用C语言中sprintf 的格式类型,%N被表单名字替代,%d用整数替代。
  • Naming:Apply:根据当前的设置的名字格式为表单中的所有标签重新命名,一般会保留数字。若想快速将标签根据它们的索引重新命名,可以先将命名格式中数字去掉,apply重命名,然后在命名格式中加上数字格式%d,再一次apply重命名,就可以快速完成命名。
  • Conversion:Convert Annotation Fiducials to Markups Fiducial Lists:将注释基准点分层作为标签表单建立。

    5.Advanced: Display Properties

                                3Dslicer_MarkupsModule第5张

            用来设置图标类型、大小、颜色、透明度,以及文本的颜色、大小透明度等,还包括默认设置的操作。

    6.Advanced: Display Properties: Fiducuial Projection

                                3Dslicer_MarkupsModule第6张

      用来控制基准点的投影,高亮某个基准点,在2D视图中显示该基准点所在的切面,这部分就是用来控制其余的基准点在该切面上投影显示的。

  • 2D Projection:控制是否显示投影。
  • Use Fiducial Color:控制是否使用基准点原来的颜色。
  • Projection Color:自定义投影颜色。
  • Outlined Behind Slice Plane:切面下基准点的投影采用轮廓方式显示,切面上的基准点投影采用实心显示,且两种情况的投影均采用下面设置的透明度,基准点在切面上时,满透明度。一些图标样式无法用轮廓表示。
  • Projection Opacity:投影的透明度。

四、开发者必晓

    1.Python开发

  • 使用python打开Markups Module,将Markups Module用户界面设置为当前界面:
slicer.util.mainWindow().moduleSelector().selectModule('Markups')
  • 从文件中加载标志基准点表单:
slicer.util.loadMarkupsFiducialList('/path/to/list/F.fcsv') #当前路径为slicer.exe所在的路径
  • 使用代码在当前表单中添加标志基准点:
slicer.modules.markups.logic().AddFiducial() #默认放在原点处
  • 上面的命令添加参数初始化新建基准点的位置:
slicer.modules.markups.logic().AddFiducial(1.0, -2.0, 3.3)
  • 通过鼠标点击来添加基准点,将鼠标模式设置为标志基准点放置模式:
placeModePersistence = 1
slicer.modules.markups.logic().StartPlaceMode(placeModePersistence)

       也可以较低级的方式来实现,通过对selection和interaction nodes的操作:

selectionNode = slicer.mrmlScene.GetNodeByID("vtkMRMLSelectionNodeSingleton")
selectionNode.SetReferenceActivePlaceNodeClassName("vtkMRMLMarkupsFiducialNode")
interactionNode = slicer.mrmlScene.GetNodeByID("vtkMRMLInteractionNodeSingleton")
placeModePersistence = 1
interactionNode.SetPlaceModePersistence(placeModePersistence)
# mode 1 is Place, can also be accessed via slicer.vtkMRMLInteractionNode().Place
interactionNode.SetCurrentInteractionMode(1)

        放置完基准点后,切换鼠标模式到view transform模式:

interactionNode = slicer.mrmlScene.GetNodeByID("vtkMRMLInteractionNodeSingleton")
interactionNode.SwitchToViewTransformMode()
# also turn off place mode persistence if required
interactionNode.SetPlaceModePersistence(0)
  • 获取基准点的属性,标志基准点表单在代码中用类vtkMRMLMarkupsFiducialNode表示,并且每一个vtkMRMLMarkupsFiducialNode的实例都有一个指针,可以用python来获取:
fidNode = getNode("vtkMRMLMarkupsFiducialNode1")
n = fidNode.AddFiducial(4.0, 5.5, -6.0)    #n获得新添加的基准点在表单中的索引。

3Dslicer_MarkupsModule第7张

        

fidNode.SetNthFiducialLabel(n, "new label")    #设置基准点的名字

3Dslicer_MarkupsModule第8张

# each markup is given a unique id which can be accessed from the superclass level
id1 = fidNode.GetNthMarkupID(n)

3Dslicer_MarkupsModule第9张

# manually set the position
fidNode.SetNthFiducialPosition(n, 6.0, 7.0, 8.0)

3Dslicer_MarkupsModule第10张

# set the label
fidNode.SetNthFiducialLabel(n, "New label")
# set the selected flag, only selected = 1 fiducials will be passed to CLIs
fidNode.SetNthFiducialSelected(n, 1)
# set the visibility flag
fidNode.SetNthFiducialVisibility(n, 0)  
  • 可以循环表单中的基准点并获取它们的坐标
fidList = slicer.util.getNode('F')
numFids = fidList.GetNumberOfFiducials()
for i in range(numFids):
    ras = [0,0,0]
    fidList.GetNthFiducialPosition(i,ras)
    # the world position is the RAS position with any transform matrices applied
    world = [0,0,0,0]
    fidList.GetNthFiducialWorldCoordinates(i,world)
    print i,": RAS =",ras,", world =",world

3Dslicer_MarkupsModule第11张

    可以查看 Endoscopy module的代码来了解怎样用python在脚本模块(scripted module)获取基准点

  • VTK Widget 的获取:

    与标志基准点相关的3D显示管理器可以通过python获取,允许对vtkSeedWidget的调试:

fidNode = slicer.mrmlScene.GetNodeByID("vtkMRMLMarkupsFiducialNode1")   #获取指定的标志基准点表单节点对象指针
lm = slicer.app.layoutManager()                                         #获取slicer的布局管理器
td = lm.threeDWidget(0)                                                 #由布局管理器获取三维显示部件
ms = vtk.vtkCollection()                                                #创建容器
td.getDisplayableManagers(ms)                                           #将三维显示部件中的所有显示管理器放入容器,三维显示部件中
for i in range(ms.GetNumberOfItems()):                                  #有多个类的显示管理器,如AnnotationRuler和AnnotationROI等
   m = ms.GetItemAsObject(i)
   if m.GetClassName() == "vtkMRMLMarkupsFiducialDisplayableManager3D": #当遍历到的显示管理器是标志基准点的3D显示管理器时
     print i, m.GetClassName()
     h = m.GetHelper()
     seedWidget = h.GetWidget(fidNode)                                   #获取对应于不同标志基准点表单节点的种子部件
     seedRepresentation = seedWidget.GetSeedRepresentation()
     handleRep2 = seedRepresentation.GetHandleRepresentation(2)          #标志基准点表单中索引为2的基准点显示信息  
     print handleRep2.GetDisplayPosition()
     print handleRep2.GetWorldPosition()

    三维部件中的显示管理器:

                        3Dslicer_MarkupsModule第12张
        同样的,与标志基准点相关的2D显示管理器可以通过python获取,也可以调试2D中的seed widget:

fidNode = slicer.mrmlScene.GetNodeByID("vtkMRMLMarkupsFiducialNode1")
lm = slicer.app.layoutManager()
redWidget = lm.sliceWidget("Red")
redView = redWidget.sliceView()
ms = vtk.vtkCollection()
redView.getDisplayableManagers(ms)
for i in range(ms.GetNumberOfItems()):
  m = ms.GetItemAsObject(i)
  if m.GetClassName() == "vtkMRMLMarkupsFiducialDisplayableManager2D":
    print i, m.GetClassName()
    h = m.GetHelper()
    seedWidget = h.GetWidget(fidNode)
    seedRepresentation = seedWidget.GetSeedRepresentation()
    handleRep = seedRepresentation.GetHandleRepresentation(0)
    print handleRep.GetDisplayPosition()

        二维部件中的显示管理器
                               3Dslicer_MarkupsModule第13张

    2.C++开发

  • Selection and Interaction

对于Selection and Interaction节点,Selection节点一般用于设置改变操作节点的类型,如注释标尺、注释ROI等。Interaction节点用于改变鼠标模式和一些交互操作。首先确保你获取到了在场景中存在的单节点,而不是自己创建,类型为vtkMRMLInteractionNode和vtkMRMLSelectionNode,ID为vtkMRMLInteractionNodeSingleton和vtkMRMLSelectionNodeSingleton:

vtkMRMLApplicationLogic *mrmlAppLogic = this->GetMRMLApplicationLogic();
vtkMRMLInteractionNode *inode = mrmlAppLogic->GetInteractionNode();
vtkMRMLSelectionNode *snode = mrmlAppLogic->GetSelectionNode();

如果在mrml application logic中得不到这两种节点,可以从场景中获取:

vtkMRMLInteractionNode *interactionNode = vtkMRMLInteractionNode::SafeDownCast(this->GetMRMLScene()->GetNodeByID("vtkMRMLInteractionNodeSingleton"));

接下来你就可以调用节点中的方法来实现你想要的效果,或者添加自己的场景事件观察者:

 vtkSlicerMarkupsModuleLogic::ObserveMRMLScene

会监视场景中的节点变化,接下来可以在vtkSlicerMarkupsModuleLogic::ProcessMRMLNodesEvents中查看怎样对interaction node的改变做出反应。
Slicer4/Base/QTGUI/qSlicerMouseModeToolBar.cxx中也有一些代码采用简便的方式在 mrml app logic 中获取两类节点。
调用下面的方法将鼠标模式转变为基准点放置模式:

selectionNode->SetReferenceActivePlaceNodeClassName("vtkMRMLMarkupsFiducialNode");
interactionNode->SetCurrentInteractionMode(vtkMRMLInteractionNode::Place);

如果你没有调用interaction节点中的方法SetPlaceModePersistence()来设置PlaceModePersistence,那么在你进行完一次放置后,当前的交互模式将返回到原来的view transform,你讲需要重新设置交互模式来进行下一步的放置(前面设置的PlaceNodeClassName不会改变)。简单来讲就是你并没有设置注释的连续放置,那么在防止玩一次之后还要重新将交互模式设置为放置模式,但放置的节点类型做了保留,不用重新设置。

  • 编程获取基准点

这部分解释怎样获取用户添加到场景中的基准点节点。

第一部分:在你的模块的Logic类中,重写SetMRMLSceneInternal函数,来观察场景中的节点添加事件(NodeAddedEvent):

void vtkSlicerMYMODULEModuleLogic::SetMRMLSceneInternal(vtkMRMLScene * newScene)
  {
  vtkNew<vtkIntArray> events;
  events->InsertNextValue(vtkMRMLScene::NodeAddedEvent);
  // Optionally you can add more events here, 
  // such as vtkMRMLScene::NodeRemovedEvent
  this->SetAndObserveMRMLSceneEventsInternal(newScene, events.GetPointer());
  }

第二部分:通过上面的设置和观察mrml场景宏,任何时候在场景中添加节点,将会触发调用Logic基类的方法 method vtkMRMLAbstractLogic::ProcessMRMLNodesEvents,在这个方法里又会调用虚方法 vtkMRMLAbstractLogic::OnMRMLSceneNodeAdded(vtkMRMLNode* node),你可以在自己的Logic中重写该方法完成对节点的获取:

void vtkSlicerMYMODULEModuleLogic::OnMRMLSceneNodeAdded(vtkMRMLNode* addedNode)
  {
  vtkMRMLMarkupsFiducialNode* fidNode =
    vtkMRMLMarkupsFiducialNode::SafeDownCast(addedNode);
  if (fidNode)
    {
    // here you write what you need to do when a 
    // fiducial node is added into the scene
    }
  }

2.该类文件.fcsv的格式

.fcsv文件中保存的就是在场景中添加的标志基准点表单节点的相关数据,打开这类文件:

3Dslicer_MarkupsModule第14张

使用逗号分隔值文件来存储节点:
 

第一行注释行给出slicer版本信息:

# Markups fiducial file version = 4.7

第二行注释行给出使用的坐标系统(RAS = 0, LPS = 1, IJK = 2 ):

# CoordinateSystem = 0

第三行注释行给出下面的列信息:

# columns = id,x,y,z,ow,ox,oy,oz,vis,sel,lock,label,desc,associatedNodeID

接下来每一行代表一个基准点信息,按上面的标注排序:

vtkMRMLMarkupsFiducialNode_4,19.8892,3.10894,-10.2143,0,0,0,1,1,1,0,F_1-1,,vtkMRMLScalarVolumeNode1
  • id = a string giving a unique id for this fiducial, usually based on the class name
  • x,y,z = the floating point coordinate of the fiducial point
  • ow,ox,oy,oz = the orientation quaternion of this fiducial, angle and axis, default 0,0,0,1 (or 0,0,0,0,0,0,1.0)
  • vis = the visibility flag for this fiducial, 0 or 1, default 1
  • sel = the selected flag for this fiducial, 0 or 1, default 1
  • lock = the locked flag for this fiducial, 0 or 1, default 0
  • label = the name for this fiducial, displayed beside the glyph, with quotes around it if there is a comma in the field
  • desc = a string description for this fiducial, optional
  • associatedNodeID = an id of a node in the scene with which the fiducial is associated, for example the volume or model on which the fiducial was placed, optional

这类文件可以使用字符串流和getline来解析:

 std::fstream fstr;
 fstr.open(fileName.c_str(), std::fstream::in);
 char line[1024];
 while (fstr.good())
    {
    fstr.getline(line, 1024);
    std::stringstream ss(line);
    std::string component;
    getline(ss, component, ',');
    [...]
    }

参考:

https://www.slicer.org/wiki/Documentation/4.8/Modules/Markups#References

免责声明:文章转载自《3Dslicer_MarkupsModule》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇python-pyppeteer模块使用汇总工作日记-storm集群业务崩溃和解决方案下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

PostgreSQL之 使用扩展Extension

   目前开发中用到的都是PostgreSQL的一些基本的功能,无意间查到PostgreSQL还支持Extension,不仅源码包中自带有Extension,还有一些其他非官方的Extension。现在不用,记录一下,以后碰到问题时希望自己能想起来,也是一个思路吧。         pg_partman 是 PostgreSQL 的一个扩展插件,用于创建和...

Wordpresss建站笔记:Astra主题修改底部菜单

描述: 1.点击 Appearance >>> Customize >>> 2.点击底部菜单的编辑,编辑后Published,不能生效。 3.回到菜单项,点击Footer Builder,进入底部模块编辑页面。  4.  选中对应模块,(此处为Widget4); 5.修改标题 Important Links 为...

urllib的使用

urllib的使用 urllib是python内置的HTTP请求库,包含如下四个模块: request:它是最基本HTTP请求模块,可以用来模拟发送请求,就像在浏览器里输入网址然后按回车一样,只需要传入URL以及额外的参数,就可以模拟实现这个过程了。 error:异常处理模块,如果出现请求错误,可以捕获到这些异常,然后进行重试或其他操作以保证程序不会意外终...

一个简单的项目介绍流程

以一个简单的项目进行介绍说明: • 最近测试的Tpshop项目是一个B/S架构的Web项目。Tpshop是一个 B2C的电商平台系统,运营模式类似于天猫,京东这些B2C类型网站。 • 项目系统由前台和后台两部分构成。前台面向购物用户,包括会员、商品展示、购物车、订单、支付、用户中心等系统模块。后台面向经营商家,包括商品管理,会员管理,订单处理等系统模块。...

Chrome开发者之测试应用

一、Chrome开发者工具简介 1.1、开发者工具(DevTools)调用 二、Chrome DevTools详细介绍 1.1、模块介绍 2.1、元素(Elements)详解 2.1.1、元素编辑 2.1.2、辅助元素定位 2.1.3、ChroPath插件 3.1、控制台(Console)详解 4.1、源代码(Sources)详解 5.1、网络(Netwo...

macOS平台下虚拟摄像头的研发总结

一、背景介绍     虚拟摄像头,顾名思义,就是利用软件技术虚拟出一个摄像头硬件设备供用户使用。当我们需要对视频图像进行处理再输出时,虚拟摄像头就具备非常大的价值了。关于如何在Windwos上实现一个虚拟设备的资料已经非常丰富了,Windows Driver Kit里面也有非常多的帮助文档。这篇博文主要总结了在Mac下开发虚拟摄像头的一些经验。Mac下的虚...