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