]> Creatis software - clitk.git/blobdiff - tools/clitkInvertVFGenericFilter.txx
Invert VF from B-Spline coefficients
[clitk.git] / tools / clitkInvertVFGenericFilter.txx
index 0cf6cb4a154418ae8e98e33d3496b46def7ab00e..5cd12c4ce202129c38ac67d59d5629fa590b58e1 100644 (file)
@@ -3,7 +3,7 @@
 
   Authors belong to:
   - University of LYON              http://www.universite-lyon.fr/
-  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - Léon Bérard cancer center       http://www.centreleonberard.fr
   - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
 
   This software is distributed WITHOUT ANY WARRANTY; without even
 
   - BSD        See included LICENSE.txt file
   - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
-======================================================================-====*/
+===========================================================================**/
 #ifndef clitkInvertVFGenericFilter_txx
 #define clitkInvertVFGenericFilter_txx
 
+#include "itkVectorResampleImageFilter.h"
+#include "clitkBSplineDeformableTransform.h"
+#if ITK_VERSION_MAJOR >= 4
+#include "itkTransformToDisplacementFieldSource.h"
+#else
+#include "itkTransformToDeformationFieldSource.h"
+#endif
+
 /* =================================================
  * @file   clitkInvertVFGenericFilter.txx
  * @author
@@ -98,6 +106,65 @@ InvertVFGenericFilter<args_info_type>::UpdateWithDim(std::string PixelType)
   // }
 }
 
+//-------------------------------------------------------------------
+// Convert Coefficient image to DVF
+//-------------------------------------------------------------------
+template<class args_info_type>
+template<class DisplacementFieldType>
+typename DisplacementFieldType::Pointer
+InvertVFGenericFilter<args_info_type>::CoeffsToDVF(std::string fileName, std::string likeFileName)
+{
+  typedef clitk::BSplineDeformableTransform<double, DisplacementFieldType::ImageDimension, DisplacementFieldType::ImageDimension> TransformType;
+  typedef typename TransformType::CoefficientImageType CoefficientImageType;
+
+  typedef itk::ImageFileReader<CoefficientImageType> CoeffReaderType;
+  typename CoeffReaderType::Pointer reader = CoeffReaderType::New();
+  reader->SetFileName(fileName);
+  reader->Update();
+
+  typename TransformType::Pointer transform = TransformType::New();
+  transform->SetCoefficientImage(reader->GetOutput());
+  
+#if ITK_VERSION_MAJOR >= 4
+      typedef itk::TransformToDisplacementFieldSource<DisplacementFieldType, double> ConvertorType;
+#else
+      typedef itk::TransformToDeformationFieldSource<DisplacementFieldType, double> ConvertorType;
+#endif
+
+  typedef itk::ImageIOBase ImageIOType;
+  typename ImageIOType::Pointer imageIO = itk::ImageIOFactory::CreateImageIO(likeFileName.c_str(), itk::ImageIOFactory::ReadMode);
+  imageIO->SetFileName(likeFileName);
+  imageIO->ReadImageInformation();
+
+  typename ConvertorType::Pointer convertor= ConvertorType::New();
+  typename ConvertorType::SizeType output_size;
+  typename ConvertorType::SpacingType output_spacing;
+  typename ConvertorType::OriginType output_origin;
+  typename ConvertorType::DirectionType output_direction;
+  for (unsigned int i = 0; i < DisplacementFieldType::ImageDimension; i++) {
+    output_size[i] = imageIO->GetDimensions(i);
+    output_spacing[i] = imageIO->GetSpacing(i);
+    output_origin[i] = imageIO->GetOrigin(i);
+    for (unsigned int j = 0; j < DisplacementFieldType::ImageDimension; j++)
+      output_direction[i][j] = imageIO->GetDirection(i)[j];
+  }
+  
+  if (m_Verbose) {
+    std::cout << "Interpolating coefficients with grid:" << std::endl;
+    std::cout << output_size << output_spacing << std::endl;
+  }
+  
+  convertor->SetNumberOfThreads(1);
+  convertor->SetTransform(transform);
+  convertor->SetOutputOrigin(output_origin);
+  convertor->SetOutputSpacing(output_spacing);
+  convertor->SetOutputSize(output_size);
+  convertor->SetOutputDirection(output_direction);
+  convertor->Update();
+
+  return convertor->GetOutput();
+}
+
 
 //-------------------------------------------------------------------
 // Update with the number of dimensions and the pixeltype
@@ -117,7 +184,7 @@ InvertVFGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
   typename InputReaderType::Pointer reader = InputReaderType::New();
   reader->SetFileName( m_InputFileName);
   reader->Update();
-  typename InputImageType::Pointer input= reader->GetOutput();
+  typename InputImageType::Pointer input = reader->GetOutput();
 
   // Filter
   typename OutputImageType::Pointer output;
@@ -128,7 +195,30 @@ InvertVFGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
     // Create the InvertVFFilter
     typedef clitk::InvertVFFilter<InputImageType,OutputImageType> FilterType;
     typename FilterType::Pointer filter =FilterType::New();
-    filter->SetInput(input);
+    if (m_ArgsInfo.like_given) {
+      typename FilterType::SpacingType spacing;
+      typename FilterType::SizeType size;
+      itk::ImageIOBase::Pointer header = readImageHeader(m_ArgsInfo.like_arg);
+      for(unsigned int i=0; i<InputImageType::ImageDimension; i++) {
+        size[i] = header->GetDimensions(i);
+        spacing[i] = header->GetSpacing(i);
+      }
+
+      typedef itk::VectorResampleImageFilter<InputImageType, OutputImageType> ResampleFilterType;
+      typename ResampleFilterType::Pointer resampler = ResampleFilterType::New();
+      resampler->SetInput(input);
+      resampler->SetOutputOrigin(input->GetOrigin());
+      resampler->SetOutputDirection(input->GetDirection());
+      resampler->SetOutputSpacing(spacing);
+      resampler->SetSize(size);
+      resampler->Update();
+      spacing = resampler->GetOutput()->GetSpacing();
+      size = resampler->GetOutput()->GetLargestPossibleRegion().GetSize();
+      filter->SetInput(resampler->GetOutput());
+    }
+    else
+      filter->SetInput(input);
+
     filter->SetVerbose(m_Verbose);
     if (m_ArgsInfo.threads_given) filter->SetNumberOfThreads(m_ArgsInfo.threads_arg);
     if (m_ArgsInfo.pad_given) {
@@ -147,8 +237,37 @@ InvertVFGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
   }
 
   case 1: {
+    // Create the InvertVFFilter
+    typedef clitk::InvertVFFilter<InputImageType,OutputImageType> FilterType;
+    typename FilterType::Pointer filter =FilterType::New();
+    if (m_ArgsInfo.like_given) {
+      filter->SetInput(CoeffsToDVF<OutputImageType>(m_InputFileName, m_ArgsInfo.like_arg));
+    }
+
+    filter->SetVerbose(m_Verbose);
+    if (m_ArgsInfo.threads_given) filter->SetNumberOfThreads(m_ArgsInfo.threads_arg);
+    if (m_ArgsInfo.pad_given) {
+      PixelType pad;
+      if (m_ArgsInfo.pad_given !=  (pad.GetNumberOfComponents()) )
+        pad.Fill(m_ArgsInfo.pad_arg[0]);
+      else
+        for(unsigned int i=0; i<Dimension; i++)
+          pad[i]=m_ArgsInfo.pad_arg[i];
+    }
+    filter->SetThreadSafe(m_ArgsInfo.threadSafe_flag);
+    filter->Update();
+    output=filter->GetOutput();
+
+    break;
+  }
+
+  case 2: {
     // Create the InverseDeformationFieldFilter
+#if ITK_VERSION_MAJOR >= 4
+    typedef itk::InverseDisplacementFieldImageFilter<InputImageType,OutputImageType> FilterType;
+#else
     typedef itk::InverseDeformationFieldImageFilter<InputImageType,OutputImageType> FilterType;
+#endif
     typename FilterType::Pointer filter =FilterType::New();
     filter->SetInput(input);
     filter->SetOutputOrigin(input->GetOrigin());
@@ -161,6 +280,7 @@ InvertVFGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
     break;
   }
 
+    
   }
 
   // Output