]> Creatis software - clitk.git/blobdiff - tools/clitkAffineTransformGenericFilter.txx
Merge branch 'master' of tux.creatis.insa-lyon.fr:clitk
[clitk.git] / tools / clitkAffineTransformGenericFilter.txx
index 5a8cfa964e144132560fbc080da28ae903c67937..93cd16c91c2928455b4af569a450a985ecaa0a49 100644 (file)
@@ -135,16 +135,59 @@ AffineTransformGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
 
   // Matrix
   typename itk::Matrix<double, Dimension+1, Dimension+1> matrix;
-  if (m_ArgsInfo.matrix_given) {
-    matrix= clitk::ReadMatrix<Dimension>(m_ArgsInfo.matrix_arg);
-    if (m_Verbose) std::cout<<"Reading the matrix..."<<std::endl;
-  } else {
-    matrix.SetIdentity();
+  if (m_ArgsInfo.rotate_given || m_ArgsInfo.translate_given)
+  {
+    if (m_ArgsInfo.matrix_given)
+    {
+      std::cerr << "You must use either rotate/translate or matrix options" << std::cout;
+      return;
+    }
+    itk::Array<double> transformParameters(2 * Dimension);
+    transformParameters.Fill(0.0);
+    if (m_ArgsInfo.rotate_given)
+    {
+      if (Dimension == 2)
+        transformParameters[0] = m_ArgsInfo.rotate_arg[0];
+      else
+        for (unsigned int i = 0; i < 3; i++)
+          transformParameters[i] = m_ArgsInfo.rotate_arg[i];
+    }
+    if (m_ArgsInfo.translate_given)
+    {
+      int pos = 3;
+      if (Dimension == 2)
+        pos = 1;
+      for (unsigned int i = 0; i < Dimension && i < 3; i++)
+        transformParameters[pos++] = m_ArgsInfo.translate_arg[i];
+    }
+    if (Dimension == 4)
+    {
+      matrix.SetIdentity();
+      itk::Matrix<double, 4, 4> tmp = GetForwardAffineMatrix3D(transformParameters);
+      for (unsigned int i = 0; i < 3; ++i)
+        for (unsigned int j = 0; j < 3; ++j)
+          matrix[i][j] = tmp[i][j];
+      for (unsigned int i = 0; i < 3; ++i)
+        matrix[i][4] = tmp[i][3];
+    }
+    else
+      matrix = GetForwardAffineMatrix<Dimension>(transformParameters);
   }
-  if (m_Verbose) std::cout<<"Using the following matrix:"<<std::endl;
-  if (m_Verbose) std::cout<<matrix<<std::endl;
-  typename itk::Matrix<double, Dimension, Dimension> rotationMatrix=clitk::GetRotationalPartMatrix(matrix);
-  typename itk::Vector<double,Dimension> translationPart= clitk::GetTranslationPartMatrix(matrix);
+  else
+  {
+    if (m_ArgsInfo.matrix_given)
+    {
+      matrix= clitk::ReadMatrix<Dimension>(m_ArgsInfo.matrix_arg);
+      if (m_Verbose) std::cout << "Reading the matrix..." << std::endl;
+    }
+    else
+      matrix.SetIdentity();
+  }
+  if (m_Verbose)
+    std::cout << "Using the following matrix:" << std::endl
+              << matrix << std::endl;
+  typename itk::Matrix<double, Dimension, Dimension> rotationMatrix = clitk::GetRotationalPartMatrix(matrix);
+  typename itk::Vector<double, Dimension> translationPart = clitk::GetTranslationPartMatrix(matrix);
 
   // Transform
   typedef itk::AffineTransform<double, Dimension> AffineTransformType;
@@ -163,6 +206,46 @@ AffineTransformGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
     likeReader->SetFileName(m_ArgsInfo.like_arg);
     likeReader->Update();
     resampler->SetOutputParametersFromImage(likeReader->GetOutput());
+  } else if(m_ArgsInfo.transform_grid_flag) {
+    typename itk::Matrix<double, Dimension+1, Dimension+1> invMatrix( matrix.GetInverse() );
+    typename itk::Matrix<double, Dimension, Dimension> invRotMatrix( clitk::GetRotationalPartMatrix(invMatrix) );
+    typename itk::Vector<double,Dimension> invTrans =  clitk::GetTranslationPartMatrix(invMatrix);
+
+    // Spacing is influenced by affine transform matrix and input direction
+    typename InputImageType::SpacingType outputSpacing;
+    outputSpacing = invRotMatrix *
+                    input->GetDirection() *
+                    input->GetSpacing();
+
+    // Origin is influenced by translation but not by input direction
+    typename InputImageType::PointType outputOrigin;
+    outputOrigin = invRotMatrix *
+                   input->GetOrigin() +
+                   invTrans;
+
+    // Size is influenced by affine transform matrix and input direction
+    // Size is converted to double, transformed and converted back to size type.
+    vnl_vector<double> vnlOutputSize(Dimension);
+    for(unsigned int i=0; i< Dimension; i++) {
+      vnlOutputSize[i] = input->GetLargestPossibleRegion().GetSize()[i];
+    }
+    vnlOutputSize = invRotMatrix *
+                    input->GetDirection().GetVnlMatrix() *
+                    vnlOutputSize;
+    typename OutputImageType::SizeType outputSize;
+    for(unsigned int i=0; i< Dimension; i++) {
+      // If the size is negative, we have a flip and we must modify
+      // the origin and the spacing accordingly.
+      if(vnlOutputSize[i]<0.) {
+        vnlOutputSize[i] *= -1.;
+        outputOrigin[i] = outputOrigin[i] + outputSpacing[i] * (vnlOutputSize[i]-1);
+        outputSpacing[i] *= -1.;
+      }
+      outputSize[i] = lrint(vnlOutputSize[i]);
+    }
+    resampler->SetSize( outputSize );
+    resampler->SetOutputSpacing( outputSpacing );
+    resampler->SetOutputOrigin( outputOrigin );
   } else {
     //Size
     typename OutputImageType::SizeType outputSize;
@@ -170,7 +253,6 @@ AffineTransformGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
       for(unsigned int i=0; i< Dimension; i++)
         outputSize[i]=m_ArgsInfo.size_arg[i];
     } else outputSize=input->GetLargestPossibleRegion().GetSize();
-    std::cout<<"Setting the size to "<<outputSize<<"..."<<std::endl;
 
     //Spacing
     typename OutputImageType::SpacingType outputSpacing;
@@ -178,7 +260,6 @@ AffineTransformGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
       for(unsigned int i=0; i< Dimension; i++)
         outputSpacing[i]=m_ArgsInfo.spacing_arg[i];
     } else outputSpacing=input->GetSpacing();
-    std::cout<<"Setting the spacing to "<<outputSpacing<<"..."<<std::endl;
 
     //Origin
     typename OutputImageType::PointType outputOrigin;
@@ -186,7 +267,6 @@ AffineTransformGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
       for(unsigned int i=0; i< Dimension; i++)
         outputOrigin[i]=m_ArgsInfo.origin_arg[i];
     } else outputOrigin=input->GetOrigin();
-    std::cout<<"Setting the origin to "<<outputOrigin<<"..."<<std::endl;
 
     // Set
     resampler->SetSize( outputSize );
@@ -195,6 +275,12 @@ AffineTransformGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
 
   }
 
+  if (m_ArgsInfo.verbose_flag) {
+    std::cout << "Setting the output size to " << resampler->GetSize() << "..." << std::endl;
+    std::cout << "Setting the output spacing to " << resampler->GetOutputSpacing() << "..." << std::endl;
+    std::cout << "Setting the output origin to " << resampler->GetOutputOrigin() << "..." << std::endl;
+  }
+
   resampler->SetInput( input );
   resampler->SetTransform( affineTransform );
   resampler->SetInterpolator( genericInterpolator->GetInterpolatorPointer());
@@ -241,14 +327,59 @@ void AffineTransformGenericFilter<args_info_type>::UpdateWithDimAndVectorType()
 
   // Matrix
   typename itk::Matrix<double, Dimension+1, Dimension+1> matrix;
-  if (m_ArgsInfo.matrix_given)
-    matrix= clitk::ReadMatrix<Dimension>(m_ArgsInfo.matrix_arg);
+  if (m_ArgsInfo.rotate_given || m_ArgsInfo.translate_given)
+  {
+    if (m_ArgsInfo.matrix_given)
+    {
+      std::cerr << "You must use either rotate/translate or matrix options" << std::cout;
+      return;
+    }
+    itk::Array<double> transformParameters(2 * Dimension);
+    transformParameters.Fill(0.0);
+    if (m_ArgsInfo.rotate_given)
+    {
+      if (Dimension == 2)
+        transformParameters[0] = m_ArgsInfo.rotate_arg[0];
+      else
+        for (unsigned int i = 0; i < 3; i++)
+          transformParameters[i] = m_ArgsInfo.rotate_arg[i];
+    }
+    if (m_ArgsInfo.translate_given)
+    {
+      int pos = 3;
+      if (Dimension == 2)
+        pos = 1;
+      for (unsigned int i = 0; i < Dimension && i < 3; i++)
+        transformParameters[pos++] = m_ArgsInfo.translate_arg[i];
+    }
+    if (Dimension == 4)
+    {
+      matrix.SetIdentity();
+      itk::Matrix<double, 4, 4> tmp = GetForwardAffineMatrix3D(transformParameters);
+      for (unsigned int i = 0; i < 3; ++i)
+        for (unsigned int j = 0; j < 3; ++j)
+          matrix[i][j] = tmp[i][j];
+      for (unsigned int i = 0; i < 3; ++i)
+        matrix[i][4] = tmp[i][3];
+    }
+    else
+      matrix = GetForwardAffineMatrix<Dimension>(transformParameters);
+  }
   else
-    matrix.SetIdentity();
-  if (m_Verbose) std::cout<<"Using the following matrix:"<<std::endl;
-  if (m_Verbose) std::cout<<matrix<<std::endl;
-  typename itk::Matrix<double, Dimension, Dimension> rotationMatrix=clitk::GetRotationalPartMatrix(matrix);
-  typename itk::Vector<double, Dimension> translationPart= clitk::GetTranslationPartMatrix(matrix);
+  {
+    if (m_ArgsInfo.matrix_given)
+    {
+      matrix= clitk::ReadMatrix<Dimension>(m_ArgsInfo.matrix_arg);
+      if (m_Verbose) std::cout << "Reading the matrix..." << std::endl;
+    }
+    else
+      matrix.SetIdentity();
+  }
+  if (m_Verbose)
+    std::cout << "Using the following matrix:" << std::endl
+              << matrix << std::endl;
+  typename itk::Matrix<double, Dimension, Dimension> rotationMatrix = clitk::GetRotationalPartMatrix(matrix);
+  typename itk::Vector<double, Dimension> translationPart = clitk::GetTranslationPartMatrix(matrix);
 
   // Transform
   typedef itk::AffineTransform<double, Dimension> AffineTransformType;