Difference between revisions of "OpenIGTLink/Slicer"

From NAMIC Wiki
Jump to: navigation, search
 
(114 intermediate revisions by 3 users not shown)
Line 1: Line 1:
 
[[OpenIGTLink | << OpenIGTLink]]
 
[[OpenIGTLink | << OpenIGTLink]]
  
=Introduction=
+
=Overview=
The OpenIGTLink module is a communication interface between 3D Slicer and Open-IGT-Link-compliant  devices. It enables the 3D SLicer to import various types of data such as real-time images, tracking data and other user-defined commands and data. The module supports multiple device connections. Each of connections can be configured as either server mode (the Slicer waits connections from devices) or client mode (the Slicer request connection to clients) independently.
 
  
The module works with MRML to exchange coordinate and image data with other clinical modules e.g. NeuroNav and ProstateNav in the Slicer. The module has a dedicated graphical user interface to manage and control multiple connections.
+
The 3D Slicer OpenIGTLink Interface Module is a program module that can handle network communications between  [http://www.slicer.org 3D Slicer] and external software / hardware using [[OpenIGTLink]] protocol. The module provides following functions:
 +
 
 +
*Data import: The module can import position, linear transform and image data from [[OpenIGTLink/List| OpenIGTLink-compliant software / hardware]] to the [[NA-MIC/Projects/NA-MIC_Kit/MRML| MRML]] scene.
 +
*Data export: The module can export linear transform and image data from the MRML scene.
 +
*Multi-connection: The module can manage multiple OpenIGTLink connections at the same time.
 +
*Locator visualization: The user can choose one of linear transforms in the MRML scene to visualize its position and orientation in the 3D space.
 +
*Slice driving: The module can control volume re-slicing plane based on linear transform in the MRML scene.
 +
 
 +
 
 +
[[Image:OpenIGTLink_Slicer_Screenshot.png]]
  
 
=Install the Software=
 
=Install the Software=
  
 
==From binaries==
 
==From binaries==
 +
The module is available only in Slicer 3.3 source distribution.
 +
For Slicer 3.2, please see [[OpenIGTLink/Slicer_3_2| old page]].
  
The Open IGT Link is currently distributed as a loadable module for 3D Slicer. You need to obtain 3D Slicer and Module object.
+
==From source==
  
=== 3D Slicer (Version 3.2 release)===
+
Building instruction can be found in [[OpenIGTLink/Slicer/Build]].
* [http://www.slicer.org/DownloadSlicer.php/Nightly/Slicer3-3.2.2008-06-02-win32.exe For Windows (32-bit)]
 
* [http://www.slicer.org/DownloadSlicer.php/Nightly/Slicer3-3.2.2008-06-02-linux-x86.tar.gz For Linux (x86, 32-bit)]
 
* [http://www.slicer.org/DownloadSlicer.php/Nightly/Slicer3-3.2.2008-06-02-linux-x86_64.tar.gz For Linux (x86, 64-bit)]
 
* [http://www.slicer.org/DownloadSlicer.php/Nightly/Slicer3-3.2.2008-06-02-darwin-x86.tar.gz For Mac OS X (x86)]
 
* [http://www.slicer.org/DownloadSlicer.php/Nightly/Slicer3-3.2.2008-06-02-darwin-ppc.tar.gz For Mac OS X (PPC)]
 
  
=== Open IGT Link Loadable Module (for Version 3.2)===
 
* [[Media:OpenIGTLink_3.2_Linux_x86_32.tgz| For Linux (x86, 32-bit)]].
 
* [[Media:OpenIGTLink_3.2_Linux_x86_64.tgz| For Linux (x86, 64-bit)]].
 
* [[Media:OpenIGTLink_3.2_Win_x86_32.zip| For Windows (32-bit)]].
 
* [[Media:OpenIGTLink_Darwin_3.2_x86.tgz| For Mac OS X(x86)]].
 
  
=== Install ===
+
<br>
* Copy the binary into '''your-slicer3-build(install)-directory'''/lib/Slicer3/Modules.
 
* You should see '''OpenIGTLink''' in the Slicer3 module list after Slicer is started.
 
  
==Build from source==
+
=Tutorial (for users)=
===Build 3D Slicer===
+
==Simulators==
Please refer instruction in [http://www.slicer.org/slicerWiki/index.php/Slicer3:Build_Instructions].
 
  
===Build Open IGT Link Loadable Module===
+
To test the OpenIGTLink interface module (or other OpenIGTLinkcomplaint devices and software), tracking simulator software is provided as an example program of the OpenIGTLink library (note that the OpenIGTLink library is different from the OpenIGTLink interface module in 3D Slicer).
  
Before build the module, please make sure that your CMake's version is higher than 2.6.
+
===From binaries===
You can find it in Slicer3-lib/CMake-build directory, which was created during building 3D Slicer.
+
Obtain a binary file for your environment.  
 +
* [[Media:OpenIGTLinkExamples_Linux_x86_32.tgz|For Linux (x86, 32-bit)]].
 +
* [[Media:OpenIGTLinkExamples_Linux_x86_64.tgz|For Linux (x86, 64-bit)]].
 +
* [[Media:OpenIGTLinkExamples_Win_x86_32.zip|For Windows (32-bit)]].
 +
* [[Media:OpenIGTLinkExamples_Darwin_x86.tgz |For Mac OS X (x86)]].
 +
* [[Media:OpenIGTLinkExamples_Darwin_ppc.tgz |For Mac OS X (PPC)]].
  
First, get the source code from the repository. For Linux and Mac:
+
===From Source===
  $ cd <working directory>
 
  $ svn co http://www.na-mic.org/svn/NAMICSandBox/trunk/IGTLoadableModules/OpenIGTLink OpenIGTLink
 
  
Create build direcotry
+
The instruction can be found in [[OpenIGTLink/Library/Build]]. Please make sure that you enable "build examples" option.
  $ mkdir OpenIGTLink-build
 
  $ cd OpenIGTLink-build
 
  
Then configure by using CMake
+
<br>
  $ cmake -DSlicer3_DIR=<Path to Slicer-build directory> ../OpenIGTLink
 
 
If the previous command has completed without error, you can start compiling
 
  $ make
 
  
After the compilation, you will find libOpenIGTLink.so (Linux) libOpenIGTLink.dylib (Mac) in OpenIGTLink-build dirctory.
+
==Show Tracking Device in the 3D Slicer==
  
<br>
+
===Set up Open IGT Link Module===
 +
 
 +
# Select "OpenIGTLinkIF" from "Modules:" menu
 +
# Open "Connector Browser" frame, and press "Add" button below the "Connectors" list to add a new connector
 +
# Configure and start the connector. Choose "Server" check box in the "Type" option, then clinck "Active" check box. Now the Slicer is ready to accept connections through Open IGT Link.
  
=Tracker Simulator for Testing=
+
===Run Tracker Simulator===
 +
Go to OpenIGTLink binary directory.
 +
$ cd <path to OpenIGTLink-build>/bin
  
To test the Open IGT Link module (or other Open-IGT-Link-complaint devices and software), tracking simulator software is provided. This software simply sends dummy coordinate data to the server with specified frame rate.
+
To send dummy coordinate data to the Slicer running on localhost with frame rate of 10 fps, run:
You can either obtain the software as a binary code or build from source.
+
$ ./TrackerClient  localhost 18944 10
  
==From binaries==
+
===Visualize Tracker Position===
* [[Media:TrackerSimulator_Linux_x86_32.tgz|For Linux (x86, 32-bit)]].
+
To see the coordinate from the Tracker Simulator,
* [[Media:TrackerSimulator_Linux_x86_64.tgz|For Linux (x86, 64-bit)]].
+
# Open "Visualization / Slice Control" frame in the OpenIGTLink module interface.
* [[Media:TrackerSimulator_Win_x86_32.zip|For Windows (32-bit)]].
+
# Choose "Tracker (LinearTransform) from Locator Source menu in Locator Display frame.
* [[Media:TrackerSimulator_Darwin_x86.tgz |For Mac OS X (x86)]].
+
# Click the "Show Locator" check button. A locator model shows up on the 3D viewer.
 +
 
 +
<br>
  
==From Source==
+
=Architecture (for developers)=
 +
==Overview==
 +
The OpenIGTLink Interface module is designed to adapt to the 3D Slicer’s scene graph mechanism called Medical Reality Modeling Language (MRML) architecture. MRML provides a unified way to handle various kinds of data including images, transforms, and models in the IGT setting as MRML nodes. In order to manage multiple nodes, all MRML nodes have a tree structure. For example, the user can apply a transform to an image by placing it under the transform node as a child node. When the OpenIGTLink module receives an OpenIGTLink message, it creates a MRML node with the same name as the "device name" in the message and imports the data to the node. If a node with the same name and data type already exists, the module simply updates the data. The module also can export the data from a MRML node through the OpenIGTLink interface. This mechanism maximizes the flexibility to import/export data to/from 3D Slicer, since users can configure the MRML node tree interactively without changing the source code of the software. In addition, this mechanism makes it easy for other software modules to exchange data with external software or hardware through OpenIGTLink.
  
To get the source code, run following commands:
+
=="Connectors"==
$ mkdir <working directory>
+
To manage multiple OpenIGTLink communications simultaneously, the OpenIGTLink Interface module handles an OpenIGTLink connection as a "connector". One connector can establish only one connection, and the user can add as many connectors as needed from the graphical user interface (GUI). Each connector can be configured as either server or client independently (Figure 1). Note that this does not mean directions of data stream; it just determines whether the module or the external software / hardware waits for (listens to) the other side to initiate the connection. Once the connection is established, there is no difference between server and client connectors.
$ svn co http://www.na-mic.org/svn/NAMICSandBox/trunk/BRPTools/ScannerIO ScannerIO
 
  
Then configure the source code
+
[[image:Slicer3_OpenIGTLinkIF_Architecture.png|thumb|center|500px|'''Figure 1.''' The figure shows an example schematic diagram where multiple devices are communicating with 3D Slicer through the OpenIGTLink Interface. Each connector is assigned to one of the external devices for TCP/IP connection. The connectors serve as interfaces between the external devices and the MRML scene to convert an OpenIGTLink message to a MRML node or vice versa. ]]
$ cd ScannerIO
 
$ ccmake .
 
  
Usually, you don't need to change any setting. Just press 'c' key by 'g' key to generate Makefiles. Press 'q' to quit the ccmake interface. Now you are ready to build the program.
+
From the developers' point of view, a connector is handled as an instance of vtkIGTLConnector class, which is defined in Modules/OpenIGTLinkIF/vtkIGTLConnector.cxx and vtkIGTLConnectors.h. Each instance has a thread to monitor communication with an external hardware / software.
$ make
 
  
The executable file can be found in ScannerIO/bin directory.
+
==Event-driven==
 +
The OpenIGTLink Interface module is driven by two types of events: arrivals of OpenIGTLink messages and update events in the MRML scene. The module monitors incoming messages, and once it receives a message, it starts a deserialization process to import the data into the MRML scene as a MRML node.  Other software modules in 3D Slicer can recognize that the data has been imported into the MRML scene by catching the MRML event. The module also monitors events from MRML nodes, which the user has registered as nodes to export. When one of the nodes is updated from elsewhere in 3D Slicer, the module catches the update event and starts serializing the data into an OpenIGTLink message. The serialized data is transfered to the device through an OpenIGTLink connection.
 +
This event-driven architecture allows other software modules in 3D Slicer to exchange various kinds of data with external hardware and software without accessing the API of the OpenIGTLink interface (in other words, with little modification of the code).
  
<br>
+
=="Plug-in" OpenIGTLink-vtkMRMLNode message converter==
 +
The module has "plug-in" OpenIGTLink-vtkMRMLNode converter mechanisms, where OpenIGTLink-vtkMRMLNode converting routines are defined as classes independent from the connectors. Thus the developers can add a new data type that is handled by the OpenIGTLink interface module without modifying the module itself. All OpenIGTLink-vtkMRMLNode converting classes are child classes of '''vtkIGTLToMRMLBase''', which defines several virtual functions called by the OpenIGTLink interface module. Instances of those classes are registered before receiving OpenIGTLink messages or exporting vtkMRMLnode.
  
=Testing Open IGT Link Module -- Show Tracking Device in the 3D Space=
+
The following member functions are defined in classes derived from vtkIGTLToMRMLBase class:
  
==Set up Open IGT Link Module==
+
  virtual const char*  GetIGTLName();
 +
  virtual const char*  GetMRMLName();
 +
  virtual vtkIntArray* GetNodeEvents();
 +
  virtual vtkMRMLNode* CreateNewNode(vtkMRMLScene* scene, const char* name);
 +
  virtual int          IGTLToMRML(igtl::MessageBase::Pointer buffer, vtkMRMLNode* node);
 +
  virtual int          MRMLToIGTL(unsigned long event, vtkMRMLNode* mrmlNode, int* size, void** igtlMsg);
  
# Select "OpenIGTLink" from "Modules:" menu
+
'''GetIGTLName()''' and '''GetMRMLName()''' are functions to get the character strings of "device name" of OpenIGTLink messages and "node tag name" of MRML nodes handled by the class. For example, in the case of the position data type, GetIGTLName() returns "POSITION" and GetMRMLName() returns "vtkMRMLLinearTransform", meaning that the class can convert an OpenIGTLink message with the device name "POSITION" into a MRML node with tag name '''LinearTransform''' and vice versa. '''GetNodeEvents()''' is a function to get a list of events to invoke the routine to convert the MRML node into an OpenIGTLink message, which is defined in '''MRMLToIGTL()'''. '''CreateNewNode()''' function defines a routine to create a new MRML node, when the OpenIGTLink module cannot find a MRML node to store the received data. Data conversion from OpenIGTLink message to MRML node and MRML node to OpenIGTLink message are defined as '''IGTLToMRML()''' and '''MRMLToIGTL()'''.
# Open "Connector Browser" frame, and press "Add" button below the "Connectors" list to add a new connector
 
# Configure and start the connector. Choose "Server" check box in the "Type" option, then clinck "Active" check box. Now the Slicer is ready to accept connections through Open IGT Link.
 
  
==Run Tracker Simulator==
+
OpenIGTLink-vtkMRMLNode converter classes can be registered from other program modules using a member function of vtkOpenIGTLinkIFLogic class as (NOTE "IGTLLogic is a pointer to the OpenIGTLinkIFLogic class):
To send dummy coordinate data to the Slicer running on localhost with frame rate of 10 fps, run:
 
$ cd bin
 
$ ./TrackerSim  10  c  localhost 18944
 
  
==Visualize Tracker Position==
+
  vtkIGTLToMRMLLinearTransform* LinearTransformConverter = vtkIGTLToMRMLLinearTransform::New();
To see the coordinate from the Tracker Simulator,
+
  vtkIGTLToMRMLImage* ImageConverter = vtkIGTLToMRMLImage::New();
# Open "Visualization / Slice Control" frame in the OpenIGTLink module interface.
+
  vtkIGTLToMRMLPosition* PositionConverter = vtkIGTLToMRMLPosition::New();
# Click the "Show Locator" check button. A locator model shows up on the 3D viewer.
+
  IGTLLogic->RegisterMessageConverter(LinearTransformConverter);
# Open "Data" module. Choose "Data" from "Modules:" menu.
+
  IGTLLogic->RegisterMessageConverter(ImageConverter);
# Edit MRML tree. Put "IGTLocator" under the "Tracker" by dragging "IGTLocator" node.
+
  IGTLLogic->RegisterMessageConverter(PositionConverter);
# You should see the locator model moves in the 3D viewer.
 
  
<br>
+
=Loadmap/Action items=
 +
*Abstracted I/O -- allows users to switch between network I/O and file I/O. It can be useful to support logging function.
  
=Testing Open IGT Link Module -- Reslice 3D image=
+
<BR>
We can reslice 3D image according to the locator position with following steps:
 
# Load 3D volume from the "Volumes" module.
 
# Start Tracking as we did in the previous section.
 
# In the "Visualization / Slice Control" frame in the OpenIGTLink module interface, click Red menu and choose "Locator".
 
# The image in the left 2D slice viewer (Red) should start to move. You can change the orientation by changing slice orientation menu in the 2D slice viewer.
 
# If you click the "Oblique" check button in the "Visualization / Slicer Control" frame, the slice orientation is set according to the locator orientation.
 
# You can use other 2D viewers (Yellow and Green) by choosing "Locator" from the Yellow and Green menu in the "Visualization / Slice Control" frame.
 
  
<br>
+
=Other Resources=
 +
*[[OpenIGTLink/Simulators]]
  
 
=People=
 
=People=
 
*[http://www.spl.harvard.edu/pages/People/tokuda  Junichi Tokuda]
 
*[http://www.spl.harvard.edu/pages/People/tokuda  Junichi Tokuda]
 
*[http://www.spl.harvard.edu/pages/People/hliu Haiying Liu]
 
*[http://www.spl.harvard.edu/pages/People/hliu Haiying Liu]

Latest revision as of 01:38, 23 December 2008

Home < OpenIGTLink < Slicer

<< OpenIGTLink

Overview

The 3D Slicer OpenIGTLink Interface Module is a program module that can handle network communications between 3D Slicer and external software / hardware using OpenIGTLink protocol. The module provides following functions:

  • Data import: The module can import position, linear transform and image data from OpenIGTLink-compliant software / hardware to the MRML scene.
  • Data export: The module can export linear transform and image data from the MRML scene.
  • Multi-connection: The module can manage multiple OpenIGTLink connections at the same time.
  • Locator visualization: The user can choose one of linear transforms in the MRML scene to visualize its position and orientation in the 3D space.
  • Slice driving: The module can control volume re-slicing plane based on linear transform in the MRML scene.


OpenIGTLink Slicer Screenshot.png

Install the Software

From binaries

The module is available only in Slicer 3.3 source distribution. For Slicer 3.2, please see old page.

From source

Building instruction can be found in OpenIGTLink/Slicer/Build.



Tutorial (for users)

Simulators

To test the OpenIGTLink interface module (or other OpenIGTLinkcomplaint devices and software), tracking simulator software is provided as an example program of the OpenIGTLink library (note that the OpenIGTLink library is different from the OpenIGTLink interface module in 3D Slicer).

From binaries

Obtain a binary file for your environment.

From Source

The instruction can be found in OpenIGTLink/Library/Build. Please make sure that you enable "build examples" option.


Show Tracking Device in the 3D Slicer

Set up Open IGT Link Module

  1. Select "OpenIGTLinkIF" from "Modules:" menu
  2. Open "Connector Browser" frame, and press "Add" button below the "Connectors" list to add a new connector
  3. Configure and start the connector. Choose "Server" check box in the "Type" option, then clinck "Active" check box. Now the Slicer is ready to accept connections through Open IGT Link.

Run Tracker Simulator

Go to OpenIGTLink binary directory.

$ cd <path to OpenIGTLink-build>/bin

To send dummy coordinate data to the Slicer running on localhost with frame rate of 10 fps, run:

$ ./TrackerClient  localhost 18944 10

Visualize Tracker Position

To see the coordinate from the Tracker Simulator,

  1. Open "Visualization / Slice Control" frame in the OpenIGTLink module interface.
  2. Choose "Tracker (LinearTransform) from Locator Source menu in Locator Display frame.
  3. Click the "Show Locator" check button. A locator model shows up on the 3D viewer.


Architecture (for developers)

Overview

The OpenIGTLink Interface module is designed to adapt to the 3D Slicer’s scene graph mechanism called Medical Reality Modeling Language (MRML) architecture. MRML provides a unified way to handle various kinds of data including images, transforms, and models in the IGT setting as MRML nodes. In order to manage multiple nodes, all MRML nodes have a tree structure. For example, the user can apply a transform to an image by placing it under the transform node as a child node. When the OpenIGTLink module receives an OpenIGTLink message, it creates a MRML node with the same name as the "device name" in the message and imports the data to the node. If a node with the same name and data type already exists, the module simply updates the data. The module also can export the data from a MRML node through the OpenIGTLink interface. This mechanism maximizes the flexibility to import/export data to/from 3D Slicer, since users can configure the MRML node tree interactively without changing the source code of the software. In addition, this mechanism makes it easy for other software modules to exchange data with external software or hardware through OpenIGTLink.

"Connectors"

To manage multiple OpenIGTLink communications simultaneously, the OpenIGTLink Interface module handles an OpenIGTLink connection as a "connector". One connector can establish only one connection, and the user can add as many connectors as needed from the graphical user interface (GUI). Each connector can be configured as either server or client independently (Figure 1). Note that this does not mean directions of data stream; it just determines whether the module or the external software / hardware waits for (listens to) the other side to initiate the connection. Once the connection is established, there is no difference between server and client connectors.

Figure 1. The figure shows an example schematic diagram where multiple devices are communicating with 3D Slicer through the OpenIGTLink Interface. Each connector is assigned to one of the external devices for TCP/IP connection. The connectors serve as interfaces between the external devices and the MRML scene to convert an OpenIGTLink message to a MRML node or vice versa.

From the developers' point of view, a connector is handled as an instance of vtkIGTLConnector class, which is defined in Modules/OpenIGTLinkIF/vtkIGTLConnector.cxx and vtkIGTLConnectors.h. Each instance has a thread to monitor communication with an external hardware / software.

Event-driven

The OpenIGTLink Interface module is driven by two types of events: arrivals of OpenIGTLink messages and update events in the MRML scene. The module monitors incoming messages, and once it receives a message, it starts a deserialization process to import the data into the MRML scene as a MRML node. Other software modules in 3D Slicer can recognize that the data has been imported into the MRML scene by catching the MRML event. The module also monitors events from MRML nodes, which the user has registered as nodes to export. When one of the nodes is updated from elsewhere in 3D Slicer, the module catches the update event and starts serializing the data into an OpenIGTLink message. The serialized data is transfered to the device through an OpenIGTLink connection. This event-driven architecture allows other software modules in 3D Slicer to exchange various kinds of data with external hardware and software without accessing the API of the OpenIGTLink interface (in other words, with little modification of the code).

"Plug-in" OpenIGTLink-vtkMRMLNode message converter

The module has "plug-in" OpenIGTLink-vtkMRMLNode converter mechanisms, where OpenIGTLink-vtkMRMLNode converting routines are defined as classes independent from the connectors. Thus the developers can add a new data type that is handled by the OpenIGTLink interface module without modifying the module itself. All OpenIGTLink-vtkMRMLNode converting classes are child classes of vtkIGTLToMRMLBase, which defines several virtual functions called by the OpenIGTLink interface module. Instances of those classes are registered before receiving OpenIGTLink messages or exporting vtkMRMLnode.

The following member functions are defined in classes derived from vtkIGTLToMRMLBase class:

 virtual const char*  GetIGTLName();
 virtual const char*  GetMRMLName();
 virtual vtkIntArray* GetNodeEvents();
 virtual vtkMRMLNode* CreateNewNode(vtkMRMLScene* scene, const char* name);
 virtual int          IGTLToMRML(igtl::MessageBase::Pointer buffer, vtkMRMLNode* node);
 virtual int          MRMLToIGTL(unsigned long event, vtkMRMLNode* mrmlNode, int* size, void** igtlMsg);

GetIGTLName() and GetMRMLName() are functions to get the character strings of "device name" of OpenIGTLink messages and "node tag name" of MRML nodes handled by the class. For example, in the case of the position data type, GetIGTLName() returns "POSITION" and GetMRMLName() returns "vtkMRMLLinearTransform", meaning that the class can convert an OpenIGTLink message with the device name "POSITION" into a MRML node with tag name LinearTransform and vice versa. GetNodeEvents() is a function to get a list of events to invoke the routine to convert the MRML node into an OpenIGTLink message, which is defined in MRMLToIGTL(). CreateNewNode() function defines a routine to create a new MRML node, when the OpenIGTLink module cannot find a MRML node to store the received data. Data conversion from OpenIGTLink message to MRML node and MRML node to OpenIGTLink message are defined as IGTLToMRML() and MRMLToIGTL().

OpenIGTLink-vtkMRMLNode converter classes can be registered from other program modules using a member function of vtkOpenIGTLinkIFLogic class as (NOTE "IGTLLogic is a pointer to the OpenIGTLinkIFLogic class):

 vtkIGTLToMRMLLinearTransform* LinearTransformConverter = vtkIGTLToMRMLLinearTransform::New();
 vtkIGTLToMRMLImage* ImageConverter = vtkIGTLToMRMLImage::New();
 vtkIGTLToMRMLPosition* PositionConverter = vtkIGTLToMRMLPosition::New();
 IGTLLogic->RegisterMessageConverter(LinearTransformConverter);
 IGTLLogic->RegisterMessageConverter(ImageConverter);
 IGTLLogic->RegisterMessageConverter(PositionConverter);

Loadmap/Action items

  • Abstracted I/O -- allows users to switch between network I/O and file I/O. It can be useful to support logging function.


Other Resources

People