Medical Imaging Interaction Toolkit  2016.11.0
Medical Imaging Interaction Toolkit
mitkDiffusionImageNiftiWriterService.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 #ifndef __mitkDiffusionImageNiftiWriterService__cpp
18 #define __mitkDiffusionImageNiftiWriterService__cpp
19 
21 #include "itkMetaDataDictionary.h"
22 #include "itkMetaDataObject.h"
23 #include "itkNiftiImageIO.h"
24 #include "itkImageFileWriter.h"
25 #include "itksys/SystemTools.hxx"
27 #include "mitkImageCast.h"
28 #include <mitkLocaleSwitch.h>
29 
30 #include <iostream>
31 #include <fstream>
32 
33 
35  : AbstractFileWriter(mitk::Image::GetStaticNameOfClass(), CustomMimeType( mitk::DiffusionCoreIOMimeTypes::DWI_NIFTI_MIMETYPE() ), mitk::DiffusionCoreIOMimeTypes::DWI_NIFTI_MIMETYPE_DESCRIPTION())
36 {
38 }
39 
41  : AbstractFileWriter(other)
42 {
43 }
44 
46 {}
47 
49 {
50  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image *>(this->GetInput());
51 
53  mitk::CastToItkImage(input,itkImg);
54 
55  if (input.IsNull())
56  {
57  MITK_ERROR <<"Sorry, input to DiffusionImageNiftiWriterService is NULL!";
58  return;
59  }
60  if ( this->GetOutputLocation().empty() )
61  {
62  MITK_ERROR << "Sorry, filename has not been set!";
63  return ;
64  }
65  mitk::LocaleSwitch localeSwitch("C");
66 
67  char keybuffer[512];
68  char valbuffer[512];
69 
70  //itk::MetaDataDictionary dic = input->GetImage()->GetMetaDataDictionary();
71 
72  vnl_matrix_fixed<double,3,3> measurementFrame = mitk::DiffusionPropertyHelper::GetMeasurementFrame(input);
73  if (measurementFrame(0,0) || measurementFrame(0,1) || measurementFrame(0,2) ||
74  measurementFrame(1,0) || measurementFrame(1,1) || measurementFrame(1,2) ||
75  measurementFrame(2,0) || measurementFrame(2,1) || measurementFrame(2,2))
76  {
77  sprintf( valbuffer, " (%lf,%lf,%lf) (%lf,%lf,%lf) (%lf,%lf,%lf)", measurementFrame(0,0), measurementFrame(0,1), measurementFrame(0,2), measurementFrame(1,0), measurementFrame(1,1), measurementFrame(1,2), measurementFrame(2,0), measurementFrame(2,1), measurementFrame(2,2));
78  itk::EncapsulateMetaData<std::string>(itkImg->GetMetaDataDictionary(),std::string("measurement frame"),std::string(valbuffer));
79  }
80 
81  sprintf( valbuffer, "DWMRI");
82  itk::EncapsulateMetaData<std::string>(itkImg->GetMetaDataDictionary(),std::string("modality"),std::string(valbuffer));
83 
85  {
86  sprintf( valbuffer, "%1f", mitk::DiffusionPropertyHelper::GetReferenceBValue(input) );
87  itk::EncapsulateMetaData<std::string>(itkImg->GetMetaDataDictionary(),std::string("DWMRI_b-value"),std::string(valbuffer));
88  }
89 
90  for(unsigned int i=0; i<mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size(); i++)
91  {
92  sprintf( keybuffer, "DWMRI_gradient_%04d", i );
93 
94  /*if(itk::ExposeMetaData<std::string>(input->GetMetaDataDictionary(),
95  std::string(keybuffer),tmp))
96  continue;*/
97 
98  sprintf( valbuffer, "%1f %1f %1f", mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).get(0),
100 
101  itk::EncapsulateMetaData<std::string>(itkImg->GetMetaDataDictionary(),std::string(keybuffer),std::string(valbuffer));
102  }
103 
104  typedef itk::VectorImage<short,3> ImageType;
105 
106  std::string ext = this->GetMimeType()->GetExtension(this->GetOutputLocation());
107  ext = itksys::SystemTools::LowerCase(ext);
108 
109  // default extension is .nii
110  if( ext == "")
111  {
112  ext = ".nii";
113  this->SetOutputLocation(this->GetOutputLocation() + ext);
114  }
115  if (ext == ".fsl" || ext == ".fslgz")
116  {
117  MITK_INFO << "Writing Nifti-Image for FSL";
118 
119  typedef itk::Image<short,4> ImageType4D;
121 
122  ImageType::SpacingType spacing = itkImg->GetSpacing();
123  ImageType4D::SpacingType spacing4;
124  for(int i=0; i<3; i++)
125  spacing4[i] = spacing[i];
126  spacing4[3] = 1;
127  img4->SetSpacing( spacing4 ); // Set the image spacing
128 
129  ImageType::PointType origin = itkImg->GetOrigin();
130  ImageType4D::PointType origin4;
131  for(int i=0; i<3; i++)
132  origin4[i] = origin[i];
133  origin4[3] = 0;
134  img4->SetOrigin( origin4 ); // Set the image origin
135 
136  ImageType::DirectionType direction = itkImg->GetDirection();
137  ImageType4D::DirectionType direction4;
138  for(int i=0; i<3; i++)
139  for(int j=0; j<3; j++)
140  direction4[i][j] = direction[i][j];
141  for(int i=0; i<4; i++)
142  direction4[i][3] = 0;
143  for(int i=0; i<4; i++)
144  direction4[3][i] = 0;
145  direction4[3][3] = 1;
146  img4->SetDirection( direction4 ); // Set the image direction
147 
148  ImageType::RegionType region = itkImg->GetLargestPossibleRegion();
149  ImageType4D::RegionType region4;
150 
151  ImageType::RegionType::SizeType size = region.GetSize();
152  ImageType4D::RegionType::SizeType size4;
153 
154  for(int i=0; i<3; i++)
155  size4[i] = size[i];
156  size4[3] = itkImg->GetVectorLength();
157 
158  ImageType::RegionType::IndexType index = region.GetIndex();
159  ImageType4D::RegionType::IndexType index4;
160  for(int i=0; i<3; i++)
161  index4[i] = index[i];
162  index4[3] = 0;
163 
164  region4.SetSize(size4);
165  region4.SetIndex(index4);
166  img4->SetRegions( region4 );
167 
168  img4->Allocate();
169 
170  itk::ImageRegionIterator<ImageType> it (itkImg, itkImg->GetLargestPossibleRegion() );
171  typedef ImageType::PixelType VecPixType;
172 
173  for (it.GoToBegin(); !it.IsAtEnd(); ++it)
174  {
175  VecPixType vec = it.Get();
176  ImageType::IndexType currentIndex = it.GetIndex();
177  for(unsigned int ind=0; ind<vec.Size(); ind++)
178  {
179 
180  for(int i=0; i<3; i++)
181  index4[i] = currentIndex[i];
182  index4[3] = ind;
183  img4->SetPixel(index4, vec[ind]);
184  }
185  }
186 
187  // create copy of file with correct ending for mitk
188  std::string fname3 = this->GetOutputLocation();
189  std::string::iterator itend = fname3.end();
190  if (ext == ".fsl")
191  fname3.replace( itend-3, itend, "nii");
192  else
193  fname3.replace( itend-5, itend, "nii.gz");
194 
196 
197  typedef itk::ImageFileWriter<ImageType4D> WriterType4;
198  WriterType4::Pointer nrrdWriter4 = WriterType4::New();
199  nrrdWriter4->UseInputMetaDataDictionaryOn();
200  nrrdWriter4->SetInput( img4 );
201  nrrdWriter4->SetFileName(fname3);
202  nrrdWriter4->UseCompressionOn();
203  nrrdWriter4->SetImageIO(io4);
204  try
205  {
206  nrrdWriter4->Update();
207  }
208  catch (itk::ExceptionObject e)
209  {
210  std::cout << e << std::endl;
211  throw;
212  }
213 
214  itksys::SystemTools::CopyAFile(fname3.c_str(), this->GetOutputLocation().c_str());
215 
217  {
218  std::ofstream myfile;
219  std::string fname = this->GetOutputLocation();
220  fname += ".bvals";
221  myfile.open (fname.c_str());
222  for(unsigned int i=0; i<mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size(); i++)
223  {
224  double twonorm = mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).two_norm();
225  myfile << mitk::DiffusionPropertyHelper::GetReferenceBValue(input)*twonorm*twonorm << " ";
226  }
227  myfile.close();
228 
229  std::ofstream myfile2;
230  std::string fname2 = this->GetOutputLocation();
231  fname2 += ".bvecs";
232  myfile2.open (fname2.c_str());
233  for(int j=0; j<3; j++)
234  {
235  for(unsigned int i=0; i<mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size(); i++)
236  {
237  //need to modify the length
239  GradientDirectionType direction = grads->ElementAt(i);
240  direction.normalize();
241  myfile2 << direction.get(j) << " ";
242  //myfile2 << input->GetDirections()->ElementAt(i).get(j) << " ";
243  }
244  myfile2 << std::endl;
245  }
246 
247  std::ofstream myfile3;
248  std::string fname4 = this->GetOutputLocation();
249  fname4 += ".ttk";
250  myfile3.open (fname4.c_str());
251  for(unsigned int i=0; i<mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size(); i++)
252  {
253  for(int j=0; j<3; j++)
254  {
255  myfile3 << mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).get(j) << " ";
256  }
257  myfile3 << std::endl;
258  }
259  }
260  }
261  else if (ext == ".nii" || ext == ".nii.gz")
262  {
263  MITK_INFO << "Writing Nifti-Image";
264 
265  typedef itk::Image<short,4> ImageType4D;
267 
268  ImageType::SpacingType spacing = itkImg->GetSpacing();
269  ImageType4D::SpacingType spacing4;
270  for(int i=0; i<3; i++)
271  spacing4[i] = spacing[i];
272  spacing4[3] = 1;
273  img4->SetSpacing( spacing4 ); // Set the image spacing
274 
275  ImageType::PointType origin = itkImg->GetOrigin();
276  ImageType4D::PointType origin4;
277  for(int i=0; i<3; i++)
278  origin4[i] = origin[i];
279  origin4[3] = 0;
280  img4->SetOrigin( origin4 ); // Set the image origin
281 
282  ImageType::DirectionType direction = itkImg->GetDirection();
283  ImageType4D::DirectionType direction4;
284  for(int i=0; i<3; i++)
285  for(int j=0; j<3; j++)
286  direction4[i][j] = direction[i][j];
287  for(int i=0; i<4; i++)
288  direction4[i][3] = 0;
289  for(int i=0; i<4; i++)
290  direction4[3][i] = 0;
291  direction4[3][3] = 1;
292  img4->SetDirection( direction4 ); // Set the image direction
293 
294  ImageType::RegionType region = itkImg->GetLargestPossibleRegion();
295  ImageType4D::RegionType region4;
296 
297  ImageType::RegionType::SizeType size = region.GetSize();
298  ImageType4D::RegionType::SizeType size4;
299 
300  for(int i=0; i<3; i++)
301  size4[i] = size[i];
302  size4[3] = itkImg->GetVectorLength();
303 
304  ImageType::RegionType::IndexType index = region.GetIndex();
305  ImageType4D::RegionType::IndexType index4;
306  for(int i=0; i<3; i++)
307  index4[i] = index[i];
308  index4[3] = 0;
309 
310  region4.SetSize(size4);
311  region4.SetIndex(index4);
312  img4->SetRegions( region4 );
313 
314  img4->Allocate();
315 
316  itk::ImageRegionIterator<ImageType> it (itkImg, itkImg->GetLargestPossibleRegion() );
317  typedef ImageType::PixelType VecPixType;
318 
319  for (it.GoToBegin(); !it.IsAtEnd(); ++it)
320  {
321  VecPixType vec = it.Get();
322  ImageType::IndexType currentIndex = it.GetIndex();
323  for(unsigned int ind=0; ind<vec.Size(); ind++)
324  {
325 
326  for(int i=0; i<3; i++)
327  index4[i] = currentIndex[i];
328  index4[3] = ind;
329  img4->SetPixel(index4, vec[ind]);
330  }
331  }
332 
334 
335  typedef itk::ImageFileWriter<ImageType4D> WriterType4;
336  WriterType4::Pointer nrrdWriter4 = WriterType4::New();
337  nrrdWriter4->UseInputMetaDataDictionaryOn();
338  nrrdWriter4->SetInput( img4 );
339  nrrdWriter4->SetFileName(this->GetOutputLocation());
340  nrrdWriter4->UseCompressionOn();
341  nrrdWriter4->SetImageIO(io4);
342  try
343  {
344  nrrdWriter4->Update();
345  }
346  catch (itk::ExceptionObject e)
347  {
348  std::cout << e << std::endl;
349  throw;
350  }
351 
352 
354  {
355  std::ofstream myfile;
356  std::string fname = itksys::SystemTools::GetFilenamePath( this->GetOutputLocation() ) + "/"
357  + this->GetMimeType()->GetFilenameWithoutExtension( this->GetOutputLocation() );
358  fname += ".bvals";
359  myfile.open (fname.c_str());
360  for(unsigned int i=0; i<mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size(); i++)
361  {
362  double twonorm = mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).two_norm();
363  myfile << mitk::DiffusionPropertyHelper::GetReferenceBValue(input)*twonorm*twonorm << " ";
364  }
365  myfile.close();
366 
367  std::ofstream myfile2;
368  std::string fname2 = itksys::SystemTools::GetFilenamePath( this->GetOutputLocation() ) + "/"
369  + this->GetMimeType()->GetFilenameWithoutExtension( this->GetOutputLocation() );
370  fname2 += ".bvecs";
371  myfile2.open (fname2.c_str());
372  for(int j=0; j<3; j++)
373  {
374  for(unsigned int i=0; i<mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size(); i++)
375  {
376  //need to modify the length
378  GradientDirectionType direction = grads->ElementAt(i);
379  direction.normalize();
380  myfile2 << direction.get(j) << " ";
381  //myfile2 << input->GetDirections()->ElementAt(i).get(j) << " ";
382  }
383  myfile2 << std::endl;
384  }
385 
386  std::ofstream myfile3;
387  std::string fname4 = itksys::SystemTools::GetFilenamePath( this->GetOutputLocation() ) + "/"
388  + this->GetMimeType()->GetFilenameWithoutExtension( this->GetOutputLocation() );
389  fname4 += ".ttk";
390  myfile3.open (fname4.c_str());
391  for(unsigned int i=0; i<mitk::DiffusionPropertyHelper::GetGradientContainer(input)->Size(); i++)
392  {
393  for(int j=0; j<3; j++)
394  {
395  myfile3 << mitk::DiffusionPropertyHelper::GetGradientContainer(input)->ElementAt(i).get(j) << " ";
396  }
397  myfile3 << std::endl;
398  }
399  }
400  }
401 }
402 
404 {
405  return new DiffusionImageNiftiWriterService(*this);
406 }
407 
409 {
410  mitk::Image::ConstPointer input = dynamic_cast<const mitk::Image*>(this->GetInput());
411  if (input.IsNull() || !mitk::DiffusionPropertyHelper::IsDiffusionWeightedImage( input ) )
412  {
413  return Unsupported;
414  }
415  else
416  {
417  return Supported;
418  }
419 }
420 
421 #endif //__mitkDiffusionImageNiftiWriterService__cpp
const MeasurementFrameType & GetMeasurementFrame() const
mitk::Point3D PointType
itk::SmartPointer< Self > Pointer
virtual void Write() override
Write the base data to the specified location or output stream.
mitk::DiffusionPropertyHelper::GradientDirectionType GradientDirectionType
#define MITK_INFO
Definition: mitkLogMacros.h:22
#define MITK_ERROR
Definition: mitkLogMacros.h:24
virtual ConfidenceLevel GetConfidenceLevel() const override
The confidence level of the reader or writer implementation.
DataCollection - Class to facilitate loading/accessing structured data.
The CustomMimeType class represents a custom mime-type which may be registered as a service object...
map::core::discrete::Elements< 3 >::InternalImageType ImageType
Convenience class to temporarily change the current locale.
virtual mitk::DiffusionImageNiftiWriterService * Clone() const override
Image class for storing images.
Definition: mitkImage.h:76
static const char * GetStaticNameOfClass()
void MITKCORE_EXPORT CastToItkImage(const mitk::Image *mitkImage, itk::SmartPointer< ItkOutputImageType > &itkOutputImage)
Cast an mitk::Image to an itk::Image with a specific type.
us::ServiceRegistration< IFileWriter > RegisterService(us::ModuleContext *context=us::GetModuleContext())
GradientDirectionsContainerType::Pointer GetGradientContainer() const
unsigned short PixelType
ConfidenceLevel
A confidence level describing the confidence of the reader or writer in handling the given data...
Definition: mitkIFileIO.h:49
Base class for writing mitk::BaseData objects to files or streams.
static itkEventMacro(BoundingShapeInteractionEvent, itk::AnyEvent) class MITKBOUNDINGSHAPE_EXPORT BoundingShapeInteractor Pointer New()
Basic interaction methods for mitk::GeometryData.