Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
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.