Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
mitkIGTTutorialStep1.cpp
Go to the documentation of this file.
1 /*===================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center,
6 Division of Medical and Biological Informatics.
7 All rights reserved.
8 
9 This software is distributed WITHOUT ANY WARRANTY; without
10 even the implied warranty of MERCHANTABILITY or FITNESS FOR
11 A PARTICULAR PURPOSE.
12 
13 See LICENSE.txt or http://www.mitk.org for details.
14 
15 ===================================================================*/
16 
19 #include <mitkIOUtil.h>
20 
21 #include <mitkNavigationData.h>
26 
27 #include <itksys/SystemTools.hxx>
28 
29 //##Documentation
30 //## \brief A small console tutorial about MITK-IGT
31 int main(int /*argc*/, char* /*argv*/[])
32 {
33  //The next line starts a snippet to display this code in the documentation. If you don't revise the documentation, don't remove it!
35  //*************************************************************************
36  // What we will do...
37  //*************************************************************************
38  //In this tutorial we build up a small navigation pipeline with a virtual tracking device
39  //which produce random positions and orientation so no additional hardware is required.
40  //
41  //The source of the pipeline is a TrackingDeviceSource object. This we connect to a simple
42  //filter which just displaces the positions with an offset. After that we use a recorder
43  //to store this new positions and other information to disc in a XML file. After that, we use
44  //another source (NavigationDataPlayer) to replay the recorded data.
46 
48  //*************************************************************************
49  // Part I: Basic initialization of the source and tracking device
50  //*************************************************************************
51  //First of all create a tracking device object and two tools for this "device".
52 
53  //Here we take the VirtualTrackingDevice. This is not a real tracking device it just delivers random
54  //positions and orientations. You can use other/real tracking devices if you replace the following
55  //code with different tracking devices, e.g. mitk::NDITrackingDevice. The tools represent the
56  //sensors of the tracking device. The TrackingDevice fills the tools with data.
57  std::cout << "Generating TrackingDevice ..." << std::endl;
58 
60  tracker->AddTool("tool1");
61  tracker->AddTool("tool2");
63 
65  //The tracking device object is used for the physical connection to the device. To use the
66  //data inside of our tracking pipeline we need a source. This source encapsulate the tracking device
67  //and provides objects of the type mitk::NavigationData as output. The NavigationData objects stores
68  //position, orientation, if the data is valid or not and special error informations in a covariance
69  //matrix.
70  //
71  //Typically the start of our pipeline is a TrackingDeviceSource. To work correct we have to set a
72  //TrackingDevice object. Attention you have to set the tools before you set the whole TrackingDevice
73  //object to the TrackingDeviceSource because the source need to know how many outputs should be
74  //generated.
75 
76  std::cout << "Generating Source ..." << std::endl;
77 
79  source->SetTrackingDevice(tracker); //here we set the device for the pipeline source
80 
81  source->Connect(); //here we connect to the tracking system
82  //Note we do not call this on the TrackingDevice object
83  source->StartTracking(); //start the tracking
84  //Now the source generates outputs.
86 
88  //*************************************************************************
89  // Part II: Create a NavigationDataToNavigationDataFilter
90  //*************************************************************************
91 
92  //The next thing we do is using a NavigationDataToNavigationDataFilter. One of these filter is the
93  //very simple NavigationDataDisplacementFilter. This filter just changes the positions of the input
94  //NavigationData objects with an offset for each direction (X,Y,Z). The input of this filter is the
95  //source and the output of this filter is the "displaced" input.
96 
97  std::cout << "Generating DisplacementFilter ..." << std::endl;
98 
101  mitk::FillVector3D(offset, 10.0, 100.0, 1.0); //initialize the offset
102  displacer->SetOffset(offset); //now set the offset in the NavigationDataDisplacementFilter object
103 
104  //Connect the two filters. You can use the ConnectTo method to automatically connect all outputs from one filter
105  // to inputs from another filter.
106  displacer->ConnectTo(source.GetPointer());
107 
108  // Alternatively, you can manually connect inputs and outputs.
109  // The code below shows what the ConnectTo Methods does internally:
110  //
111  //for (unsigned int i = 0; i < source->GetNumberOfOutputs(); i++)
112  //{
113  // displacer->SetInput(i, source->GetOutput(i)); //here we connect to the displacement filter
114  //}
115 
118 
119  //*************************************************************************
120  // Part III: Record the data with the NavigationDataRecorder
121  //*************************************************************************
122 
123  //The next part of our pipeline is the recorder. The input of the recorder is the output of the displacement filter
124  //and the output is a XML file with the name "Test Output-0.xml", which is written with a NavigationDataSetWriter.
125 
126  std::cout << "Start Recording ..." << std::endl;
127 
128  //we need the stringstream for building up our filename
129  std::stringstream filename;
130 
131  //the .xml extension and an counter is NOT added automatically anymore -- that was the case in an earlier version
132  filename << itksys::SystemTools::GetCurrentWorkingDirectory() << "/Test Output-0.xml";
133 
134  std::cout << "Record to file: " << filename.str() << " ..." << std::endl;
135 
137 
138  //now the output of the displacer object is connected to the recorder object
139  recorder->ConnectTo(displacer);
140 
141  recorder->StartRecording(); //after finishing the settings you can start the recording mechanism
142  //now every update of the recorder stores one line into the file for
143  //each added NavigationData
144 
145  for (unsigned int x = 0; x < 100; x++) //write 100 datasets
146  {
147  recorder->Update(); //the update causes one line in the XML file for every tool
148  //in this case two lines
149  itksys::SystemTools::Delay(100); //sleep a little
150  }
151  recorder->StopRecording(); //to get proper XML files you should stop recording
152  //if your application crashes during recording no data
153  //will be lost it is all stored to disc
154 
155  //The IO-System needs a filename. Otherwise the output
156  //is redirected to the console. See MITK-Concepts page for more details on IO in MITK
157  mitk::IOUtil::SaveBaseData(recorder->GetNavigationDataSet(), filename.str());
158 
160 
162 
163  //*************************************************************************
164  // Part IV: Play the data with the NavigationDataSequentialPlayer
165  //*************************************************************************
166 
167  //The recording is finished now so now we can play the data. The NavigationDataPlayer is similar
168  //to the TrackingDevice source. It also derives from NavigationDataSource. So you can use a player
169  //instead of a TrackingDeviceSource. The input of this player is a NavigationDataSet, which we
170  //read with a NavigationDataReader.
171 
172  std::cout << "Start playing from file: " << filename.str() << " ..." << std::endl;
173 
175 
176  mitk::NavigationDataSet::Pointer naviDataSet = dynamic_cast<mitk::NavigationDataSet*> (mitk::IOUtil::LoadBaseData(filename.str()).GetPointer());
177  player->SetNavigationDataSet(naviDataSet);
178 
179  //From now on, the player provides NavigationDatas in a sequential order. The next position is given, as soon as "update" is called, so this player is not in real time.
180  //If you need the correct time of your tracking Data, use the NavigationDataPlayer instead and call "StartPlaying" and "StopPlaying".
181 
182  //this connects the outputs of the player to the NavigationData objects
183  mitk::NavigationData::Pointer nd = player->GetOutput();
184  mitk::NavigationData::Pointer nd2 = player->GetOutput(1);
185  for (unsigned int x = 0; x < 100; x++)
186  {
187  if (nd.IsNotNull()) //check if the output is not null
188  {
189  //With this call, we go to the next recorded data set.
190  player->GoToNextSnapshot();
191 
192  MITK_INFO << "Time Step " << x;
193  MITK_INFO << "Tool 1:" << nd->GetPosition();
194  MITK_INFO << "Tool 2:" << nd2->GetPosition();
195 
196  itksys::SystemTools::Delay(100); //sleep a little like in the recorder part, just for nice reading...
197  }
198  }
199 
200  itksys::SystemTools::Delay(2000);
201  std::cout << "finished" << std::endl;
202 
204 }
int main(int, char *[])
A small console tutorial about MITK-IGT.
itk::SmartPointer< Self > Pointer
#define MITK_INFO
Definition: mitkLogMacros.h:22
static mitk::BaseData::Pointer LoadBaseData(const std::string &path)
Create a BaseData object from the given file.
Definition: mitkIOUtil.cpp:576
void FillVector3D(Tout &out, mitk::ScalarType x, mitk::ScalarType y, mitk::ScalarType z)
Definition: mitkArray.h:110
static Vector3D offset
static bool SaveBaseData(mitk::BaseData *data, const std::string &path)
SaveBaseData Convenience method to save arbitrary baseData.
Definition: mitkIOUtil.cpp:888
static const std::string filename
Data structure which stores streams of mitk::NavigationData for multiple tools.