]> Creatis software - clitk.git/commitdiff
- new resample image (itk style)
authordsarrut <dsarrut>
Mon, 3 May 2010 06:53:49 +0000 (06:53 +0000)
committerdsarrut <dsarrut>
Mon, 3 May 2010 06:53:49 +0000 (06:53 +0000)
filters/CMakeLists.txt
filters/clitkResampleImage.ggo [new file with mode: 0644]
filters/clitkResampleImageGenericFilter.h [new file with mode: 0644]
filters/clitkResampleImageGenericFilter.txx [new file with mode: 0644]
itk/clitkResampleImageWithOptionsFilter.h [new file with mode: 0644]
itk/clitkResampleImageWithOptionsFilter.txx [new file with mode: 0644]
tools/CMakeLists.txt
tools/clitkResampleImage.cxx [new file with mode: 0644]

index 12d0cc50420c119d0f562d5d0068b30eb2e92ede..0ad1caac63bf917c2a8d4923b071e3894354d699 100644 (file)
@@ -10,6 +10,7 @@ WRAP_GGO(clitkFilters_GGO_C
   clitkFooImage.ggo
   clitkImageArithm.ggo
   clitkMedianImageFilter.ggo
+  clitkResampleImage.ggo
 )
 
 SET(clitkFilters_SRC
diff --git a/filters/clitkResampleImage.ggo b/filters/clitkResampleImage.ggo
new file mode 100644 (file)
index 0000000..e681ed6
--- /dev/null
@@ -0,0 +1,27 @@
+#File clitkImageResample.ggo
+package "clitkImageResample"
+version "2.0"
+purpose "Resample an image. You can specify the interpolation, you can apply a Gaussian filter before (automated if downsample)."
+
+section "Common"
+option "config"                -       "Config file"                        string     no
+option "verbose"       v       "Verbose"                            flag       off
+option "imagetypes"    -       "Verbose: allowed image types"       flag       off
+option "thread"        -       "Nb of thread to use (default=max)"  int        no
+
+section "Input & Output options"
+option "input"         i       "Input image filename"                  string  yes
+option "output"        o       "Output image filename"                 string  yes
+option "size"          -       "Number of pixels of each coordonate"   int     no      multiple  default="0"
+option "spacing"       -       "Spacing in mm between pixels"          float   no      multiple  default="-1.0"
+option "default"       d       "Default pixel value"                   float   no      default = "0.0"
+option "time"           t       "Last Dimension Is Time -> do not resample it (auto on for 4D)" flag    off
+
+section "Interpolation"
+option "interp"                -       "Interpolation type: {nn, linear, bspline, blut}"  string  no default="nn"
+option "order"         b       "BSpline ordre (range 0-5)"                        int     no default="3"
+option "sampling"      s       "BLUT sampling value"                              int     no default="30"
+
+section "Gaussian filtering"
+option "gauss"         g       "Apply Gaussian before (sigma in mm)"             float  no     multiple  default="0.0"
+option "autogauss"     a       "Apply Gaussian with auto sigma when downsample"  flag   off    
diff --git a/filters/clitkResampleImageGenericFilter.h b/filters/clitkResampleImageGenericFilter.h
new file mode 100644 (file)
index 0000000..34cd791
--- /dev/null
@@ -0,0 +1,67 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+
+#ifndef CLITKIRESAMPLEIMAGEGENERICFILTER_H
+#define CLITKIRESAMPLEIMAGEGENERICFILTER_H
+
+// clitk include
+#include "clitkImageToImageGenericFilter.h"
+
+namespace clitk {
+  
+  //--------------------------------------------------------------------
+  template<class args_info_type>
+  class ITK_EXPORT ResampleImageGenericFilter: 
+    public ImageToImageGenericFilter<ResampleImageGenericFilter<args_info_type> > {
+    
+  public: 
+    // Constructor
+    ResampleImageGenericFilter();
+
+    // Types
+    typedef ResampleImageGenericFilter    Self;
+    typedef itk::SmartPointer<Self>       Pointer;
+    typedef itk::SmartPointer<const Self> ConstPointer;
+
+    // New
+    itkNewMacro(Self);
+
+    // Args
+    void SetArgsInfo(const args_info_type & a);
+    
+    // Main function
+    template<class InputImageType> void UpdateWithInputImageType();
+
+  protected:
+    args_info_type mArgsInfo;
+    template<unsigned int Dim> void InitializeImageType();
+     
+  }; // end class ResampleImageGenericFilter
+  //--------------------------------------------------------------------
+    
+} // end namespace clitk
+//--------------------------------------------------------------------
+
+//--------------------------------------------------------------------
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkResampleImageGenericFilter.txx"
+#endif
+//--------------------------------------------------------------------
+
+#endif /* end #define CLITKIRESAMPLEIMAGEGENERICFILTER_H */
+
diff --git a/filters/clitkResampleImageGenericFilter.txx b/filters/clitkResampleImageGenericFilter.txx
new file mode 100644 (file)
index 0000000..9bd079b
--- /dev/null
@@ -0,0 +1,178 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+
+#ifndef CLITKRESAMPLEIMAGEGENERICFILTER_TXX
+#define CLITKRESAMPLEIMAGEGENERICFILTER_TXX
+
+// clitk
+#include "clitkResampleImageWithOptionsFilter.h"
+
+namespace clitk {
+
+  //--------------------------------------------------------------------
+  template<class args_info_type>
+  ResampleImageGenericFilter<args_info_type>::ResampleImageGenericFilter():
+    ImageToImageGenericFilter<Self>("Resample") {
+    // InitializeImageType<2>();
+    InitializeImageType<3>();
+    InitializeImageType<4>();
+  }
+  //--------------------------------------------------------------------
+
+
+  //--------------------------------------------------------------------
+  template<class args_info_type>
+  template<unsigned int Dim>
+  void ResampleImageGenericFilter<args_info_type>::InitializeImageType() {      
+    //    ADD_DEFAULT_IMAGE_TYPES(Dim);
+    ADD_IMAGE_TYPE(Dim, short);
+  }
+  //--------------------------------------------------------------------
+  
+
+  //--------------------------------------------------------------------
+  template<class args_info_type>
+  void ResampleImageGenericFilter<args_info_type>::SetArgsInfo(const args_info_type & a) {
+    mArgsInfo=a;
+    if (mArgsInfo.imagetypes_flag) this->PrintAvailableImageTypes();
+    SetIOVerbose(mArgsInfo.verbose_flag);
+    if (mArgsInfo.input_given) {
+      SetInputFilename(mArgsInfo.input_arg);
+    }
+    if (mArgsInfo.output_given) {
+      SetOutputFilename(mArgsInfo.output_arg);
+    }
+  }
+  //--------------------------------------------------------------------
+
+
+  //--------------------------------------------------------------------
+  // Update with the number of dimensions and the pixeltype
+  //--------------------------------------------------------------------
+  template<class args_info_type>
+  template<class InputImageType>
+  void 
+  ResampleImageGenericFilter<args_info_type>::UpdateWithInputImageType() {
+
+    // Reading input
+    typename InputImageType::Pointer input = this->template GetInput<InputImageType>(0);
+
+    // Main filter
+    typedef typename InputImageType::PixelType PixelType;
+    typedef InputImageType OutputImageType; // to change to float is user ask it (?)
+
+    // Filter
+    typedef clitk::ResampleImageWithOptionsFilter<InputImageType, OutputImageType> ResampleImageFilterType;
+    typename ResampleImageFilterType::Pointer filter = ResampleImageFilterType::New();
+    filter->SetInput(input);
+
+    // Set Verbose   
+    filter->SetVerboseOptions(mArgsInfo.verbose_flag);
+
+    // Set size / spacing
+    static const unsigned int dim = OutputImageType::ImageDimension;
+    typename OutputImageType::SpacingType spacing;
+    typename OutputImageType::SizeType size;
+    if (mArgsInfo.spacing_given == 1) {
+      filter->SetIsoSpacing(mArgsInfo.spacing_arg[0]);
+    }
+    else {
+      if ((mArgsInfo.spacing_given != 0) && (mArgsInfo.size_given != 0)) {
+         std::cerr << "Error: use spacing or size, not both." << std::endl;
+         exit(0);
+      }
+
+      if (!((mArgsInfo.spacing_given == 0) && (mArgsInfo.size_given == 0))) {
+
+       if ((mArgsInfo.spacing_given != 0) && (mArgsInfo.spacing_given != dim)) {
+         std::cerr << "Error: spacing should have one or " << dim << " values." << std::endl;
+         exit(0);
+       }
+       if ((mArgsInfo.size_given != 0) && (mArgsInfo.size_given != dim)) {
+         std::cerr << "Error: size should have " << dim << " values." << std::endl;
+         exit(0);
+       }
+        if (mArgsInfo.spacing_given)
+          for(unsigned int i=0; i<dim; i++) 
+            spacing[i] = mArgsInfo.spacing_arg[i];
+        if (mArgsInfo.size_given)
+          for(unsigned int i=0; i<dim; i++) 
+         size[i] = mArgsInfo.size_arg[i];
+       filter->SetOutputSpacing(spacing);
+       filter->SetOutputSize(size);
+      }
+    }
+      
+    // Set temporal dimension
+    filter->SetLastDimensionIsTime(mArgsInfo.time_flag);
+
+    // Set Gauss
+    filter->SetGaussianFilteringEnabled(mArgsInfo.autogauss_flag);
+    if (mArgsInfo.gauss_given != 0) {
+      typename ResampleImageFilterType::GaussianSigmaType g;
+      for(unsigned int i=0; i<dim; i++) {
+       g[i] = mArgsInfo.gauss_arg[i];
+      }
+      filter->SetGaussianSigma(g);
+    }
+    
+    // Set Interpolation
+    std::string interp = std::string(mArgsInfo.interp_arg);
+    if (interp == "nn") {
+      filter->SetInterpolationType(ResampleImageFilterType::NearestNeighbor);
+    }
+    else {
+      if (interp == "linear") {
+        filter->SetInterpolationType(ResampleImageFilterType::Linear);
+      }
+      else {
+        if (interp == "bspline") {
+          filter->SetInterpolationType(ResampleImageFilterType::BSpline);
+        }
+        else {
+          if (interp == "blut") {
+            filter->SetInterpolationType(ResampleImageFilterType::B_LUT);
+          }
+          else {
+            std::cerr << "Error. I do not know interpolation '" << mArgsInfo.interp_arg 
+                      << "'. Choose among: nn, linear, bspline, blut" << std::endl;
+            exit(0);
+          }
+        }
+      }
+    }
+    
+    // Set default pixel value
+    filter->SetDefaultPixelValue(mArgsInfo.default_arg);
+
+    // Set thread
+    if (mArgsInfo.thread_given) {
+      filter->SetNumberOfThreads(mArgsInfo.thread_arg);
+    }
+
+    // Go !
+    filter->Update();
+    typename OutputImageType::Pointer outputImage = filter->GetOutput();
+    this->template SetNextOutput<OutputImageType>(outputImage);
+  }
+  //--------------------------------------------------------------------
+
+}
+
+#endif /* end #define CLITKRESAMPLEIMAGEGENERICFILTER_TXX */
+
diff --git a/itk/clitkResampleImageWithOptionsFilter.h b/itk/clitkResampleImageWithOptionsFilter.h
new file mode 100644 (file)
index 0000000..7c212f0
--- /dev/null
@@ -0,0 +1,153 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+  ======================================================================-====*/
+
+#ifndef CLITKRESAMPLEIMAGEWITHOPTIONSFILTER_H
+#define CLITKRESAMPLEIMAGEWITHOPTIONSFILTER_H
+
+#include "itkImageToImageFilter.h"
+#include "itkAffineTransform.h"
+
+namespace clitk {
+  
+  //--------------------------------------------------------------------
+  /*
+    Image resampling with several interpolations and Gaussian filtering included.
+  */
+  //--------------------------------------------------------------------
+  
+  template <class TInputImage, class TOutputImage=TInputImage>
+  class ITK_EXPORT ResampleImageWithOptionsFilter: 
+    public itk::ImageToImageFilter<TInputImage, TOutputImage> {
+
+  public:
+    /** Standard class typedefs. */
+    typedef ResampleImageWithOptionsFilter                     Self;
+    typedef itk::ImageToImageFilter<TInputImage, TOutputImage> Superclass;
+    typedef itk::SmartPointer<Self>                            Pointer;
+    typedef itk::SmartPointer<const Self>                      ConstPointer;
+    
+    /** Method for creation through the object factory. */
+    itkNewMacro(Self);
+    
+    /** Run-time type information (and related methods). */
+    itkTypeMacro(ResampleImageWithOptionsFilter, ImageToImageFilter);
+
+    /** Some convenient typedefs. */
+    typedef TInputImage                           InputImageType;
+    typedef typename InputImageType::ConstPointer InputImageConstPointer;
+    typedef typename InputImageType::Pointer      InputImagePointer;
+    typedef typename InputImageType::RegionType   InputImageRegionType; 
+    typedef typename InputImageType::PixelType    InputImagePixelType;
+    typedef typename InputImageType::SpacingType  InputImageSpacingType;
+    typedef typename InputImageType::SizeType     InputImageSizeType;
+    
+    typedef TOutputImage                           OutputImageType;
+    typedef typename OutputImageType::ConstPointer OutputImageConstPointer;
+    typedef typename OutputImageType::Pointer      OutputImagePointer;
+    typedef typename OutputImageType::RegionType   OutputImageRegionType; 
+    typedef typename OutputImageType::PixelType    OutputImagePixelType;
+    typedef typename OutputImageType::SpacingType  OutputImageSpacingType;
+    typedef typename OutputImageType::SizeType     OutputImageSizeType;
+    
+    typedef itk::AffineTransform<double, InputImageType::ImageDimension> TransformType;
+    typedef typename InputImageType::SpacingType                         GaussianSigmaType;
+
+    /** ImageDimension constants */
+    itkStaticConstMacro(InputImageDimension, unsigned int,
+                        TInputImage::ImageDimension);
+    itkStaticConstMacro(OutputImageDimension, unsigned int,
+                        TOutputImage::ImageDimension);
+    itkConceptMacro(SameDimensionCheck,
+                    (itk::Concept::SameDimension<InputImageDimension, OutputImageDimension>));
+
+    /** Interpolation types */
+    typedef enum {
+      NearestNeighbor = 0,
+      Linear = 1, 
+      BSpline = 2, 
+      B_LUT = 3
+    } InterpolationTypeEnumeration;
+
+    /** Input : image to resample */
+    void SetInput(const InputImageType * image);
+    
+    /** ImageDimension constants */
+    itkStaticConstMacro(ImageDimension, unsigned int, InputImageType::ImageDimension);
+
+    // Options
+    itkGetMacro(LastDimensionIsTime, bool);
+    itkSetMacro(LastDimensionIsTime, bool);
+    itkSetMacro(IsoSpacing, double);
+    itkGetMacro(IsoSpacing, double);
+    itkSetMacro(OutputSpacing, OutputImageSpacingType);
+    itkGetMacro(OutputSpacing, OutputImageSpacingType);
+    itkSetMacro(OutputSize, OutputImageSizeType);
+    itkGetMacro(OutputSize, OutputImageSizeType);
+    itkGetMacro(InterpolationType, InterpolationTypeEnumeration);
+    itkSetMacro(InterpolationType, InterpolationTypeEnumeration);    
+    itkGetMacro(GaussianFilteringEnabled, bool);
+    itkSetMacro(GaussianFilteringEnabled, bool);
+    itkGetMacro(BSplineOrder, int);
+    itkSetMacro(BSplineOrder, int);
+    itkGetMacro(BLUTSamplingFactor, int);
+    itkSetMacro(BLUTSamplingFactor, int);
+    itkGetMacro(Transform, typename TransformType::Pointer);
+    itkSetMacro(Transform, typename TransformType::Pointer);
+    itkGetMacro(GaussianSigma, GaussianSigmaType);
+    itkSetMacro(GaussianSigma, GaussianSigmaType);
+    itkGetMacro(DefaultPixelValue, OutputImagePixelType);
+    itkSetMacro(DefaultPixelValue, OutputImagePixelType);
+    itkGetMacro(VerboseOptions, bool);
+    itkSetMacro(VerboseOptions, bool);
+    
+  protected:
+    ResampleImageWithOptionsFilter();
+    virtual ~ResampleImageWithOptionsFilter() {}
+    
+    bool m_LastDimensionIsTime;
+    double m_IsoSpacing;
+    InterpolationTypeEnumeration m_InterpolationType;
+    bool m_GaussianFilteringEnabled;
+    int m_BSplineOrder;
+    int m_BLUTSamplingFactor;    
+    OutputImageSizeType m_OutputSize;
+    OutputImageSpacingType m_OutputSpacing;  
+    typename TransformType::Pointer m_Transform;
+    GaussianSigmaType m_GaussianSigma;
+    OutputImagePixelType m_DefaultPixelValue;
+    bool m_VerboseOptions;
+
+    virtual void GenerateInputRequestedRegion();
+    virtual void GenerateOutputInformation();
+    virtual void GenerateData();
+    
+  private:
+    ResampleImageWithOptionsFilter(const Self&); //purposely not implemented
+    void operator=(const Self&); //purposely not implemented
+    
+  }; // end class
+  //--------------------------------------------------------------------
+
+} // end namespace clitk
+//--------------------------------------------------------------------
+
+#ifndef ITK_MANUAL_INSTANTIATION
+#include "clitkResampleImageWithOptionsFilter.txx"
+#endif
+
+#endif
diff --git a/itk/clitkResampleImageWithOptionsFilter.txx b/itk/clitkResampleImageWithOptionsFilter.txx
new file mode 100644 (file)
index 0000000..87f34dd
--- /dev/null
@@ -0,0 +1,290 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+  ======================================================================-====*/
+
+// clitk
+#include "clitkCommon.h"
+
+// itk include
+#include "itkImage.h"
+#include "itkImageFileReader.h"
+#include "itkImageSeriesReader.h"
+#include "itkImageFileWriter.h"
+#include "itkRecursiveGaussianImageFilter.h"
+#include "itkResampleImageFilter.h"
+#include "itkAffineTransform.h"
+#include "itkNearestNeighborInterpolateImageFunction.h"
+#include "itkLinearInterpolateImageFunction.h"
+#include "itkBSplineInterpolateImageFunction.h"
+#include "itkBSplineInterpolateImageFunctionWithLUT.h"
+#include "itkCommand.h"
+
+namespace clitk {
+
+  //--------------------------------------------------------------------
+  template <class TInputImage, class TOutputImage>
+  ResampleImageWithOptionsFilter<TInputImage, TOutputImage>::
+  ResampleImageWithOptionsFilter():itk::ImageToImageFilter<TInputImage, TOutputImage>() {
+    static const unsigned int dim = InputImageType::ImageDimension;
+    this->SetNumberOfRequiredInputs(1);
+    m_IsoSpacing = -1;
+    m_InterpolationType = NearestNeighbor;
+    m_GaussianFilteringEnabled = true;
+    m_BSplineOrder = 3;
+    m_BLUTSamplingFactor = 20;
+    m_LastDimensionIsTime = false;
+    m_Transform =  TransformType::New();
+    if (dim == 4) m_LastDimensionIsTime = true; // by default 4D is 3D+t
+    for(unsigned int i=0; i<dim; i++) {
+      m_OutputSize[i] = 0;
+      m_OutputSpacing[i] = -1;
+      m_GaussianSigma[i] = -1;
+    }
+    m_VerboseOptions = false;
+  }
+  //--------------------------------------------------------------------
+
+
+  //--------------------------------------------------------------------
+  template <class TInputImage, class TOutputImage>
+  void 
+  ResampleImageWithOptionsFilter<TInputImage, TOutputImage>::
+  SetInput(const InputImageType * image) {
+    // Process object is not const-correct so the const casting is required.
+    this->SetNthInput(0, const_cast<InputImageType *>(image));
+  }
+  //--------------------------------------------------------------------
+  
+
+  //--------------------------------------------------------------------
+  template <class TInputImage, class TOutputImage>
+  void 
+  ResampleImageWithOptionsFilter<TInputImage, TOutputImage>::
+  GenerateInputRequestedRegion() {
+    // call the superclass's implementation of this method
+    Superclass::GenerateInputRequestedRegion();
+    
+    // get pointers to the input and output
+    InputImagePointer  inputPtr  = 
+      const_cast< TInputImage *>( this->GetInput() );
+    
+    // Request the entire input image
+    InputImageRegionType inputRegion;
+    inputRegion = inputPtr->GetLargestPossibleRegion();
+    inputPtr->SetRequestedRegion(inputRegion);
+   }
+  //--------------------------------------------------------------------
+
+
+  //--------------------------------------------------------------------
+  template <class TInputImage, class TOutputImage>
+  void 
+  ResampleImageWithOptionsFilter<TInputImage, TOutputImage>::
+  GenerateOutputInformation() { 
+    static const unsigned int dim = InputImageType::ImageDimension;
+
+    // Warning
+    if (!std::numeric_limits<InputImagePixelType>::is_signed) {
+      if ((m_InterpolationType == BSpline) || 
+          (m_InterpolationType == B_LUT)) {
+        std::cerr << "Warning : input pixel type is not signed, use bspline interpolation at your own risk ..." << std::endl;
+      }
+    }
+
+    // Get input pointer
+    InputImagePointer input = dynamic_cast<InputImageType*>(itk::ProcessObject::GetInput(0));
+     
+    // Perform default implementation
+    Superclass::GenerateOutputInformation();
+
+    // Compute sizes 
+    InputImageSpacingType inputSpacing = input->GetSpacing();
+    InputImageSizeType inputSize = input->GetLargestPossibleRegion().GetSize();
+
+    if (m_IsoSpacing != -1) { // apply isoSpacing
+      for(unsigned int i=0; i<dim; i++) {
+        m_OutputSpacing[i] = m_IsoSpacing;
+        m_OutputSize[i] = (int)lrint(inputSize[i]*inputSpacing[i]/m_OutputSpacing[i]);
+      }
+    }
+    else {
+      if (m_OutputSpacing[0] != -1) { // apply spacing, compute size
+        for(unsigned int i=0; i<dim; i++) {
+          m_OutputSize[i] = (int)lrint(inputSize[i]*inputSpacing[i]/m_OutputSpacing[i]);
+        }
+      }
+      else {
+        if (m_OutputSize[0] != 0) { // apply size, compute spacing
+          for(unsigned int i=0; i<dim; i++) {
+            m_OutputSpacing[i] = (double)inputSize[i]*inputSpacing[i]/(double)m_OutputSize[i];
+          }
+        }
+        else { // copy input size/spacing ... (no resampling)
+          m_OutputSize = inputSize;
+          m_OutputSpacing = inputSpacing;
+        }
+      }
+    }
+
+    // Special case for temporal image 2D+t or 3D+t
+    if (m_LastDimensionIsTime) {
+      int l = dim-1;
+      m_OutputSize[l] = inputSize[l];
+      m_OutputSpacing[l] = inputSpacing[l];
+    }
+    
+    // Set Size/Spacing
+    OutputImagePointer outputImage = this->GetOutput(0);
+    OutputImageRegionType region;
+    region.SetSize(m_OutputSize);
+    region.SetIndex(input->GetLargestPossibleRegion().GetIndex());
+    outputImage->SetLargestPossibleRegion(region);
+
+    // Init Gaussian sigma
+    if (m_GaussianSigma[0] != -1) { // Gaussian filter set by user
+      m_GaussianFilteringEnabled = true;
+    }
+    else {
+      if (m_GaussianFilteringEnabled) { // Automated sigma when downsample
+        for(unsigned int i=0; i<dim; i++) {
+          if (m_OutputSpacing[i] > inputSpacing[i]) { // downsample
+            m_GaussianSigma[i] = 0.5*m_OutputSpacing[i];// / inputSpacing[i]);
+          }
+          else m_GaussianSigma[i] = 0; // will be ignore after
+        }
+      }
+    }
+    if (m_GaussianFilteringEnabled && m_LastDimensionIsTime) {
+      m_GaussianSigma[dim-1] = 0;
+    }
+  }
+  //--------------------------------------------------------------------
+
+
+  //--------------------------------------------------------------------
+   template <class TInputImage, class TOutputImage>
+  void 
+  ResampleImageWithOptionsFilter<TInputImage, TOutputImage>::
+  GenerateData() {
+   
+    // Get input pointer
+    InputImagePointer input = dynamic_cast<InputImageType*>(itk::ProcessObject::GetInput(0));
+    static const unsigned int dim = InputImageType::ImageDimension;
+
+     // Create main Resample Image Filter
+    typedef itk::ResampleImageFilter<InputImageType,OutputImageType> FilterType;
+    typename FilterType::Pointer filter = FilterType::New();
+    filter->GraftOutput(this->GetOutput());
+
+    // Print options if needed
+    if (m_VerboseOptions) {
+      std::cout << "Output Spacing = " << m_OutputSpacing << std::endl
+                << "Output Size    = " << m_OutputSize << std::endl
+                << "Gaussian       = " << m_GaussianFilteringEnabled << std::endl;
+      if (m_GaussianFilteringEnabled) 
+        std::cout << "Sigma          = " << m_GaussianSigma << std::endl;
+      std::cout << "Interpol       = ";
+      switch (m_InterpolationType) {
+      case NearestNeighbor: std::cout << "NearestNeighbor" << std::endl; break;
+      case Linear:          std::cout << "Linear" << std::endl; break;
+      case BSpline:         std::cout << "BSpline " << m_BSplineOrder << std::endl; break;
+      case B_LUT:           std::cout << "B-LUT " << m_BSplineOrder << " " << m_BLUTSamplingFactor << std::endl; break;
+      }
+      std::cout << "Threads        = " << this->GetNumberOfThreads() << std::endl;
+      std::cout << "LastDimIsTime  = " << m_LastDimensionIsTime << std::endl;
+    }
+
+    // Instance of the transform object to be passed to the resample
+    // filter. By default, identity transform is applied
+    filter->SetTransform(m_Transform);
+    filter->SetSize(m_OutputSize);
+    filter->SetOutputSpacing(m_OutputSpacing);
+    filter->SetOutputOrigin(input->GetOrigin());
+    filter->SetDefaultPixelValue(m_DefaultPixelValue);
+    filter->SetNumberOfThreads(this->GetNumberOfThreads()); 
+
+    // Select interpolator
+    switch (m_InterpolationType) {
+    case NearestNeighbor: 
+      {
+        typedef itk::NearestNeighborInterpolateImageFunction<InputImageType, double> InterpolatorType;     
+        typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
+        filter->SetInterpolator(interpolator);
+        break;
+      }
+    case Linear: 
+      {
+        typedef itk::LinearInterpolateImageFunction<InputImageType, double> InterpolatorType;     
+        typename InterpolatorType::Pointer interpolator =  InterpolatorType::New();
+        filter->SetInterpolator(interpolator);
+        break;
+      }
+    case BSpline: 
+      {
+        typedef itk::BSplineInterpolateImageFunction<InputImageType, double> InterpolatorType; 
+        typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
+        interpolator->SetSplineOrder(m_BSplineOrder);
+        filter->SetInterpolator(interpolator);
+      break;
+      }
+    case B_LUT: 
+      {
+        typedef itk::BSplineInterpolateImageFunctionWithLUT<InputImageType, double> InterpolatorType; 
+        typename InterpolatorType::Pointer interpolator = InterpolatorType::New();
+        interpolator->SetSplineOrder(m_BSplineOrder);
+        interpolator->SetLUTSamplingFactor(m_BLUTSamplingFactor);
+        filter->SetInterpolator(interpolator);
+        break;
+      }
+    }
+    
+    // Initial Gaussian blurring if needed
+    typedef itk::RecursiveGaussianImageFilter<InputImageType, InputImageType> GaussianFilterType;
+    std::vector<typename GaussianFilterType::Pointer> gaussianFilters;
+    if (m_GaussianFilteringEnabled) {
+      for(unsigned int i=0; i<dim; i++) {
+        if (m_GaussianSigma[i] != 0) {
+          gaussianFilters.push_back(GaussianFilterType::New());
+          gaussianFilters[i]->SetDirection(i);
+          gaussianFilters[i]->SetOrder(GaussianFilterType::ZeroOrder);
+          gaussianFilters[i]->SetNormalizeAcrossScale(false);
+          gaussianFilters[i]->SetSigma(m_GaussianSigma[i]); // in millimeter !
+          if (gaussianFilters.size() == 1) { // first
+            gaussianFilters[0]->SetInput(input);
+          }
+          else {
+            gaussianFilters[i]->SetInput(gaussianFilters[i-1]->GetOutput());
+          }
+        }
+      }
+      if (gaussianFilters.size() > 0) {
+        filter->SetInput(gaussianFilters[gaussianFilters.size()-1]->GetOutput());
+      }
+      else filter->SetInput(input);
+    }
+    else filter->SetInput(input);
+
+    // Go ! 
+    filter->Update();
+    
+    // Set output
+    this->GraftOutput(filter->GetOutput());
+  }
+  //--------------------------------------------------------------------
+  
+}//end clitk
index 5bd72b5f9ed9e9cc2f1fccbc7f35d1cc2166c15a..dff973e9cfb6c857922c9291b9a93d0b2b2cec35 100644 (file)
@@ -94,3 +94,7 @@ TARGET_LINK_LIBRARIES(clitkBinarizeImage clitkCommon ITKIO clitkFilters)
 WRAP_GGO(clitkMedianImageFilter_GGO_C clitkMedianImageFilter.ggo)
 ADD_EXECUTABLE(clitkMedianImageFilter clitkMedianImageFilter.cxx)
 TARGET_LINK_LIBRARIES(clitkMedianImageFilter clitkCommon ITKIO clitkFilters ITKBasicFilters)
+
+ADD_EXECUTABLE(clitkResampleImage clitkResampleImage.cxx ${clitkResampleImage_GGO_C})
+TARGET_LINK_LIBRARIES(clitkResampleImage clitkCommon ITKIO clitkFilters)
+
diff --git a/tools/clitkResampleImage.cxx b/tools/clitkResampleImage.cxx
new file mode 100644 (file)
index 0000000..acecb05
--- /dev/null
@@ -0,0 +1,41 @@
+/*=========================================================================
+  Program:   vv                     http://www.creatis.insa-lyon.fr/rio/vv
+
+  Authors belong to: 
+  - University of LYON              http://www.universite-lyon.fr/
+  - Léon Bérard cancer center       http://oncora1.lyon.fnclcc.fr
+  - CREATIS CNRS laboratory         http://www.creatis.insa-lyon.fr
+
+  This software is distributed WITHOUT ANY WARRANTY; without even
+  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+  PURPOSE.  See the copyright notices for more information.
+
+  It is distributed under dual licence
+
+  - BSD        See included LICENSE.txt file
+  - CeCILL-B   http://www.cecill.info/licences/Licence_CeCILL-B_V1-en.html
+======================================================================-====*/
+
+// clitk
+#include "clitkResampleImage_ggo.h"
+#include "clitkIO.h"
+#include "clitkResampleImageGenericFilter.h"
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[]) {
+
+  // Init command line
+  GGO(clitkResampleImage, args_info);
+
+  // Filter
+  typedef clitk::ResampleImageGenericFilter<args_info_clitkResampleImage> FilterType;
+  FilterType::Pointer filter = FilterType::New();
+  
+  filter->SetArgsInfo(args_info);
+  filter->Update();
+
+  // this is the end my friend  
+  return EXIT_SUCCESS;
+
+}// end main
+//--------------------------------------------------------------------