Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
StreamlineTracking.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 
17 #include <mitkImageCast.h>
18 #include <mitkTensorImage.h>
19 #include <mitkIOUtil.h>
20 #include <mitkFiberBundle.h>
22 #include <itkDiffusionTensor3D.h>
23 #include "mitkCommandLineParser.h"
24 #include <mitkCoreObjectFactory.h>
25 
26 using namespace std;
27 
31 int main(int argc, char* argv[])
32 {
33  mitkCommandLineParser parser;
34  parser.setArgumentPrefix("--", "-");
35  parser.addArgument("input", "i", mitkCommandLineParser::StringList, "Input images", "input tensor images (.dti)", us::Any(), false);
36  parser.addArgument("seed", "si", mitkCommandLineParser::InputFile, "Seed image", "binary seed image", us::Any(), true);
37  parser.addArgument("mask", "mi", mitkCommandLineParser::InputFile, "Mask", "binary mask image", us::Any(), true);
38  parser.addArgument("faImage", "fai", mitkCommandLineParser::InputFile, "FA image", "FA image", us::Any(), true);
39  parser.addArgument("minFA", "fa", mitkCommandLineParser::Float, "Min. FA threshold", "minimum fractional anisotropy threshold", 0.15, true);
40  parser.addArgument("minCurv", "c", mitkCommandLineParser::Float, "Min. curvature radius", "minimum curvature radius in mm (default = 0.5*minimum-spacing)");
41  parser.addArgument("stepSize", "s", mitkCommandLineParser::Float, "Step size", "step size in mm (default = 0.1*minimum-spacing)");
42  parser.addArgument("tendf", "f", mitkCommandLineParser::Float, "Weight f", "Weighting factor between first eigenvector (f=1 equals FACT tracking) and input vector dependent direction (f=0).", 1.0, true);
43  parser.addArgument("tendg", "g", mitkCommandLineParser::Float, "Weight g", "Weighting factor between input vector (g=0) and tensor deflection (g=1 equals TEND tracking)", 0.0, true);
44  parser.addArgument("numSeeds", "n", mitkCommandLineParser::Int, "Seeds per voxel", "Number of seeds per voxel.", 1, true);
45  parser.addArgument("minLength", "l", mitkCommandLineParser::Float, "Min. fiber length", "minimum fiber length in mm", 20, true);
46 
47  parser.addArgument("interpolate", "ip", mitkCommandLineParser::Bool, "Interpolate", "Use linear interpolation", false, true);
48  parser.addArgument("outFile", "o", mitkCommandLineParser::String, "Output file", "output fiber bundle (.fib)", us::Any(), false);
49 
50  parser.setCategory("Fiber Tracking and Processing Methods");
51  parser.setTitle("Streamline Tracking");
52  parser.setDescription("Deterministic tensor-based streamline tractography or TEND tractography (multi tensor possible)");
53  parser.setContributor("MBI");
54 
55  map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
56  if (parsedArgs.size()==0)
57  return EXIT_FAILURE;
58 
60  string dtiFileName;
61  string outFileName = us::any_cast<string>(parsedArgs["outFile"]);
62 
63  float minFA = 0.15;
64  float minCurv = -1;
65  float stepSize = -1;
66  float tendf = 1;
67  float tendg = 0;
68  float minLength = 20;
69  int numSeeds = 1;
70  bool interpolate = false;
71 
72  if (parsedArgs.count("minCurv"))
73  minCurv = us::any_cast<float>(parsedArgs["minCurv"]);
74  if (parsedArgs.count("minFA"))
75  minFA = us::any_cast<float>(parsedArgs["minFA"]);
76  if (parsedArgs.count("stepSize"))
77  stepSize = us::any_cast<float>(parsedArgs["stepSize"]);
78  if (parsedArgs.count("tendf"))
79  tendf = us::any_cast<float>(parsedArgs["tendf"]);
80  if (parsedArgs.count("tendg"))
81  tendg = us::any_cast<float>(parsedArgs["tendg"]);
82  if (parsedArgs.count("minLength"))
83  minLength = us::any_cast<float>(parsedArgs["minLength"]);
84  if (parsedArgs.count("numSeeds"))
85  numSeeds = us::any_cast<int>(parsedArgs["numSeeds"]);
86 
87 
88  if (parsedArgs.count("interpolate"))
89  interpolate = us::any_cast<bool>(parsedArgs["interpolate"]);
90 
91 
92 
93  try
94  {
95  typedef itk::StreamlineTrackingFilter< float > FilterType;
97 
98  mitk::Image::Pointer mitkImage = NULL;
99 
100  std::cout << "Loading tensor images ...";
101  typedef itk::Image< itk::DiffusionTensor3D<float>, 3 > ItkTensorImage;
102  dtiFileName = inputImages.at(0);
103  for (unsigned int i=0; i<inputImages.size(); i++)
104  {
105  try
106  {
107  mitkImage = dynamic_cast<mitk::Image*>(mitk::IOUtil::LoadDataNode(inputImages.at(i))->GetData());
108  mitk::TensorImage::Pointer img = dynamic_cast<mitk::TensorImage*>(mitk::IOUtil::LoadDataNode(inputImages.at(i))->GetData());
110  mitk::CastToItkImage(img, itk_dti);
111  filter->SetInput(i, itk_dti);
112  }
113  catch(...){ std::cout << "could not load: " << inputImages.at(i); }
114  }
115 
116  std::cout << "Loading seed image ...";
117  typedef itk::Image< unsigned char, 3 > ItkUCharImageType;
118  mitk::Image::Pointer mitkSeedImage = NULL;
119  if (parsedArgs.count("seed"))
120  mitkSeedImage = mitk::IOUtil::LoadImage(us::any_cast<string>(parsedArgs["seed"]));
121 
122  std::cout << "Loading mask image ...";
123  mitk::Image::Pointer mitkMaskImage = NULL;
124  if (parsedArgs.count("mask"))
125  mitkMaskImage = mitk::IOUtil::LoadImage(us::any_cast<string>(parsedArgs["mask"]));
126 
127  // instantiate tracker
128  filter->SetSeedsPerVoxel(numSeeds);
129  filter->SetFaThreshold(minFA);
130  filter->SetMinCurvatureRadius(minCurv);
131  filter->SetStepSize(stepSize);
132  filter->SetF(tendf);
133  filter->SetG(tendg);
134  filter->SetInterpolate(interpolate);
135  filter->SetMinTractLength(minLength);
136 
137  if (mitkSeedImage.IsNotNull())
138  {
140  mitk::CastToItkImage(mitkSeedImage, mask);
141  filter->SetSeedImage(mask);
142  }
143 
144  if (mitkMaskImage.IsNotNull())
145  {
147  mitk::CastToItkImage(mitkMaskImage, mask);
148  filter->SetMaskImage(mask);
149  }
150 
151  filter->Update();
152 
153  vtkSmartPointer<vtkPolyData> fiberBundle = filter->GetFiberPolyData();
154  if ( fiberBundle->GetNumberOfLines()==0 )
155  {
156  std::cout << "No fibers reconstructed. Check parametrization.";
157  return EXIT_FAILURE;
158  }
160  fib->SetReferenceGeometry(mitkImage->GetGeometry());
161 
162  mitk::IOUtil::SaveBaseData(fib.GetPointer(), outFileName );
163 
164  }
165  catch (itk::ExceptionObject e)
166  {
167  std::cout << e;
168  return EXIT_FAILURE;
169  }
170  catch (std::exception e)
171  {
172  std::cout << e.what();
173  return EXIT_FAILURE;
174  }
175  catch (...)
176  {
177  std::cout << "ERROR!?!";
178  return EXIT_FAILURE;
179  }
180  return EXIT_SUCCESS;
181 }
itk::SmartPointer< Self > Pointer
Performes deterministic streamline tracking on the input tensor image.
int main(int argc, char *argv[])
Deterministic tensor-based streamline tractography or TEND tractography (multi tensor possible) ...
void setContributor(std::string contributor)
STL namespace.
ValueType * any_cast(Any *operand)
Definition: usAny.h:377
std::map< std::string, us::Any > parseArguments(const StringContainerType &arguments, bool *ok=nullptr)
T::Pointer GetData(const std::string &name)
static bool SaveBaseData(mitk::BaseData *data, const std::string &path)
SaveBaseData Convenience method to save arbitrary baseData.
Definition: mitkIOUtil.cpp:888
void addArgument(const std::string &longarg, const std::string &shortarg, Type type, const std::string &argLabel, const std::string &argHelp=std::string(), const us::Any &defaultValue=us::Any(), bool optional=true, bool ignoreRest=false, bool deprecated=false)
Image class for storing images.
Definition: mitkImage.h:76
Definition: usAny.h:163
void setCategory(std::string category)
static mitk::DataNode::Pointer LoadDataNode(const std::string &path)
LoadDataNode Method to load an arbitrary DataNode.
Definition: mitkIOUtil.cpp:586
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
this class encapsulates tensor images
std::vector< std::string > StringContainerType
itk::Image< itk::DiffusionTensor3D< float >, 3 > ItkTensorImage
void setTitle(std::string title)
void setDescription(std::string description)
static mitk::Image::Pointer LoadImage(const std::string &path)
LoadImage Convenience method to load an arbitrary mitkImage.
Definition: mitkIOUtil.cpp:597
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.