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
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.