]> Creatis software - clitk.git/blobdiff - tools/clitkAffineTransformGenericFilter.txx
Add warning
[clitk.git] / tools / clitkAffineTransformGenericFilter.txx
index c758cb2f80273b6c7576abfe04626f0adee996ff..0fa4869f2af12d9f680373060faa16ccba109f85 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);
+  }
+  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;
-  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_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;
@@ -168,7 +211,26 @@ AffineTransformGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
     typename itk::Matrix<double, Dimension, Dimension> invRotMatrix( clitk::GetRotationalPartMatrix(invMatrix) );
     typename itk::Vector<double,Dimension> invTrans =  clitk::GetTranslationPartMatrix(invMatrix);
 
-    // Size is converted to double, transformed and converted back to size type
+    // Display warning
+    if (m_ArgsInfo.spacing_given)
+      std::cout << "Warning --spacing ignored (because --transform_grid_flag)" << std::endl;
+    if (m_ArgsInfo.origin_given)
+      std::cout << "Warning --origin ignored (because --transform_grid_flag)" << std::endl;
+
+    // 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];
@@ -178,18 +240,18 @@ AffineTransformGenericFilter<args_info_type>::UpdateWithDimAndPixelType()
                     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 );
-    
-    // Spacing can be dictly computed in the same way
-    resampler->SetOutputSpacing ( invRotMatrix *
-                                  input->GetDirection() *
-                                  input->GetSpacing() );
-    // Origin is influenced by translation but not by direction
-    resampler->SetOutputOrigin ( invRotMatrix *
-                                 input->GetOrigin() +
-                                 invTrans );
+    resampler->SetOutputSpacing( outputSpacing );
+    resampler->SetOutputOrigin( outputOrigin );
   } else {
     //Size
     typename OutputImageType::SizeType outputSize;
@@ -271,14 +333,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;