diff --git a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.cpp b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.cpp index 7a5b2e1aca..4478583fa5 100644 --- a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.cpp @@ -1,36 +1,100 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKDIFFUSIONIMAGECORRECTIONFILTER_CPP #define MITKDIFFUSIONIMAGECORRECTIONFILTER_CPP #include "mitkDiffusionImageCorrectionFilter.h" +#include +#include + template< typename TPixelType > mitk::DiffusionImageCorrectionFilter::DiffusionImageCorrectionFilter() { } +template< typename TPixelType > +typename mitk::DiffusionImageCorrectionFilter::TransformMatrixType +mitk::DiffusionImageCorrectionFilter +::GetRotationComponent(const TransformMatrixType &A) +{ + TransformMatrixType B; + + B = A * A.transpose(); + + // get the eigenvalues and eigenvectors + typedef double MType; + vnl_vector< MType > eigvals; + vnl_matrix< MType > eigvecs; + vnl_symmetric_eigensystem_compute< MType > ( B, eigvecs, eigvals ); + + vnl_matrix_fixed< MType, 3, 3 > eigvecs_fixed; + eigvecs_fixed.set_columns(0, eigvecs ); + + TransformMatrixType C; + C.set_identity(); + + vnl_vector_fixed< MType, 3 > eigvals_sqrt; + for(unsigned int i=0; i<3; i++) + { + C(i,i) = std::sqrt( eigvals[i] ); + } + + TransformMatrixType S = vnl_inverse( eigvecs_fixed * C * vnl_inverse( eigvecs_fixed )) * A; + + return S; +} + template< typename TPixelType > void mitk::DiffusionImageCorrectionFilter ::CorrectDirections( const TransformsVectorType& transformations) { + if( m_SourceImage.IsNull() ) + { + mitkThrow() << " No diffusion image given! "; + } + + GradientDirectionContainerType directions = m_SourceImage->GetDirections(); + GradientDirectionContainerType corrected_directions; + + unsigned int transformed = 0; + for(size_t i=0; i< directions->Size(); i++ ) + { + + // skip b-zero images + if( directions->ElementAt(i).one_norm() <= 0.0 ) + { + corrected_directions->push_back( directions->ElementAt(i) ); + continue; + } + + GradientDirectionType corrected = GetRotationComponent( + transformations.at(transformed)) + * directions->ElementAt(i); + // store the corrected direction + corrected_directions->push_back( corrected ); + transformed++; + } + + // replace the old directions with the corrected ones + m_SourceImage->SetDirections( corrected_directions ); } #endif diff --git a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.h b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.h index 81645eb02a..c7608f93f9 100644 --- a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.h +++ b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.h @@ -1,77 +1,89 @@ /*=================================================================== The Medical Imaging Interaction Toolkit (MITK) Copyright (c) German Cancer Research Center, Division of Medical and Biological Informatics. All rights reserved. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See LICENSE.txt or http://www.mitk.org for details. ===================================================================*/ #ifndef MITKDIFFUSIONIMAGECORRECTIONFILTER_H #define MITKDIFFUSIONIMAGECORRECTIONFILTER_H #include "mitkDiffusionImageSource.h" namespace mitk { /** * @class DiffusionImageCorrectionFilter */ template< typename TPixelType > class DiffusionImageCorrectionFilter : public DiffusionImageSource< TPixelType > { public: /** class macros */ mitkClassMacro( DiffusionImageCorrectionFilter, DiffusionImageSource ) itkSimpleNewMacro(Self) typedef vnl_vector_fixed< double, 3 > GradientDirectionType; typedef vnl_matrix_fixed< double, 3, 3 > TransformMatrixType; typedef itk::VectorContainer< unsigned int, GradientDirectionType >::Pointer GradientDirectionContainerType; typedef std::vector< TransformMatrixType > TransformsVectorType; typedef typename Superclass::OutputType DiffusionImageType; typedef typename DiffusionImageType::Pointer DiffusionImageTypePointer; typedef itk::VectorImage ImageType; /** * @brief Set the mitk image ( a 3d+t image ) which is to be reinterpreted as dw image * @param mitkImage */ void SetImage( DiffusionImageTypePointer input ) { m_SourceImage = input; } /** * @brief Correct each gradient direction according to the given transform * * The size of the input is expected to correspond to the count of gradient images in the image. */ void CorrectDirections( const TransformsVectorType& ); protected: DiffusionImageCorrectionFilter(); virtual ~DiffusionImageCorrectionFilter() {} + /** + * @brief Get the rotation component following the Finite Strain + * + * For a given transformation \f$A\f$ its rotation component is defined as \f$ (AA^{T})^{-1/2}\f$. + * + * The computation first computes \f$ B = AA^T \f$ and then estimates the square root. Square root of + * diagonal matrices is defined as + * \f$ S = Q * \sqrt{C} * Q^{-1} \f$ with \f$ C \f$ having the eigenvalues on the diagonal. + * + */ + TransformMatrixType GetRotationComponent( const TransformMatrixType& ); + DiffusionImageTypePointer m_SourceImage; }; } -#include "mitkDiffusionImageCorrectionFilter.h" +#include "mitkDiffusionImageCorrectionFilter.cpp" #endif // MITKDIFFUSIONIMAGECORRECTIONFILTER_H