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