Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
DiffusionIVIMFit.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 "mitkCommandLineParser.h"
18 #include <mitkIOUtil.h>
20 
21 #include <mitkImageCaster.h>
23 
24 //vnl_includes
25 #include "vnl/vnl_math.h"
26 #include "vnl/vnl_cost_function.h"
27 #include "vnl/vnl_least_squares_function.h"
28 #include "vnl/algo/vnl_lbfgsb.h"
29 #include "vnl/algo/vnl_lbfgs.h"
30 
31 #include "vnl/algo/vnl_levenberg_marquardt.h"
32 
34 
35 #include <itkGaussianBlurImageFunction.h>
36 #include <itkUnaryFunctorImageFilter.h>
37 
38 #include <itkImageFileWriter.h>
39 
40 #include <itkVectorIndexSelectionCastImageFilter.h>
41 #include <itkComposeImageFilter.h>
42 #include <itkDiscreteGaussianImageFilter.h>
43 
45 {
46  typedef itk::DiscreteGaussianImageFilter< itk::Image<DPH::DiffusionPixelType, 3 >, itk::Image<DPH::DiffusionPixelType, 3 > > GaussianFilterType;
47 
48  typedef itk::VectorIndexSelectionCastImageFilter< DPH::ImageType, itk::Image<DPH::DiffusionPixelType, 3 > > IndexSelectionType;
50  indexSelectionFilter->SetInput( vectorImage );
51 
52  typedef itk::ComposeImageFilter< itk::Image<DPH::DiffusionPixelType, 3>, DPH::ImageType > ComposeFilterType;
54 
55  for( unsigned int i=0; i<vectorImage->GetVectorLength(); ++i)
56  {
58 
59  indexSelectionFilter->SetIndex( i );
60 
61  gaussian_filter->SetInput( indexSelectionFilter->GetOutput() );
62  gaussian_filter->SetVariance( sigma );
63 
64  vec_composer->SetInput(i, gaussian_filter->GetOutput() );
65 
66  gaussian_filter->Update();
67  }
68 
69  try
70  {
71  vec_composer->Update();
72  }
73  catch(const itk::ExceptionObject &e)
74  {
75  mitkThrow() << "[VectorImage.GaussianSmoothing] !! Failed with ITK Exception: " << e.what();
76  }
77 
78  DPH::ImageType::Pointer smoothed_vector = vec_composer->GetOutput();
79 /*
80  itk::ImageFileWriter< DPH::ImageType >::Pointer writer =
81  itk::ImageFileWriter< DPH::ImageType >::New();
82 
83  writer->SetInput( smoothed_vector );
84  writer->SetFileName( "/tmp/itk_smoothed_vector.nrrd");
85  writer->Update();*/
86 
87  return smoothed_vector;
88 
89 
90 }
91 
92 void KurtosisMapComputation( mitk::Image::Pointer input, std::string output_prefix )
93 {
95  mitk::CastToItkImage( input, vectorImage );
96 
97 
98 
101 
102  kurtosis_filter->SetInput( GetBlurredVectorImage( vectorImage, 1.5 ) );
103  kurtosis_filter->SetReferenceBValue( DPH::GetReferenceBValue( input.GetPointer() ) );
104  kurtosis_filter->SetGradientDirections( DPH::GetGradientContainer( input.GetPointer() ) );
105  kurtosis_filter->SetNumberOfThreads(1);
106 
107  KurtosisFilterType::OutputImageRegionType o_region;
108  KurtosisFilterType::OutputImageRegionType::SizeType o_size;
109  KurtosisFilterType::OutputImageRegionType::IndexType o_index;
110 
111  o_index.Fill(0); o_size.Fill(0);
112  o_index[0] = 48; o_index[1] = 18; o_index[2] = 12;
113  o_size[0] = 16; o_size[1] = 24; o_size[2] = 1;
114 
115  o_region.SetSize( o_size );
116  o_region.SetIndex( o_index );
117  kurtosis_filter->SetMapOutputRegion( o_region );
118 
119  try
120  {
121  kurtosis_filter->Update();
122  }
123  catch( const itk::ExceptionObject& e)
124  {
125  mitkThrow() << "Kurtosis fit failed with an ITK Exception: " << e.what();
126  }
127 
129  d_image->InitializeByItk( kurtosis_filter->GetOutput(0) );
130  d_image->SetVolume( kurtosis_filter->GetOutput(0)->GetBufferPointer() );
131 
133  k_image->InitializeByItk( kurtosis_filter->GetOutput(1) );
134  k_image->SetVolume( kurtosis_filter->GetOutput(1)->GetBufferPointer() );
135 
136  std::string outputD_FileName = output_prefix + "_ADC_map.nrrd";
137  std::string outputK_FileName = output_prefix + "_AKC_map.nrrd";
138 
139  try
140  {
141  mitk::IOUtil::Save( d_image, outputD_FileName );
142  mitk::IOUtil::Save( k_image, outputK_FileName );
143  }
144  catch( const itk::ExceptionObject& e)
145  {
146  mitkThrow() << "Failed to save the KurtosisFit Results due to exception: " << e.what();
147  }
148 
149 }
150 
151 int main( int argc, char* argv[] )
152 {
153 
154 
155  mitkCommandLineParser parser;
156 
157  parser.setTitle("Diffusion IVIM (Kurtosis) Fit");
158  parser.setCategory("Signal Reconstruction");
159  parser.setContributor("MIC");
160  parser.setDescription("Fitting of IVIM / Kurtosis");
161 
162  parser.setArgumentPrefix("--","-");
163  // mandatory arguments
164  parser.addArgument("input", "i", mitkCommandLineParser::InputFile, "Input: ", "input image (DWI)", us::Any(), false);
165  parser.addArgument("output", "o", mitkCommandLineParser::String, "Output Preifx: ", "Prefix for the output images, will append _f, _K, _D accordingly ", us::Any(), false);
166  parser.addArgument("fit", "f", mitkCommandLineParser::String, "Input: ", "input image (DWI)", us::Any(), false);
167 
168  // optional arguments
169  parser.addArgument("mask", "m", mitkCommandLineParser::InputFile, "Masking Image: ", "ROI (segmentation)", us::Any(), true);
170 
171 
172  std::map<std::string, us::Any> parsedArgs = parser.parseArguments(argc, argv);
173  if (parsedArgs.size()==0)
174  return EXIT_FAILURE;
175 
176  // mandatory arguments
177  std::string inFileName = us::any_cast<std::string>(parsedArgs["input"]);
178  std::string out_prefix = us::any_cast<std::string>(parsedArgs["output"]);
179  std::string fit_name = us::any_cast<std::string>(parsedArgs["fit"]);
180 
181  mitk::Image::Pointer inputImage = mitk::IOUtil::LoadImage(inFileName);
182  if( !DPH::IsDiffusionWeightedImage( inputImage ) )
183  {
184  MITK_ERROR("DiffusionIVIMFit.Input") << "No valid diffusion-weighted image provided, failed to load " << inFileName << " as DW Image. Aborting...";
185  return EXIT_FAILURE;
186  }
187 
188  if( fit_name == "Kurtosis" )
189  {
190  MITK_INFO("DiffusionIVIMFit.Main") << "-----[ Kurtosis Fit ]-----";
191 
192  KurtosisMapComputation( inputImage, out_prefix );
193 
194  }
195  else if (fit_name == "IVIM" )
196  {
197  MITK_INFO("DiffusionIVIMFit.Main") << "IVIM Fit not fully implemented yet. Aborting...";
198  return EXIT_FAILURE;
199  }
200  else
201  {
202  MITK_ERROR("DiffusionIVIMFit.Main") << "Unrecognized option: " << fit_name << ". Valid values [\"IVIM\", \"Kurtosis\"] \n Aborting... \n";
203  return EXIT_FAILURE;
204 
205  }
206 
207 }
static void Save(const mitk::BaseData *data, const std::string &path)
Save a mitk::BaseData instance.
Definition: mitkIOUtil.cpp:824
itk::SmartPointer< Self > Pointer
#define MITK_INFO
Definition: mitkLogMacros.h:22
DPH::ImageType::Pointer GetBlurredVectorImage(DPH::ImageType::Pointer vectorImage, double sigma)
#define MITK_ERROR
Definition: mitkLogMacros.h:24
void setContributor(std::string contributor)
Helper class for mitk::Images containing diffusion weighted data.
ValueType * any_cast(Any *operand)
Definition: usAny.h:377
void KurtosisMapComputation(mitk::Image::Pointer input, std::string output_prefix)
std::map< std::string, us::Any > parseArguments(const StringContainerType &arguments, bool *ok=nullptr)
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)
#define mitkThrow()
mitk::DiffusionPropertyHelper DPH
Definition: usAny.h:163
void setCategory(std::string category)
static Pointer New()
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.
GradientDirectionsContainerType::Pointer GetGradientContainer() const
This filter provides the fit of the kurtosis (non-IVIM) signal to the data.
void setTitle(std::string title)
void setDescription(std::string description)
int main(int argc, char *argv[])
static mitk::Image::Pointer LoadImage(const std::string &path)
LoadImage Convenience method to load an arbitrary mitkImage.
Definition: mitkIOUtil.cpp:597
itk::VectorImage< DiffusionPixelType, 3 > ImageType
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.