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
GibbsTracking.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 <mitkQBallImage.h>
19 #include <mitkTensorImage.h>
20 #include <mitkFiberBundle.h>
21 #include <itkGibbsTrackingFilter.h>
22 #include <itkDiffusionTensor3D.h>
24 #include <mitkImageToItk.h>
25 #include <mitkIOUtil.h>
26 #include "mitkCommandLineParser.h"
27 #include <boost/algorithm/string.hpp>
28 #include <itkFlipImageFilter.h>
29 #include <mitkCoreObjectFactory.h>
30 
31 template<int shOrder>
33 {
35  typedef mitk::ImageToItk< itk::Image< float, 4 > > CasterType;
37  caster->SetInput(mitkImg);
38  caster->Update();
39  itk::Image< float, 4 >::Pointer itkImage = caster->GetOutput();
40  typename FilterType::Pointer filter = FilterType::New();
41 
42  if (noFlip)
43  {
44  filter->SetInputImage(itkImage);
45  }
46  else
47  {
48  std::cout << "Flipping image";
49  itk::FixedArray<bool, 4> flipAxes;
50  flipAxes[0] = true;
51  flipAxes[1] = true;
52  flipAxes[2] = false;
53  flipAxes[3] = false;
54  itk::FlipImageFilter< itk::Image< float, 4 > >::Pointer flipper = itk::FlipImageFilter< itk::Image< float, 4 > >::New();
55  flipper->SetInput(itkImage);
56  flipper->SetFlipAxes(flipAxes);
57  flipper->Update();
58  itk::Image< float, 4 >::Pointer flipped = flipper->GetOutput();
59  itk::Matrix< double,4,4 > m = itkImage->GetDirection(); m[0][0] *= -1; m[1][1] *= -1;
60  flipped->SetDirection(m);
61 
62  itk::Point< float, 4 > o = itkImage->GetOrigin();
63  o[0] -= (flipped->GetLargestPossibleRegion().GetSize(0)-1);
64  o[1] -= (flipped->GetLargestPossibleRegion().GetSize(1)-1);
65  flipped->SetOrigin(o);
66  filter->SetInputImage(flipped);
67  }
68 
69  switch (toolkit)
70  {
71  case 0:
72  filter->SetToolkit(FilterType::FSL);
73  break;
74  case 1:
75  filter->SetToolkit(FilterType::MRTRIX);
76  break;
77  default:
78  filter->SetToolkit(FilterType::FSL);
79  }
80  filter->GenerateData();
81  return filter->GetQballImage();
82 }
83 
87 int main(int argc, char* argv[])
88 {
89  mitkCommandLineParser parser;
90 
91  parser.setTitle("Gibbs Tracking");
92  parser.setCategory("Fiber Tracking and Processing Methods");
93  parser.setDescription("Perform global fiber tractography (Gibbs tractography)");
94  parser.setContributor("MBI");
95 
96  parser.setArgumentPrefix("--", "-");
97  parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input:", "input image (tensor, Q-ball or FSL/MRTrix SH-coefficient image)", us::Any(), false);
98  parser.addArgument("parameters", "p", mitkCommandLineParser::InputFile, "Parameters:", "parameter file (.gtp)", us::Any(), false);
99  parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Mask:", "binary mask image");
100  parser.addArgument("shConvention", "s", mitkCommandLineParser::String, "SH coefficient:", "sh coefficient convention (FSL, MRtrix)", string("FSL"), true);
101  parser.addArgument("outFile", "o", mitkCommandLineParser::OutputFile, "Output:", "output fiber bundle (.fib)", us::Any(), false);
102  parser.addArgument("noFlip", "f", mitkCommandLineParser::Bool, "No flip:", "do not flip input image to match MITK coordinate convention");
103 
104  map<string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
105  if (parsedArgs.size()==0)
106  return EXIT_FAILURE;
107 
108  string inFileName = us::any_cast<string>(parsedArgs["input"]);
109  string paramFileName = us::any_cast<string>(parsedArgs["parameters"]);
110  string outFileName = us::any_cast<string>(parsedArgs["outFile"]);
111 
112  bool noFlip = false;
113  if (parsedArgs.count("noFlip"))
114  noFlip = us::any_cast<bool>(parsedArgs["noFlip"]);
115 
116  try
117  {
118  // instantiate gibbs tracker
119  typedef itk::Vector<float, QBALL_ODFSIZE> OdfVectorType;
120  typedef itk::Image<OdfVectorType,3> ItkQballImageType;
121  typedef itk::GibbsTrackingFilter<ItkQballImageType> GibbsTrackingFilterType;
123 
124  // load input image
125  mitk::Image::Pointer mitkImage = mitk::IOUtil::LoadImage(inFileName);
126 
127  // try to cast to qball image
128  if( boost::algorithm::ends_with(inFileName, ".qbi") )
129  {
130  std::cout << "Loading qball image ...";
131  mitk::QBallImage::Pointer mitkQballImage = dynamic_cast<mitk::QBallImage*>(mitkImage.GetPointer());
133  mitk::CastToItkImage(mitkQballImage, itk_qbi);
134  gibbsTracker->SetQBallImage(itk_qbi.GetPointer());
135  }
136  else if( boost::algorithm::ends_with(inFileName, ".dti") )
137  {
138  std::cout << "Loading tensor image ...";
139  typedef itk::Image< itk::DiffusionTensor3D<float>, 3 > ItkTensorImage;
140  mitk::TensorImage::Pointer mitkTensorImage = dynamic_cast<mitk::TensorImage*>(mitkImage.GetPointer());
142  mitk::CastToItkImage(mitkTensorImage, itk_dti);
143  gibbsTracker->SetTensorImage(itk_dti);
144  }
145  else if ( boost::algorithm::ends_with(inFileName, ".nii") )
146  {
147  std::cout << "Loading sh-coefficient image ...";
148  int nrCoeffs = mitkImage->GetLargestPossibleRegion().GetSize()[3];
149  int c=3, d=2-2*nrCoeffs;
150  double D = c*c-4*d;
151  int shOrder;
152  if (D>0)
153  {
154  shOrder = (-c+sqrt(D))/2.0;
155  if (shOrder<0)
156  shOrder = (-c-sqrt(D))/2.0;
157  }
158  else if (D==0)
159  shOrder = -c/2.0;
160 
161  std::cout << "using SH-order " << shOrder;
162 
163  int toolkitConvention = 0;
164 
165  if (parsedArgs.count("shConvention"))
166  {
167  string convention = us::any_cast<string>(parsedArgs["shConvention"]).c_str();
168 
169  if ( boost::algorithm::equals(convention, "MRtrix") )
170  {
171  toolkitConvention = 1;
172  std::cout << "Using MRtrix style sh-coefficient convention";
173  }
174  else
175  std::cout << "Using FSL style sh-coefficient convention";
176  }
177  else
178  std::cout << "Using FSL style sh-coefficient convention";
179 
180  switch (shOrder)
181  {
182  case 4:
183  gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<4>(mitkImage, toolkitConvention, noFlip));
184  break;
185  case 6:
186  gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<6>(mitkImage, toolkitConvention, noFlip));
187  break;
188  case 8:
189  gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<8>(mitkImage, toolkitConvention, noFlip));
190  break;
191  case 10:
192  gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<10>(mitkImage, toolkitConvention, noFlip));
193  break;
194  case 12:
195  gibbsTracker->SetQBallImage(TemplatedConvertShCoeffs<12>(mitkImage, toolkitConvention, noFlip));
196  break;
197  default:
198  std::cout << "SH-order " << shOrder << " not supported";
199  }
200  }
201  else
202  return EXIT_FAILURE;
203 
204  // global tracking
205  if (parsedArgs.count("mask"))
206  {
207  typedef itk::Image<float,3> MaskImgType;
208  mitk::Image::Pointer mitkMaskImage = mitk::IOUtil::LoadImage(us::any_cast<string>(parsedArgs["mask"]));
210  mitk::CastToItkImage(mitkMaskImage, itk_mask);
211  gibbsTracker->SetMaskImage(itk_mask);
212  }
213 
214  gibbsTracker->SetDuplicateImage(false);
215  gibbsTracker->SetLoadParameterFile( paramFileName );
216 // gibbsTracker->SetLutPath( "" );
217  gibbsTracker->Update();
218 
219  mitk::FiberBundle::Pointer mitkFiberBundle = mitk::FiberBundle::New(gibbsTracker->GetFiberBundle());
220  mitkFiberBundle->SetReferenceGeometry(mitkImage->GetGeometry());
221 
222  mitk::IOUtil::SaveBaseData(mitkFiberBundle.GetPointer(), outFileName );
223  }
224  catch (itk::ExceptionObject e)
225  {
226  std::cout << e;
227  return EXIT_FAILURE;
228  }
229  catch (std::exception e)
230  {
231  std::cout << e.what();
232  return EXIT_FAILURE;
233  }
234  catch (...)
235  {
236  std::cout << "ERROR!?!";
237  return EXIT_FAILURE;
238  }
239  return EXIT_SUCCESS;
240 }
itk::SmartPointer< Self > Pointer
Performes global fiber tractography on the input Q-Ball or tensor image (Gibbs tracking, Reisert 2010).
itk::ShCoefficientImageImporter< float, shOrder >::QballImageType::Pointer TemplatedConvertShCoeffs(mitk::Image *mitkImg, int toolkit, bool noFlip=false)
void setContributor(std::string contributor)
ValueType * any_cast(Any *operand)
Definition: usAny.h:377
std::map< std::string, us::Any > parseArguments(const StringContainerType &arguments, bool *ok=nullptr)
this class encapsulates qball images
static bool SaveBaseData(mitk::BaseData *data, const std::string &path)
SaveBaseData Convenience method to save arbitrary baseData.
Definition: mitkIOUtil.cpp:888
int main(int argc, char *argv[])
Perform global fiber tractography (Gibbs tractography)
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)
void setArgumentPrefix(const std::string &longPrefix, const std::string &shortPrefix)
bool equals(const mitk::ScalarType &val1, const mitk::ScalarType &val2, mitk::ScalarType epsilon=mitk::eps)
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
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.