]> Creatis software - clitk.git/commitdiff
Merge branch 'master' of git.creatis.insa-lyon.fr:clitk
authorSimon Rit <simon.rit@creatis.insa-lyon.fr>
Thu, 25 Jul 2013 15:31:03 +0000 (17:31 +0200)
committerSimon Rit <simon.rit@creatis.insa-lyon.fr>
Thu, 25 Jul 2013 15:31:03 +0000 (17:31 +0200)
17 files changed:
common/CMakeLists.txt
common/clitkElastix.h [new file with mode: 0644]
common/clitkMatrix.cxx [new file with mode: 0644]
common/clitkMatrix.h [new file with mode: 0644]
common/vvImageReader.cxx
itk/clitkResampleImageWithOptionsFilter.txx
tools/CMakeLists.txt
tools/clitkAffineTransformGenericFilter.h
tools/clitkAffineTransformGenericFilter.txx
tools/clitkElastixTransformToMatrix.cxx
tools/clitkMatrixInverse.cxx [new file with mode: 0644]
tools/clitkMatrixInverse.ggo [new file with mode: 0644]
tools/clitkMatrixToElastixTransform.cxx [new file with mode: 0644]
tools/clitkMatrixToElastixTransform.ggo [new file with mode: 0644]
vv/vvMainWindow.cxx
vv/vvMainWindow.h
vv/vvToolRigidReg.cxx

index 95a1023733734e2e18037763c6fa1247a22b8426..bef0f36c799d76257671f6044a701d67479787b5 100644 (file)
@@ -39,6 +39,7 @@ SET(clitkCommon_SRC
   clitkExceptionObject.cxx
   clitkFilterBase.cxx
   clitkMemoryUsage.cxx
+  clitkMatrix.cxx
   vvImage.cxx
   vvImageReader.cxx
   vvImageWriter.cxx
diff --git a/common/clitkElastix.h b/common/clitkElastix.h
new file mode 100644 (file)
index 0000000..7452bb5
--- /dev/null
@@ -0,0 +1,166 @@
+/*=========================================================================
+  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://www.centreleonberard.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 clitkElastix_h
+#define clitkElastix_h
+
+#include <itkEuler3DTransform.h>
+
+//--------------------------------------------------------------------
+namespace clitk {
+
+//-------------------------------------------------------------------
+bool
+GetElastixValueFromTag(std::ifstream & is,
+                       std::string tag,
+                       std::string & value)
+{
+  std::string line;
+  is.seekg (0, is.beg);
+  while(std::getline(is, line))   {
+    unsigned pos = line.find(tag);
+    if (pos<line.size()) {
+      value=line.substr(pos+tag.size(),line.size()-2);// remove last ')'
+      value.erase (std::remove (value.begin(), value.end(), '"'), value.end());
+      value.erase (std::remove (value.begin(), value.end(), ')'), value.end());
+      return true;
+    }
+  }
+  return false;
+}
+//-------------------------------------------------------------------
+
+
+//-------------------------------------------------------------------
+void
+GetValuesFromValue(const std::string & s,
+                   std::vector<std::string> & values)
+{
+  std::stringstream strstr(s);
+  std::istream_iterator<std::string> it(strstr);
+  std::istream_iterator<std::string> end;
+  std::vector<std::string> results(it, end);
+  values.clear();
+  values.resize(results.size());
+  for(uint i=0; i<results.size(); i++) values[i] = results[i];
+}
+//-------------------------------------------------------------------
+
+
+//-------------------------------------------------------------------
+template<unsigned int Dimension>
+typename itk::Matrix<double, Dimension+1, Dimension+1>
+createMatrixFromElastixFile(std::vector<std::string> & filename, bool verbose=true) {
+  if (Dimension != 3) {
+    FATAL("Only 3D yet" << std::endl);
+  }
+  typename itk::Matrix<double, Dimension+1, Dimension+1> matrix;
+
+  itk::Euler3DTransform<double>::Pointer mat = itk::Euler3DTransform<double>::New();
+  itk::Euler3DTransform<double>::Pointer previous;
+  for(uint j=0; j<filename.size(); j++) {
+
+    // Open file
+    if (verbose) std::cout << "Read elastix parameters in " << filename[j] << std::endl;
+    std::ifstream is;
+    clitk::openFileForReading(is, filename[j]);
+
+    // Check Transform
+    std::string s;
+    bool b = GetElastixValueFromTag(is, "Transform ", s);
+    if (!b) {
+      FATAL("Error must read 'Transform' in " << filename[j] << std::endl);
+    }
+    if (s != "EulerTransform") {
+      FATAL("Sorry only 'EulerTransform'" << std::endl);
+    }
+
+    // FIXME check
+    //    (InitialTransformParametersFilename[j] "NoInitialTransform")
+
+    // Get CenterOfRotationPoint
+    GetElastixValueFromTag(is, "CenterOfRotationPoint ", s); // space is needed
+    if (!b) {
+      FATAL("Error must read 'CenterOfRotationPoint' in " << filename[j] << std::endl);
+    }
+    std::vector<std::string> cor;
+    GetValuesFromValue(s, cor);
+    itk::Euler3DTransform<double>::CenterType c;
+    for(uint i=0; i<3; i++)
+      c[i] = atof(cor[i].c_str());
+    mat->SetCenter(c);
+
+    // Get Transformparameters
+    GetElastixValueFromTag(is, "ComputeZYX ", s); // space is needed
+    mat->SetComputeZYX( s==std::string("true") );
+
+    // Get Transformparameters
+    GetElastixValueFromTag(is, "TransformParameters ", s); // space is needed
+    if (!b) {
+      FATAL("Error must read 'TransformParameters' in " << filename[j] << std::endl);
+    }
+    std::vector<std::string> results;
+    GetValuesFromValue(s, results);
+
+    // construct a stream from the string
+    itk::Euler3DTransform<double>::ParametersType p;
+    p.SetSize(6);
+    for(uint i=0; i<3; i++)
+      p[i] = atof(results[i].c_str()); // Rotation
+    for(uint i=0; i<3; i++)
+      p[i+3] = atof(results[i+3].c_str()); // Translation
+    mat->SetParameters(p);
+
+    if (verbose) {
+      std::cout << "Rotation      (deg) : " << rad2deg(p[0]) << " " << rad2deg(p[1]) << " " << rad2deg(p[2]) << std::endl;
+      std::cout << "Center of rot (phy) : " << c[0] << " " << c[1] << " " << c[2] << std::endl;
+      std::cout << "Translation   (phy) : " << p[3] << " " << p[4] << " " << p[5] << std::endl;
+    }
+
+    // Compose with previous if needed
+    if (j!=0) {
+      mat->Compose(previous);
+      if (verbose) {
+        std::cout << "Composed rotation      (deg) : " << rad2deg(mat->GetAngleX()) << " " << rad2deg(mat->GetAngleY()) << " " << rad2deg(mat->GetAngleZ()) << std::endl;
+        std::cout << "Composed center of rot (phy) : " << mat->GetCenter() << std::endl;
+        std::cout << "Compsoed translation   (phy) : " << mat->GetTranslation() << std::endl;
+      }
+    }
+    // previous = mat->Clone(); // ITK4
+    previous = itk::Euler3DTransform<double>::New();
+    previous->SetParameters(mat->GetParameters());
+    previous->SetCenter(c);
+    previous->SetComputeZYX(mat->GetComputeZYX());
+  }
+
+  mat = previous;
+  for(uint i=0; i<3; i++)
+    for(uint j=0; j<3; j++)
+      matrix[i][j] = mat->GetMatrix()[i][j];
+  // Offset is -Rc + t + c
+  matrix[0][3] = mat->GetOffset()[0];
+  matrix[1][3] = mat->GetOffset()[1];
+  matrix[2][3] = mat->GetOffset()[2];
+  matrix[3][3] = 1;
+
+  return matrix;
+}
+}
+//-------------------------------------------------------------------
+
+#endif
diff --git a/common/clitkMatrix.cxx b/common/clitkMatrix.cxx
new file mode 100644 (file)
index 0000000..c911f55
--- /dev/null
@@ -0,0 +1,71 @@
+/*=========================================================================
+  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://www.centreleonberard.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
+===========================================================================**/
+
+#include "clitkMatrix.h"
+
+//--------------------------------------------------------------------
+namespace clitk {
+
+//-------------------------------------------------------------------
+std::string
+Get4x4MatrixDoubleAsString(vtkMatrix4x4 *matrix,
+                           const int precision)
+{
+  std::ostringstream strmatrix;
+
+  // Figure out the number of digits of the integer part of the largest absolute value
+  // for each column
+  unsigned width[4];
+  for (unsigned int j = 0; j < 4; j++){
+    double absmax = 0.;
+    for (unsigned int i = 0; i < 4; i++)
+      absmax = std::max(absmax, vnl_math_abs(matrix->GetElement(i, j)));
+    unsigned ndigits = (unsigned)std::max(0.,std::log10(absmax))+1;
+    width[j] = precision+ndigits+3;
+  }
+
+  // Output with correct width, aligned to the right
+  for (unsigned int i = 0; i < 4; i++) {
+    for (unsigned int j = 0; j < 4; j++) {
+      strmatrix.setf(ios::fixed,ios::floatfield);
+      strmatrix.precision(precision);
+      strmatrix.fill(' ');
+      strmatrix.width(width[j]);
+      strmatrix << std::right << matrix->GetElement(i, j);
+    }
+    strmatrix << std::endl;
+  }
+  std::string result = strmatrix.str().c_str();
+  return result;
+}
+//-------------------------------------------------------------------
+
+//-------------------------------------------------------------------
+std::string
+Get4x4MatrixDoubleAsString(itk::Matrix<double, 4, 4> m,
+                           const int precision)
+{
+  vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
+  for (unsigned int j = 0; j < 4; j++)
+    for (unsigned int i = 0; i < 4; i++)
+      matrix->SetElement(j,i,m[j][i]);
+  return Get4x4MatrixDoubleAsString(matrix, precision);
+}
+//-------------------------------------------------------------------
+}
+//-------------------------------------------------------------------
diff --git a/common/clitkMatrix.h b/common/clitkMatrix.h
new file mode 100644 (file)
index 0000000..1e497ea
--- /dev/null
@@ -0,0 +1,38 @@
+/*=========================================================================
+  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://www.centreleonberard.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 clitkMatrix_h
+#define clitkMatrix_h
+
+#include <itkMatrix.h>
+#include <vtkMatrix4x4.h>
+#include <vtkSmartPointer.h>
+
+//--------------------------------------------------------------------
+namespace clitk {
+std::string
+Get4x4MatrixDoubleAsString(vtkMatrix4x4 *matrix,
+                           const int precision=3);
+
+std::string
+Get4x4MatrixDoubleAsString(itk::Matrix<double, 4, 4> m,
+                           const int precision=3);
+}
+//-------------------------------------------------------------------
+
+#endif
index ddc4ad3833ae2e60050fee3debd5c58e106ee4c7..23c78f155dd9e4c51ddad251cf87c549e6d7b70c 100644 (file)
@@ -22,6 +22,7 @@
 #include "vvImageReader.h"
 #include "vvImageReader.txx"
 #include "clitkTransformUtilities.h"
+#include "clitkElastix.h"
 
 //------------------------------------------------------------------------------
 vvImageReader::vvImageReader()
@@ -150,18 +151,20 @@ void vvImageReader::ReadMatImageTransform()
 {
   std::string filename(mInputFilenames[0]);
   std::string ext(itksys::SystemTools::GetFilenameLastExtension(filename));
+
+  // Try a ".mat" extension
   if (ext.length() > 0) {
     size_t pos = filename.rfind(ext);
     filename.replace(pos, ext.length(), ".mat");
   }
   else
     filename += ".mat";
-    
   std::ifstream f(filename.c_str());
+  itk::Matrix<double, 4, 4> itkMat;
+  bool itkMatRead = false;
   if(f.is_open()) {
-    f.close();
+    itkMatRead = true;
 
-    itk::Matrix<double, 4, 4> itkMat;
     itkMat.SetIdentity();
     try {
       itkMat = clitk::ReadMatrix3D(filename);
@@ -169,8 +172,29 @@ void vvImageReader::ReadMatImageTransform()
     catch (itk::ExceptionObject & err) {
       itkWarningMacro(<< "Found " << filename
                       << " but this is not a 4x4 matrix so it is ignored.");
+      itkMatRead = false;
     }
+  }
+  f.close();
+
+  // Try a ".elx" extension
+  filename = mInputFilenames[0];
+  if (ext.length() > 0) {
+    size_t pos = filename.rfind(ext);
+    filename.replace(pos, ext.length(), ".elx");
+  }
+  else
+    filename += ".elx";
+  f.open(filename.c_str());
+  if(!itkMatRead && f.is_open()) {
+    itkMatRead = true;
+    std::vector<std::string> l;
+    l.push_back(filename);
+    itkMat = clitk::createMatrixFromElastixFile<3>(l, true);
+  }
+  f.close();
 
+  if(itkMatRead) {
     vtkSmartPointer<vtkMatrix4x4> matrix = vtkSmartPointer<vtkMatrix4x4>::New();
     matrix->Identity();
     for(int j=0; j<4; j++)
@@ -208,12 +232,12 @@ void vvImageReader::ReadMatImageTransform()
     //for image sequences, apply the transform to each images of the sequence
     if (mImage->IsTimeSequence())
     {
-       for (unsigned i = 1 ; i<mImage->GetTransform().size() ; i++)
-        {
-            mImage->GetTransform()[i]->PreMultiply();
-            mImage->GetTransform()[i]->Concatenate(matrix);
-            mImage->GetTransform()[i]->Update();
-        }
+      for (unsigned i = 1 ; i<mImage->GetTransform().size() ; i++)
+      {
+        mImage->GetTransform()[i]->PreMultiply();
+        mImage->GetTransform()[i]->Concatenate(matrix);
+        mImage->GetTransform()[i]->Update();
+      }
     }
 
   }
index a3f88beb3db8443f08fa376da1480433f24e4051..ddaa8a077b41f2ffcf2456836c2eeb7a4f0119fc 100644 (file)
@@ -222,12 +222,19 @@ GenerateData()
     std::cout << "LastDimIsTime  = " << m_LastDimensionIsTime << std::endl;
   }
 
+  // Compute origin based on image corner
+  typename FilterType::OriginPointType origin = input->GetOrigin();
+  for(unsigned int i=0; i<OutputImageType::ImageDimension; i++) {
+    origin[i] -= 0.5 * input->GetSpacing()[i];
+    origin[i] += 0.5 * m_OutputSpacing[i];
+  }
+
   // 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->SetOutputOrigin(origin);
   filter->SetDefaultPixelValue(m_DefaultPixelValue);
   filter->SetNumberOfThreads(this->GetNumberOfThreads()); 
   filter->SetOutputDirection(input->GetDirection()); // <-- NEEDED if we want to keep orientation (in case of PermutAxes for example)
index 77f12f9f863e301e089cc28c49aab05a20276fe8..4cf12f7ec27a45a0b1af906058951996ac99568f 100644 (file)
@@ -113,6 +113,15 @@ IF (CLITK_BUILD_TOOLS)
   TARGET_LINK_LIBRARIES(clitkElastixTransformToMatrix clitkCommon )
   SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkElastixTransformToMatrix)
 
+  WRAP_GGO(clitkMatrixToElastixTransform_GGO_C clitkMatrixToElastixTransform.ggo)
+  ADD_EXECUTABLE(clitkMatrixToElastixTransform clitkMatrixToElastixTransform.cxx ${clitkMatrixToElastixTransform_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkMatrixToElastixTransform clitkCommon )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMatrixToElastixTransform)
+
+  WRAP_GGO(clitkMatrixInverse_GGO_C clitkMatrixInverse.ggo)
+  ADD_EXECUTABLE(clitkMatrixInverse clitkMatrixInverse.cxx ${clitkMatrixInverse_GGO_C})
+  TARGET_LINK_LIBRARIES(clitkMatrixInverse clitkCommon )
+  SET(TOOLS_INSTALL ${TOOLS_INSTALL} clitkMatrixInverse)
 
   WRAP_GGO(clitkSetBackground_GGO_C clitkSetBackground.ggo)
   ADD_EXECUTABLE(clitkSetBackground clitkSetBackground.cxx clitkSetBackgroundGenericFilter.cxx ${clitkSetBackground_GGO_C})
index 39506326f572a2bb614da44524c64547879eda41..613e1cc677b868305c2cf5e5513baacb7026751a 100644 (file)
@@ -87,11 +87,6 @@ namespace clitk
     //----------------------------------------  
     void Update();
 
-    template<unsigned int Dimension, class PixelType>
-      static
-      typename itk::Matrix<double, Dimension+1, Dimension+1>
-      createMatrixFromElastixFile(std::vector<std::string> & filename, bool verbose=true);
-
   protected:
 
     //----------------------------------------  
@@ -108,10 +103,6 @@ namespace clitk
     template <unsigned int Dimension, class PixelType>  void UpdateWithDimAndPixelType();
     template <unsigned int Dimension, class PixelType>  void UpdateWithDimAndVectorType();
 
-    static bool GetElastixValueFromTag(std::ifstream & is, std::string tag, std::string & value); 
-    static void GetValuesFromValue(const std::string & s, 
-                                   std::vector<std::string> & values);
-
     //----------------------------------------  
     // Data members
     //----------------------------------------
index 03cf862e2ee261548d6707761648821823b9e1fb..150c8c172187c9455af05d8a7861e05d34c46855 100644 (file)
@@ -22,6 +22,7 @@
 #include <istream>
 #include <iterator>
 #include <itkCenteredEuler3DTransform.h>
+#include "clitkElastix.h"
 
 namespace clitk
 {
@@ -183,7 +184,7 @@ namespace clitk
           if (m_ArgsInfo.elastix_given) {
             std::vector<std::string> s;
             for(uint i=0; i<m_ArgsInfo.elastix_given; i++) s.push_back(m_ArgsInfo.elastix_arg[i]);
-            matrix = createMatrixFromElastixFile<Dimension,PixelType>(s, m_Verbose);
+            matrix = createMatrixFromElastixFile<Dimension>(s, m_Verbose);
           }
           else 
             matrix.SetIdentity();
@@ -491,140 +492,6 @@ namespace clitk
 
   }
   //-------------------------------------------------------------------
-  
-  
-  //-------------------------------------------------------------------
-  template<class args_info_type>
-  template<unsigned int Dimension, class PixelType>
-  typename itk::Matrix<double, Dimension+1, Dimension+1>
-                                                           AffineTransformGenericFilter<args_info_type>::createMatrixFromElastixFile(std::vector<std::string> & filename, bool verbose)
-  {
-    if (Dimension != 3) {
-      FATAL("Only 3D yet" << std::endl);
-    }
-    typename itk::Matrix<double, Dimension+1, Dimension+1> matrix;
-
-    itk::CenteredEuler3DTransform<double>::Pointer mat = itk::CenteredEuler3DTransform<double>::New();
-    itk::CenteredEuler3DTransform<double>::Pointer previous;
-    for(uint j=0; j<filename.size(); j++) {
-      
-      // Open file
-      if (verbose) std::cout << "Read elastix parameters in " << filename[j] << std::endl;
-      std::ifstream is;
-      clitk::openFileForReading(is, filename[j]);
-      
-      // Check Transform
-      std::string s; 
-      bool b = GetElastixValueFromTag(is, "Transform ", s);
-      if (!b) {
-        FATAL("Error must read 'Transform' in " << filename[j] << std::endl);
-      }
-      if (s != "EulerTransform") {
-        FATAL("Sorry only 'EulerTransform'" << std::endl);
-      }
-      
-      // FIXME check
-      //    (InitialTransformParametersFilename[j] "NoInitialTransform")
-      
-      // Get CenterOfRotationPoint
-      GetElastixValueFromTag(is, "CenterOfRotationPoint ", s); // space is needed
-      if (!b) {
-        FATAL("Error must read 'CenterOfRotationPoint' in " << filename[j] << std::endl);
-      }
-      std::vector<std::string> cor; 
-      GetValuesFromValue(s, cor);
-      
-      // Get Transformparameters
-      GetElastixValueFromTag(is, "TransformParameters ", s); // space is needed
-      if (!b) {
-        FATAL("Error must read 'TransformParameters' in " << filename[j] << std::endl);
-      }
-      std::vector<std::string> results; 
-      GetValuesFromValue(s, results);
-      
-      // construct a stream from the string
-      itk::CenteredEuler3DTransform<double>::ParametersType p;
-      p.SetSize(9);
-      for(uint i=0; i<3; i++)
-        p[i] = atof(results[i].c_str()); // Rotation
-      for(uint i=0; i<3; i++)
-        p[i+3] = atof(cor[i].c_str()); // Centre of rotation
-      for(uint i=0; i<3; i++)
-        p[i+6] = atof(results[i+3].c_str()); // Translation
-      mat->SetParameters(p);
-    
-      if (verbose) {
-        std::cout << "Rotation      (deg) : " << rad2deg(p[0]) << " " << rad2deg(p[1]) << " " << rad2deg(p[2]) << std::endl;
-        std::cout << "Center of rot (phy) : " << p[3] << " " << p[4] << " " << p[5] << std::endl;
-        std::cout << "Translation   (phy) : " << p[6] << " " << p[7] << " " << p[8] << std::endl;
-      }
-
-      // Compose with previous if needed
-      if (j!=0) {
-        mat->Compose(previous);
-        if (verbose) {
-          std::cout << "Composed rotation      (deg) : " << rad2deg(mat->GetAngleX()) << " " << rad2deg(mat->GetAngleY()) << " " << rad2deg(mat->GetAngleZ()) << std::endl;
-          std::cout << "Composed center of rot (phy) : " << mat->GetCenter() << std::endl;
-          std::cout << "Compsoed translation   (phy) : " << mat->GetTranslation() << std::endl;
-        }
-      }
-      // previous = mat->Clone(); // ITK4
-      previous = itk::CenteredEuler3DTransform<double>::New();
-      previous->SetParameters(mat->GetParameters());
-    }
-
-    mat = previous;
-    for(uint i=0; i<3; i++)
-      for(uint j=0; j<3; j++)
-        matrix[i][j] = mat->GetMatrix()[i][j];
-    // Offset is -Rc + t + c
-    matrix[0][3] = mat->GetOffset()[0];
-    matrix[1][3] = mat->GetOffset()[1];
-    matrix[2][3] = mat->GetOffset()[2];
-    matrix[3][3] = 1;
-    
-    return matrix;
-  }
-
-  //-------------------------------------------------------------------
-  template<class args_info_type>
-  bool
-  AffineTransformGenericFilter<args_info_type>::GetElastixValueFromTag(std::ifstream & is, 
-                                                                       std::string tag, 
-                                                                       std::string & value)
-  {
-    std::string line;
-    is.seekg (0, is.beg);
-    while(std::getline(is, line))   {
-      unsigned pos = line.find(tag);
-      if (pos<line.size()) {
-        value=line.substr(pos+tag.size(),line.size()-2);// remove last ')'
-        value.erase (std::remove (value.begin(), value.end(), '"'), value.end());
-        value.erase (std::remove (value.begin(), value.end(), ')'), value.end());
-        return true;
-      }
-    }
-    return false;
-  }
-  //-------------------------------------------------------------------
-
-
-  //-------------------------------------------------------------------
-  template<class args_info_type>
-  void
-  AffineTransformGenericFilter<args_info_type>::GetValuesFromValue(const std::string & s, 
-                                                                   std::vector<std::string> & values)
-  {
-    std::stringstream strstr(s);
-    std::istream_iterator<std::string> it(strstr);
-    std::istream_iterator<std::string> end;
-    std::vector<std::string> results(it, end);
-    values.clear();
-    values.resize(results.size());
-    for(uint i=0; i<results.size(); i++) values[i] = results[i];
-  }
-  //-------------------------------------------------------------------
-
 
 } //end clitk
 
index 59bf49e60ae955abcdd504e1f588fab0e33b88bf..7efc4e965161c8171f80f1d4157431fcdb02abd2 100644 (file)
@@ -19,6 +19,8 @@
 // clitk
 #include "clitkElastixTransformToMatrix_ggo.h"
 #include "clitkAffineTransformGenericFilter.h"
+#include "clitkElastix.h"
+#include "clitkMatrix.h"
 
 //--------------------------------------------------------------------
 int main(int argc, char * argv[])
@@ -29,21 +31,15 @@ int main(int argc, char * argv[])
   CLITK_INIT;
 
   // Use static fct of AffineTransformGenericFilter
-  typedef clitk::AffineTransformGenericFilter<args_info_clitkElastixTransformToMatrix> FilterType;
   std::vector<std::string> l;
   l.push_back(args_info.input_arg);
-  itk::Matrix<double, 4, 4> m = 
-    FilterType::createMatrixFromElastixFile<3, int>(l, args_info.verbose_flag);
+  itk::Matrix<double, 4, 4> m = clitk::createMatrixFromElastixFile<3>(l, args_info.verbose_flag);
 
   // Print matrix
   std::ofstream os;
   clitk::openFileForWriting(os, args_info.output_arg);
-  for(unsigned int i=0; i<4; i++) {
-    for(unsigned int j=0; j<4; j++)
-      os << m[i][j] << " ";
-    os << std::endl;
-  }
-  os.close();  
+  os << clitk::Get4x4MatrixDoubleAsString(m, 16);
+  os.close();
 
   return EXIT_SUCCESS;
 }// end main
diff --git a/tools/clitkMatrixInverse.cxx b/tools/clitkMatrixInverse.cxx
new file mode 100644 (file)
index 0000000..7171467
--- /dev/null
@@ -0,0 +1,54 @@
+/*=========================================================================
+  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://www.centreleonberard.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 "clitkMatrixInverse_ggo.h"
+#include "clitkTransformUtilities.h"
+#include "clitkIO.h"
+#include "clitkMatrix.h"
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[])
+{
+  // Init command line
+  GGO(clitkMatrixInverse, args_info);
+  CLITK_INIT;
+
+  // Read matrix
+  itk::Matrix<double, 4, 4> matrix;
+  try {
+    matrix = clitk::ReadMatrix3D(args_info.input_arg);
+  }
+  catch (itk::ExceptionObject & err) {
+    std::cerr << "Error reading " << args_info.input_arg << std::endl;
+    std::cerr << err.GetDescription() << std::endl;
+    exit(-1);
+  }
+
+  matrix = matrix.GetInverse();
+
+  // Print matrix
+  std::ofstream os;
+  clitk::openFileForWriting(os, args_info.output_arg);
+  os << clitk::Get4x4MatrixDoubleAsString(matrix, 16);
+  os.close();
+
+  return EXIT_SUCCESS;
+}// end main
+
+//--------------------------------------------------------------------
diff --git a/tools/clitkMatrixInverse.ggo b/tools/clitkMatrixInverse.ggo
new file mode 100644 (file)
index 0000000..391ae2f
--- /dev/null
@@ -0,0 +1,8 @@
+#File clitkMatrixToElastixTransform.ggo
+package "clitkMatrixInverse"
+version "1.0"
+purpose ""
+
+option "config"  - "Config file"            string optional
+option "input"   i "Input matrix filename"  string required
+option "output"  o "Output matrix filename" string required
diff --git a/tools/clitkMatrixToElastixTransform.cxx b/tools/clitkMatrixToElastixTransform.cxx
new file mode 100644 (file)
index 0000000..a8b7520
--- /dev/null
@@ -0,0 +1,118 @@
+/*=========================================================================
+  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://www.centreleonberard.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 "clitkMatrixToElastixTransform_ggo.h"
+#include "clitkTransformUtilities.h"
+#include "clitkIO.h"
+
+// itk
+#include <itkEuler3DTransform.h>
+
+//--------------------------------------------------------------------
+int main(int argc, char * argv[])
+{
+  // Init command line
+  GGO(clitkMatrixToElastixTransform, args_info);
+  CLITK_INIT;
+
+  // Read matrix
+  itk::Matrix<double, 4, 4> matrix;
+  try {
+    matrix = clitk::ReadMatrix3D(args_info.input_arg);
+  }
+  catch (itk::ExceptionObject & err) {
+    std::cerr << "Error reading " << args_info.input_arg << std::endl;
+    std::cerr << err.GetDescription() << std::endl;
+    exit(-1);
+  }
+
+  // Compute parameters from transfer using itk Euler transform
+  itk::Euler3DTransform<double>::CenterType center;
+  center.Fill(0.);
+  if(args_info.center_given==3) {
+    center[0] = args_info.center_arg[0];
+    center[1] = args_info.center_arg[1];
+    center[2] = args_info.center_arg[2];
+  }
+  itk::Euler3DTransform<double>::MatrixType rotMat;
+  itk::Euler3DTransform<double>::OutputVectorType transVec;
+  for(int i=0; i<3; i++) {
+    transVec[i] = matrix[i][3];
+    for(int j=0; j<3; j++)
+      rotMat[i][j] = matrix[i][j];
+  }
+  itk::Euler3DTransform<double>::Pointer euler;
+  euler = itk::Euler3DTransform<double>::New();
+  euler->SetCenter(center);
+  euler->SetOffset(transVec);
+  euler->SetComputeZYX(false);
+  try {
+    euler->SetMatrix(rotMat);
+  }
+  catch (itk::ExceptionObject & err) {
+    std::cerr << "Error reading " << args_info.input_arg << std::endl;
+    std::cerr << err.GetDescription() << std::endl;
+    exit(-1);
+  }
+
+  // Write result
+  std::ofstream out;
+  clitk::openFileForWriting(out, args_info.output_arg);
+  out << "(Transform \"EulerTransform\")" << std::endl;
+  out << "(NumberOfParameters 6)" << std::endl;
+  out << "(TransformParameters ";
+  for(unsigned int i=0; i<6; i++)
+    out << euler->GetParameters()[i] << ' ';
+  out << ')' << std::endl;
+  out << "(InitialTransformParametersFileName \"NoInitialTransform\")" << std::endl;
+  out << "(HowToCombineTransforms \"Compose\")" << std::endl;
+
+  out << "// EulerTransform specific" << std::endl;
+  out << "(CenterOfRotationPoint "<< center[0] << ' ' << center[1] << ' ' << center[2] << ')' << std::endl;
+  out << "(ComputeZYX \"false\")" << std::endl;
+
+  // The rest is commented, up to the user to define it manually
+  out << "// Image specific" << std::endl;
+  out << "// (FixedImageDimension 3)" << std::endl;
+  out << "// (MovingImageDimension 3)" << std::endl;
+  out << "// (FixedInternalImagePixelType \"float\")" << std::endl;
+  out << "// (MovingInternalImagePixelType \"float\")" << std::endl;
+  out << "// (Size 1 1 1)" << std::endl;
+  out << "// (Index 0 0 0)" << std::endl;
+  out << "// (Spacing 1 1 1)" << std::endl;
+  out << "// (Origin -0.5 -0.5 -0.5)" << std::endl;
+  out << "// (Direction 1 0 0 0 1 0 0 0 1)" << std::endl;
+  out << "// (UseDirectionCosines \"true\")" << std::endl << std::endl;
+
+  out << "// ResampleInterpolator specific" << std::endl;
+  out << "// (ResampleInterpolator \"FinalBSplineInterpolator\")" << std::endl;
+  out << "// (FinalBSplineInterpolationOrder 3)" << std::endl << std::endl;
+
+  out << "// Resampler specific" << std::endl;
+  out << "// (Resampler \"DefaultResampler\")" << std::endl;
+  out << "// (DefaultPixelValue 0.000000)" << std::endl;
+  out << "// (ResultImageFormat \"mhd\")" << std::endl;
+  out << "// (ResultImagePixelType \"short\")" << std::endl;
+  out << "// (CompressResultImage \"false\")" << std::endl;
+  out.close();
+
+  return EXIT_SUCCESS;
+}// end main
+
+//--------------------------------------------------------------------
diff --git a/tools/clitkMatrixToElastixTransform.ggo b/tools/clitkMatrixToElastixTransform.ggo
new file mode 100644 (file)
index 0000000..38f73fa
--- /dev/null
@@ -0,0 +1,10 @@
+#File clitkMatrixToElastixTransform.ggo
+package "clitkMatrixToElastixTransform"
+version "1.0"
+purpose ""
+
+option "config"  - "Config file"             string optional
+option "verbose" v "Verbose"                 flag   off
+option "input"   i "Input matrix filename"   string required
+option "output"  o "Output elastix filename" string required
+option "center"  - "Rotation center"         float     no multiple(3)
index 42107987512a3c78686455c9e0f266ebb253b4e3..15e1d910c4163103205447bf5d35aebb8bb25d4b 100644 (file)
@@ -48,6 +48,7 @@ It is distributed under dual licence
 #include "vvSaveState.h"
 #include "vvReadState.h"
 #include "clitkConfiguration.h"
+#include "clitkMatrix.h"
 
 // ITK include
 #include <itkImage.h>
@@ -1145,7 +1146,7 @@ void vvMainWindow::ImageInfoChanged()
     infoPanel->setNPixel(QString::number(NPixel)+" ("+inputSizeInBytes+")");
 
     transformation = imageSelected->GetTransform()[tSlice]->GetMatrix();
-    infoPanel->setTransformation(Get4x4MatrixDoubleAsString(transformation));
+    infoPanel->setTransformation(clitk::Get4x4MatrixDoubleAsString(transformation).c_str());
 
     landmarksPanel->SetCurrentLandmarks(mSlicerManagers[index]->GetLandmarks(),
                                         mSlicerManagers[index]->GetTSlice());
@@ -1343,38 +1344,6 @@ QString vvMainWindow::GetSizeInBytes(unsigned long size)
 }
 //------------------------------------------------------------------------------
 
-//------------------------------------------------------------------------------
-QString vvMainWindow::Get4x4MatrixDoubleAsString(vtkSmartPointer<vtkMatrix4x4> matrix, const int precision)
-{
-  std::ostringstream strmatrix;
-
-  // Figure out the number of digits of the integer part of the largest absolute value
-  // for each column
-  unsigned width[4];
-  for (unsigned int j = 0; j < 4; j++){
-    double absmax = 0.;
-    for (unsigned int i = 0; i < 4; i++)
-      absmax = std::max(absmax, vnl_math_abs(matrix->GetElement(i, j)));
-    unsigned ndigits = (unsigned)std::max(0.,std::log10(absmax))+1;
-    width[j] = precision+ndigits+3;
-  }
-
-  // Output with correct width, aligned to the right
-  for (unsigned int i = 0; i < 4; i++) {
-    for (unsigned int j = 0; j < 4; j++) {
-      strmatrix.setf(ios::fixed,ios::floatfield);
-      strmatrix.precision(precision);
-      strmatrix.fill(' ');
-      strmatrix.width(width[j]);
-      strmatrix << std::right << matrix->GetElement(i, j);
-    }
-    strmatrix << std::endl;
-  }
-  QString result = strmatrix.str().c_str();
-  return result;
-}
-//------------------------------------------------------------------------------
-
 //------------------------------------------------------------------------------
 QString vvMainWindow::GetVectorDoubleAsString(std::vector<double> vectorDouble)
 {
index e5e315509b1924c2392358cc36c6fe80c4e14fa4..b093554d0a0b92018d352f1eb1236db1012b8be6 100644 (file)
@@ -69,7 +69,6 @@ class vvMainWindow: public vvMainWindowBase,
   void SaveCurrentStateAs(const std::string& stateFile);
   void ReadSavedStateFile(const std::string& stateFile);
        void LinkAllImages();
-  QString Get4x4MatrixDoubleAsString(vtkSmartPointer<vtkMatrix4x4> matrix, const int precision=3);
 
   virtual void UpdateCurrentSlicer();
   virtual QTabWidget * GetTab();
index 508551da86a7dec2ed064921e170439f2d6faeff..29481651e21aad16311963d9557ea74155e107a1 100644 (file)
@@ -30,6 +30,7 @@
 
 // clitk
 #include "clitkTransformUtilities.h"
+#include "clitkMatrix.h"
 
 // qt
 #include <QMessageBox>
@@ -120,7 +121,7 @@ void vvToolRigidReg::InputIsSelected(vvSlicerManager *input)
     for(int i=0; i<4; i++)
       // TODO SR and BP: check on the list of transforms and not the first only
       mInitialMatrix->SetElement(i,j, mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix()->GetElement(i,j));
-  QString origTransformString = dynamic_cast<vvMainWindow*>(mMainWindow)->Get4x4MatrixDoubleAsString(mInitialMatrix);
+  QString origTransformString(clitk::Get4x4MatrixDoubleAsString(mInitialMatrix).c_str());
   transformationLabel->setText(origTransformString);
   SetTransform(mInitialMatrix);
 
@@ -298,7 +299,7 @@ void vvToolRigidReg::SaveFile()
   if (file.open(QFile::WriteOnly | QFile::Truncate)) {
     // TODO SR and BP: check on the list of transforms and not the first only
     vtkMatrix4x4* matrix = mCurrentSlicerManager->GetImage()->GetTransform()[0]->GetMatrix();
-    QString matrixStr = dynamic_cast<vvMainWindow*>(mMainWindow)->Get4x4MatrixDoubleAsString(matrix,16);
+    QString matrixStr = clitk::Get4x4MatrixDoubleAsString(matrix,16).c_str();
     QTextStream out(&file);
     out << matrixStr;
   }