diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkPyramidImageRegistrationMethod.cpp b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkPyramidImageRegistrationMethod.cpp index ec983dad04..418a5a1bd7 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkPyramidImageRegistrationMethod.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkPyramidImageRegistrationMethod.cpp @@ -1,140 +1,180 @@ /*=================================================================== 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. ===================================================================*/ #include "mitkPyramidImageRegistrationMethod.h" #include "mitkException.h" #include "mitkImageAccessByItk.h" mitk::PyramidImageRegistrationMethod::PyramidImageRegistrationMethod() : m_FixedImage(NULL), m_MovingImage(NULL), m_CrossModalityRegistration(true), m_UseAffineTransform(true), m_UseWindowedSincInterpolator(false), + m_UseNearestNeighborInterpolator(false), + m_UseMask(false), m_EstimatedParameters(NULL), - m_Verbose(false) + m_Verbose(false), + m_InitializeByGeometry(false) { } mitk::PyramidImageRegistrationMethod::~PyramidImageRegistrationMethod() { if( m_EstimatedParameters != NULL) { delete [] m_EstimatedParameters; } } void mitk::PyramidImageRegistrationMethod::SetFixedImage(mitk::Image::Pointer fixed) { if( fixed.IsNotNull() ) { m_FixedImage = fixed; } } void mitk::PyramidImageRegistrationMethod::SetMovingImage(mitk::Image::Pointer moving) { if( moving.IsNotNull() ) { m_MovingImage = moving; } } + +void mitk::PyramidImageRegistrationMethod::SetFixedImageMask(mitk::Image::Pointer mask) +{ + m_FixedImageMask = mask; +} + void mitk::PyramidImageRegistrationMethod::Update() { if( m_MovingImage.IsNull() ) { mitkThrow() << " Moving image is null"; } if( m_FixedImage.IsNull() ) { mitkThrow() << " Moving image is null"; } unsigned int allowedDimension = 3; if( m_FixedImage->GetDimension() != allowedDimension || m_MovingImage->GetDimension() != allowedDimension ) { mitkThrow() << " Only 3D Images supported."; } // // One possibility: use the FixedDimesnionByItk, but this instantiates ALL possible // pixel type combinations! // AccessTwoImagesFixedDimensionByItk( m_FixedImage, m_MovingImage, RegisterTwoImages, 3); // in helper: TypeSubset : short, float AccessTwoImagesFixedDimensionTypeSubsetByItk( m_FixedImage, m_MovingImage, RegisterTwoImages, 3); } mitk::PyramidImageRegistrationMethod::TransformMatrixType mitk::PyramidImageRegistrationMethod ::GetLastRotationMatrix() { TransformMatrixType output; if( m_EstimatedParameters == NULL ) { output.set_identity(); return output; } typedef itk::MatrixOffsetTransformBase< double, 3, 3> BaseTransformType; BaseTransformType::Pointer base_transform = BaseTransformType::New(); if( this->m_UseAffineTransform ) { typedef itk::AffineTransform< double > TransformType; TransformType::Pointer transform = TransformType::New(); TransformType::ParametersType affine_params( TransformType::ParametersDimension ); this->GetParameters( &affine_params[0] ); transform->SetParameters( affine_params ); - base_transform = transform; } else { typedef itk::Euler3DTransform< double > RigidTransformType; RigidTransformType::Pointer rtransform = RigidTransformType::New(); RigidTransformType::ParametersType rigid_params( RigidTransformType::ParametersDimension ); this->GetParameters( &rigid_params[0] ); rtransform->SetParameters( rigid_params ); base_transform = rtransform; } return base_transform->GetMatrix().GetVnlMatrix(); } mitk::Image::Pointer mitk::PyramidImageRegistrationMethod ::GetResampledMovingImage() { mitk::Image::Pointer output = mitk::Image::New(); //output->Initialize( this->m_FixedImage ); AccessFixedDimensionByItk_1( this->m_MovingImage, ResampleMitkImage, 3, output ); return output; } + +mitk::Image::Pointer mitk::PyramidImageRegistrationMethod::GetResampledMovingImage(mitk::Image::Pointer movingImage, double* transform) +{ + mitk::Image::Pointer output = mitk::Image::New(); + + + unsigned int dim = 12; + if( !m_UseAffineTransform ) + dim = 6; + + if (m_EstimatedParameters == NULL) + m_EstimatedParameters = new double[dim]; + + double tmpParams[12]; + // save and set temporal transformation values + for( unsigned int i=0; i #include +#include "itkImageMaskSpatialObject.h" +#include "itkNotImageFilter.h" +#include #include #include "mitkImage.h" #include "mitkBaseProcess.h" #include "mitkPyramidRegistrationMethodHelper.h" #include #include "mitkImageToItk.h" +#include "mitkImageCast.h" +#include "mitkImageCaster.h" #include "mitkITKImageImport.h" +#include "mitkIOUtil.h" namespace mitk { /** * @brief The PyramidImageRegistration class implements a multi-scale registration method * * The PyramidImageRegistration class is suitable for aligning (f.e.) brain MR images. The method offers two * transform types * - Rigid: optimizing translation and rotation only and * - Affine ( default ): with scaling in addition ( 12 DOF ) * * The error metric is internally chosen based on the selected task type ( @sa SetCrossModalityOn ) * It uses * - MattesMutualInformation for CrossModality=on ( default ) and * - NormalizedCorrelation for CrossModality=off. */ class DiffusionCore_EXPORT PyramidImageRegistrationMethod : public itk::Object { public: /** Typedefs */ mitkClassMacro(PyramidImageRegistrationMethod, itk::Object) /** Smart pointer support */ itkNewMacro(Self) /** Typedef for the transformation matrix, corresponds to the InternalMatrixType from ITK transforms */ typedef vnl_matrix_fixed< double, 3, 3> TransformMatrixType; + typedef itk::AffineTransform< double > AffineTransformType; + typedef itk::Euler3DTransform< double > RigidTransformType; + /** Registration is between modalities - will take MattesMutualInformation as error metric */ void SetCrossModalityOn() { m_CrossModalityRegistration = true; } /** Registration is between modalities - will take NormalizedCorrelation as error metric */ void SetCrossModalityOff() { m_CrossModalityRegistration = false; } /** Turn the cross-modality on/off */ void SetCrossModality(bool flag) { if( flag ) this->SetCrossModalityOn(); else this->SetCrossModalityOff(); } /** Controll the verbosity of the registration output * * for true, each iteration step of the optimizer is watched and passed to the std::cout */ void SetVerbose(bool flag) { if( flag ) this->SetVerboseOn(); else this->SetVerboseOff(); } /** Turn verbosity on, \sa SetVerbose */ void SetVerboseOn() { m_Verbose = true; } /** Turn verbosity off, \sa SetVerbose */ void SetVerboseOff() { m_Verbose = false; } /** A rigid ( 6dof : translation + rotation ) transform is optimized */ void SetTransformToRigid() { m_UseAffineTransform = false; } /** An affine ( 12dof : Rigid + scale + skew ) transform is optimized */ void SetTransformToAffine() { m_UseAffineTransform = true; } /** Input image, the reference one */ void SetFixedImage( mitk::Image::Pointer ); /** Input image, the one to be transformed */ void SetMovingImage( mitk::Image::Pointer ); + /** Fixed image mask, excludes the masked voxels from the registration metric*/ + void SetFixedImageMask( mitk::Image::Pointer mask); + + + void SetInitializeByGeometry(bool flag) + { + m_InitializeByGeometry = flag; + } + void Update(); /** * @brief Get the number of parameters optimized ( 12 or 6 ) * * @return number of paramters */ unsigned int GetNumberOfParameters() { unsigned int retValue = 12; if(!m_UseAffineTransform) retValue = 6; return retValue; } /** * @brief Copies the estimated parameters to the given array * @param paramArray, target array for copy, make sure to allocate enough space */ void GetParameters( double* paramArray) { if( m_EstimatedParameters == NULL ) { mitkThrow() << "No parameters were estimated yet, call Update() first."; } unsigned int dim = 12; if( !m_UseAffineTransform ) dim = 6; for( unsigned int i=0; i * * It returns identity if the internal parameters are not-yet allocated ( i.e. the filter did not run yet ) * * @return \sa TransformMatrixType */ TransformMatrixType GetLastRotationMatrix(); protected: PyramidImageRegistrationMethod(); ~PyramidImageRegistrationMethod(); /** Fixed image, used as reference for registration */ mitk::Image::Pointer m_FixedImage; /** Moving image, will be transformed */ mitk::Image::Pointer m_MovingImage; + mitk::Image::Pointer m_FixedImageMask; + bool m_CrossModalityRegistration; bool m_UseAffineTransform; bool m_UseWindowedSincInterpolator; + bool m_UseNearestNeighborInterpolator; + + bool m_UseMask; + double* m_EstimatedParameters; /** Control the verbosity of the regsitistration output */ bool m_Verbose; + bool m_InitializeByGeometry; + template void RegisterTwoImages(itk::Image* itkImage1, itk::Image* itkImage2) { typedef typename itk::Image< TPixel1, VImageDimension1> FixedImageType; typedef typename itk::Image< TPixel2, VImageDimension2> MovingImageType; typedef typename itk::MultiResolutionImageRegistrationMethod< FixedImageType, MovingImageType > RegistrationType; typedef itk::RegularStepGradientDescentOptimizer OptimizerType; - typedef itk::AffineTransform< double > AffineTransformType; - typedef itk::Euler3DTransform< double > RigidTransformType; typedef itk::MatrixOffsetTransformBase< double, VImageDimension1, VImageDimension2 > BaseTransformType; typedef typename itk::MattesMutualInformationImageToImageMetric< FixedImageType, MovingImageType > MMIMetricType; typedef typename itk::NormalizedCorrelationImageToImageMetric< FixedImageType, MovingImageType > NCMetricType; typedef typename itk::ImageToImageMetric< FixedImageType, MovingImageType> BaseMetricType; typename itk::LinearInterpolateImageFunction::Pointer interpolator = itk::LinearInterpolateImageFunction::New(); typename BaseMetricType::Pointer metric; if( m_CrossModalityRegistration ) { metric = MMIMetricType::New(); } else { metric = NCMetricType::New(); } // initial parameter dimension ( affine = default ) unsigned int paramDim = 12; typename BaseTransformType::Pointer transform; if( m_UseAffineTransform ) { transform = AffineTransformType::New(); } else { transform = RigidTransformType::New(); paramDim = 6; } typename BaseTransformType::ParametersType initialParams(paramDim); initialParams.Fill(0); if( m_UseAffineTransform ) { initialParams[0] = initialParams[4] = initialParams[8] = 1; } - - typename FixedImageType::Pointer referenceImage = itkImage1; typename MovingImageType::Pointer movingImage = itkImage2; typename FixedImageType::RegionType maskedRegion = referenceImage->GetLargestPossibleRegion(); typename RegistrationType::Pointer registration = RegistrationType::New(); unsigned int max_pyramid_lvl = 3; unsigned int max_schedule_val = 4; typename FixedImageType::RegionType::SizeType image_size = referenceImage->GetLargestPossibleRegion().GetSize(); unsigned int min_value = std::min( image_size[0], std::min( image_size[1], image_size[2])); // condition for the top level pyramid image float optmaxstep = 6; float optminstep = 0.05f; unsigned int iterations = 100; if( min_value / max_schedule_val < 12 ) { max_schedule_val /= 2; optmaxstep *= 0.25f; optminstep *= 0.1f; } typename RegistrationType::ScheduleType fixedSchedule(max_pyramid_lvl,3); fixedSchedule.Fill(1); fixedSchedule[0][0] = max_schedule_val; fixedSchedule[0][1] = max_schedule_val; fixedSchedule[0][2] = max_schedule_val; for( unsigned int i=1; iSetScales( optScales ); optimizer->SetInitialPosition( initialParams ); optimizer->SetNumberOfIterations( iterations ); optimizer->SetGradientMagnitudeTolerance( 1e-4 ); optimizer->SetRelaxationFactor( 0.7 ); optimizer->SetMaximumStepLength( optmaxstep ); optimizer->SetMinimumStepLength( optminstep ); + // Initializing by Geometry + if (!m_UseAffineTransform && m_InitializeByGeometry) + { + typedef itk::CenteredVersorTransformInitializer< FixedImageType, MovingImageType> TransformInitializerType; + typename TransformInitializerType::TransformType::Pointer rigidTransform = TransformInitializerType::TransformType::New() ; + MITK_INFO << "Initializer starting at : " << rigidTransform->GetParameters(); + + typename TransformInitializerType::Pointer initializer = TransformInitializerType::New(); + initializer->SetTransform( rigidTransform); + initializer->SetFixedImage( referenceImage.GetPointer() ); + initializer->SetMovingImage( movingImage.GetPointer() ); + initializer->MomentsOn(); + initializer->InitializeTransform(); + MITK_INFO << "Initialized Rigid position : " << rigidTransform->GetParameters(); + initialParams[3]=rigidTransform->GetParameters()[3]; + initialParams[4]=rigidTransform->GetParameters()[4]; + initialParams[5]=rigidTransform->GetParameters()[5]; + } + // add observer tag if verbose */ unsigned long vopt_tag = 0; if(m_Verbose) { MITK_INFO << " :: Starting at " << initialParams; MITK_INFO << " :: Scales = " << optScales; OptimizerIterationCommand< OptimizerType >::Pointer iterationObserver = OptimizerIterationCommand::New(); vopt_tag = optimizer->AddObserver( itk::IterationEvent(), iterationObserver ); } // INPUT IMAGES registration->SetFixedImage( referenceImage ); registration->SetFixedImageRegion( maskedRegion ); registration->SetMovingImage( movingImage ); registration->SetSchedules( fixedSchedule, fixedSchedule); + // SET MASKED AREA + typedef itk::Image BinaryImageType; + BinaryImageType::Pointer itkFixedImageMask = BinaryImageType::New(); + itk::ImageMaskSpatialObject< 3 >::Pointer fixedMaskSpatialObject = itk::ImageMaskSpatialObject< 3 >::New(); + if (m_UseMask) + { + CastToItkImage(m_FixedImageMask,itkFixedImageMask); + itk::NotImageFilter::Pointer notFilter = itk::NotImageFilter::New(); + notFilter->SetInput(itkFixedImageMask); + notFilter->Update(); + fixedMaskSpatialObject->SetImage( notFilter->GetOutput() ); + metric->SetFixedImageMask( fixedMaskSpatialObject ); + } // OTHER INPUTS registration->SetMetric( metric ); registration->SetOptimizer( optimizer ); registration->SetTransform( transform.GetPointer() ); registration->SetInterpolator( interpolator ); registration->SetInitialTransformParameters( initialParams ); typename PyramidOptControlCommand::Pointer pyramid_observer = PyramidOptControlCommand::New(); registration->AddObserver( itk::IterationEvent(), pyramid_observer ); try { registration->Update(); } catch (itk::ExceptionObject &e) { MITK_ERROR << "[Registration Update] Caught ITK exception: "; mitkThrow() << "Registration failed with exception: " << e.what(); } if( m_EstimatedParameters != NULL) { delete [] m_EstimatedParameters; } m_EstimatedParameters = new double[paramDim]; typename BaseTransformType::ParametersType finalParameters = registration->GetLastTransformParameters(); for( unsigned int i=0; iRemoveObserver( vopt_tag ); } } template< typename TPixel, unsigned int VDimension> void ResampleMitkImage( itk::Image* itkImage, mitk::Image::Pointer& outputImage ) { typedef typename itk::Image< TPixel, VDimension> ImageType; typedef typename itk::ResampleImageFilter< ImageType, ImageType, double> ResampleImageFilterType; typedef itk::LinearInterpolateImageFunction< ImageType, double > InterpolatorType; typename InterpolatorType::Pointer linear_interpolator = InterpolatorType::New(); + + typedef itk::NearestNeighborInterpolateImageFunction< ImageType, double > NearestNeighborInterpolatorType; + typename NearestNeighborInterpolatorType::Pointer nn_interpolator = NearestNeighborInterpolatorType::New(); + + typedef itk::WindowedSincInterpolateImageFunction< ImageType, 7> WindowedSincInterpolatorType; typename WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New(); - typename mitk::ImageToItk< ImageType >::Pointer reference_image = mitk::ImageToItk< ImageType >::New(); - reference_image->SetInput( this->m_FixedImage ); - reference_image->Update(); + typename ImageType::Pointer reference_image = ImageType::New(); + CastToItkImage(m_FixedImage,reference_image); typedef itk::MatrixOffsetTransformBase< double, 3, 3> BaseTransformType; BaseTransformType::Pointer base_transform = BaseTransformType::New(); if( this->m_UseAffineTransform ) { - typedef itk::AffineTransform< double > TransformType; - TransformType::Pointer transform = TransformType::New(); + typedef itk::AffineTransform< double > TransformType; + TransformType::Pointer transform = TransformType::New(); - TransformType::ParametersType affine_params( TransformType::ParametersDimension ); - this->GetParameters( &affine_params[0] ); + TransformType::ParametersType affine_params( TransformType::ParametersDimension ); + this->GetParameters( &affine_params[0] ); - transform->SetParameters( affine_params ); + transform->SetParameters( affine_params ); - base_transform = transform; + base_transform = transform; } // Rigid else { - typedef itk::Euler3DTransform< double > RigidTransformType; - RigidTransformType::Pointer rtransform = RigidTransformType::New(); + typedef itk::Euler3DTransform< double > RigidTransformType; + RigidTransformType::Pointer rtransform = RigidTransformType::New(); - RigidTransformType::ParametersType rigid_params( RigidTransformType::ParametersDimension ); - this->GetParameters( &rigid_params[0] ); + RigidTransformType::ParametersType rigid_params( RigidTransformType::ParametersDimension ); + this->GetParameters( &rigid_params[0] ); - rtransform->SetParameters( rigid_params ); + rtransform->SetParameters( rigid_params ); - base_transform = rtransform; + base_transform = rtransform; } typename ResampleImageFilterType::Pointer resampler = ResampleImageFilterType::New(); + resampler->SetInterpolator( linear_interpolator ); if( m_UseWindowedSincInterpolator ) resampler->SetInterpolator( sinc_interpolator ); + if ( m_UseNearestNeighborInterpolator) + resampler->SetInterpolator ( nn_interpolator ); resampler->SetInput( itkImage ); resampler->SetTransform( base_transform ); - resampler->SetReferenceImage( reference_image->GetOutput() ); + resampler->SetReferenceImage( reference_image ); resampler->UseReferenceImageOn(); resampler->Update(); - mitk::GrabItkImageMemory( resampler->GetOutput(), outputImage); - } }; } // end namespace #endif // MITKPYRAMIDIMAGEREGISTRATION_H diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkPyramidRegistrationMethodHelper.h b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkPyramidRegistrationMethodHelper.h index 0fd024ad79..69b96e4475 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkPyramidRegistrationMethodHelper.h +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkPyramidRegistrationMethodHelper.h @@ -1,122 +1,122 @@ /*=================================================================== 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 MITKPYRAMIDREGISTRATIONMETHODHELPER_H #define MITKPYRAMIDREGISTRATIONMETHODHELPER_H #include #include #include #include #include #include #include #include #include #include "mitkImageAccessByItk.h" /** * @brief Provides same functionality as \a AccessTwoImagesFixedDimensionByItk for a subset of types * * For now, the subset defined is only short and float. */ #define AccessTwoImagesFixedDimensionTypeSubsetByItk(mitkImage1, mitkImage2, itkImageTypeFunction, dimension) \ { \ const mitk::PixelType& pixelType1 = mitkImage1->GetPixelType(); \ const mitk::PixelType& pixelType2 = mitkImage2->GetPixelType(); \ const mitk::Image* constImage1 = mitkImage1; \ const mitk::Image* constImage2 = mitkImage2; \ mitk::Image* nonConstImage1 = const_cast(constImage1); \ mitk::Image* nonConstImage2 = const_cast(constImage2); \ nonConstImage1->Update(); \ nonConstImage2->Update(); \ _checkSpecificDimension(mitkImage1, (dimension)); \ _checkSpecificDimension(mitkImage2, (dimension)); \ - _accessTwoImagesByItkForEach(itkImageTypeFunction, ((short, dimension))((float, dimension)), ((short, dimension))((float, dimension)) ) \ + _accessTwoImagesByItkForEach(itkImageTypeFunction, ((short, dimension))((unsigned short, dimension))((float, dimension))((double, dimension)), ((short, dimension))((unsigned short, dimension))((float, dimension))((double, dimension)) ) \ { \ std::string msg("Pixel type "); \ msg.append(pixelType1.GetComponentTypeAsString() ); \ msg.append(" or pixel type "); \ msg.append(pixelType2.GetComponentTypeAsString() ); \ msg.append(" is not in " MITK_PP_STRINGIZE(MITK_ACCESSBYITK_TYPES_DIMN_SEQ(dimension))); \ throw mitk::AccessByItkException(msg); \ } \ } /** * @brief The PyramidOptControlCommand class stears the step lenght of the * gradient descent optimizer in multi-scale registration methods */ template class PyramidOptControlCommand : public itk::Command { public: typedef itk::RegularStepGradientDescentOptimizer OptimizerType; itkNewMacro( PyramidOptControlCommand ) void Execute(itk::Object *caller, const itk::EventObject & /*event*/) { RegistrationType* registration = dynamic_cast< RegistrationType* >( caller ); MITK_DEBUG << "\t - Pyramid level " << registration->GetCurrentLevel(); if( registration->GetCurrentLevel() == 0 ) return; OptimizerType* optimizer = dynamic_cast< OptimizerType* >(registration->GetOptimizer()); MITK_INFO << optimizer->GetStopConditionDescription() << "\n" << optimizer->GetValue() << " : " << optimizer->GetCurrentPosition(); optimizer->SetMaximumStepLength( optimizer->GetMaximumStepLength() * 0.25f ); optimizer->SetMinimumStepLength( optimizer->GetMinimumStepLength() * 0.1f ); // optimizer->SetNumberOfIterations( optimizer->GetNumberOfIterations() * 1.5f ); } void Execute(const itk::Object * /*object*/, const itk::EventObject & /*event*/){} }; template class OptimizerIterationCommand : public itk::Command { public: itkNewMacro( OptimizerIterationCommand ) void Execute(itk::Object *caller, const itk::EventObject & event) { OptimizerType* optimizer = dynamic_cast< OptimizerType* >( caller ); unsigned int currentIter = optimizer->GetCurrentIteration(); MITK_INFO << "[" << currentIter << "] : " << optimizer->GetValue() << " : " << optimizer->GetCurrentPosition(); } void Execute(const itk::Object * object, const itk::EventObject & event) { } }; #endif // MITKPYRAMIDREGISTRATIONMETHODHELPER_H diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkRegistrationWrapper.cpp b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkRegistrationWrapper.cpp new file mode 100644 index 0000000000..259c2c85f6 --- /dev/null +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkRegistrationWrapper.cpp @@ -0,0 +1,163 @@ +#include "mitkRegistrationWrapper.h" + +#include "mitkPyramidImageRegistrationMethod.h" +#include "mitkDiffusionImage.h" +#include +#include "itkB0ImageExtractionImageFilter.h" + +#include + + +mitk::RegistrationWrapper::RegistrationWrapper() +{ +} + +void mitk::RegistrationWrapper::ApplyTransformationToImage(mitk::Image::Pointer &img, const mitk::RegistrationWrapper::RidgidTransformType &transformation,double* offset, mitk::Image::Pointer resampleReference, bool binary) const +{ + typedef mitk::DiffusionImage DiffusionImageType; + + mitk::Image::Pointer ref; + mitk::PyramidImageRegistrationMethod::Pointer registrationMethod = mitk::PyramidImageRegistrationMethod::New(); + registrationMethod->SetTransformToRigid(); + if (binary) + registrationMethod->SetUseNearestNeighborInterpolation(true); + + if (resampleReference.IsNotNull()) + { + registrationMethod->SetFixedImage( resampleReference ); + } + else + { + // clone image, to prevent recursive access on resampling .. + ref = img->Clone(); + registrationMethod->SetFixedImage( ref ); + } + + if (dynamic_cast (img.GetPointer()) == NULL) + { + itk::Image::Pointer itkImage = itk::Image::New(); + CastToItkImage(img, itkImage); + + typedef itk::Euler3DTransform< double > RigidTransformType; + RigidTransformType::Pointer rtransform = RigidTransformType::New(); + RigidTransformType::ParametersType parameters(RigidTransformType::ParametersDimension); + + for (int i = 0; i<6;++i) + parameters[i] = transformation[i]; + + rtransform->SetParameters( parameters ); + + mitk::Point3D origin = itkImage->GetOrigin(); + origin[0]-=offset[0]; + origin[1]-=offset[1]; + origin[2]-=offset[2]; + + mitk::Point3D newOrigin = rtransform->GetInverseTransform()->TransformPoint(origin); + + itk::Matrix dir = itkImage->GetDirection(); + itk::Matrix transM ( vnl_inverse(rtransform->GetMatrix().GetVnlMatrix())); + itk::Matrix newDirection = transM * dir; + + itkImage->SetOrigin(newOrigin); + itkImage->SetDirection(newDirection); + GrabItkImageMemory(itkImage, img); + + } + else + { + DiffusionImageType::Pointer diffImages = dynamic_cast(img.GetPointer()); + + typedef itk::Euler3DTransform< double > RigidTransformType; + RigidTransformType::Pointer rtransform = RigidTransformType::New(); + RigidTransformType::ParametersType parameters(RigidTransformType::ParametersDimension); + + for (int i = 0; i<6;++i) + { + parameters[i] = transformation[i]; + } + + rtransform->SetParameters( parameters ); + + mitk::Point3D b0origin = diffImages->GetVectorImage()->GetOrigin(); + b0origin[0]-=offset[0]; + b0origin[1]-=offset[1]; + b0origin[2]-=offset[2]; + + mitk::Point3D newOrigin = rtransform->GetInverseTransform()->TransformPoint(b0origin); + + itk::Matrix dir = diffImages->GetVectorImage()->GetDirection(); + itk::Matrix transM ( vnl_inverse(rtransform->GetMatrix().GetVnlMatrix())); + itk::Matrix newDirection = transM * dir; + + diffImages->GetVectorImage()->SetOrigin(newOrigin); + diffImages->GetVectorImage()->SetDirection(newDirection); + diffImages->Modified(); + + mitk::DiffusionImageCorrectionFilter::Pointer correctionFilter = mitk::DiffusionImageCorrectionFilter::New(); + + // For Diff. Images: Need to rotate the gradients (works in-place) + correctionFilter->SetImage(diffImages); + correctionFilter->CorrectDirections(transM.GetVnlMatrix()); + img = diffImages; + } +} + +void mitk::RegistrationWrapper::GetTransformation(mitk::Image::Pointer fixedImage, mitk::Image::Pointer movingImage, RidgidTransformType transformation,double* offset, mitk::Image::Pointer mask) +{ + // Handle the case that fixed/moving image is a DWI image + mitk::DiffusionImage* fixedDwi = dynamic_cast*> (fixedImage.GetPointer()); + mitk::DiffusionImage* movingDwi = dynamic_cast*> (movingImage.GetPointer()); + itk::B0ImageExtractionImageFilter::Pointer b0Extraction = itk::B0ImageExtractionImageFilter::New(); + offset[0]=offset[1]=offset[2]=0; + if (fixedDwi != NULL) + { // Set b0 extraction as fixed image + b0Extraction->SetInput(fixedDwi->GetVectorImage()); + b0Extraction->SetDirections(fixedDwi->GetDirections()); + b0Extraction->Update(); + mitk::Image::Pointer tmp = mitk::Image::New(); + tmp->InitializeByItk(b0Extraction->GetOutput()); + tmp->SetVolume(b0Extraction->GetOutput()->GetBufferPointer()); + fixedImage = tmp; + } + if (movingDwi != NULL) + { // Set b0 extraction as moving image + b0Extraction->SetInput(movingDwi->GetVectorImage()); + b0Extraction->SetDirections(movingDwi->GetDirections()); + b0Extraction->Update(); + mitk::Image::Pointer tmp = mitk::Image::New(); + tmp->InitializeByItk(b0Extraction->GetOutput()); + tmp->SetVolume(b0Extraction->GetOutput()->GetBufferPointer()); + movingImage = tmp; + } + + // align the offsets of the two images. this is done to avoid non-overlapping initialization + Point3D origin = fixedImage->GetGeometry()->GetOrigin(); + Point3D originMoving = movingImage->GetGeometry()->GetOrigin(); + + offset[0] = originMoving[0]-origin[0]; + offset[1] = originMoving[1]-origin[1]; + offset[2] = originMoving[2]-origin[2]; + + mitk::Image::Pointer tmpImage = movingImage->Clone(); + tmpImage->GetGeometry()->SetOrigin(origin); + // Start registration + mitk::PyramidImageRegistrationMethod::Pointer registrationMethod = mitk::PyramidImageRegistrationMethod::New(); + registrationMethod->SetFixedImage( fixedImage ); + + if (mask.IsNotNull()) + { + registrationMethod->SetFixedImageMask(mask); + registrationMethod->SetUseFixedImageMask(true); + } + else + { + registrationMethod->SetUseFixedImageMask(false); + } + + registrationMethod->SetTransformToRigid(); + registrationMethod->SetCrossModalityOn(); + + registrationMethod->SetMovingImage(tmpImage); + registrationMethod->Update(); + registrationMethod->GetParameters(transformation); // first three: euler angles, last three translation +} diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkRegistrationWrapper.h b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkRegistrationWrapper.h new file mode 100644 index 0000000000..9eb02d2c2d --- /dev/null +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkRegistrationWrapper.h @@ -0,0 +1,80 @@ +#ifndef MITKBATCHEDREGISTRATION_H +#define MITKBATCHEDREGISTRATION_H + +// ITK +#include +// MITK +#include +#include "mitkCommon.h" +#include "mitkImage.h" + + +namespace mitk +{ +/** + * @brief The RegistrationWrapper class wraps the pyramid registration to calculate and apply a reference transformation to several images. + * + * Use if several pictures with the same world geometry are to be registered + * to one reference image, the registration is only computed once (for the moving image) and the geometry can be transformed for the complete + * image batch accordingly. Can handle image types that are usually not supported by registrations filters, e.g. fiber bundles and segmentations: + * these can be registered if a "registerable" image such as B0/T2 from which they are derived is supplied, since the transformation can be calculated + * on those and applied to the derived objects. + * + * For DWI images a registerable B0 Image will automatically be extracted. + * + */ +class DiffusionCore_EXPORT RegistrationWrapper : public itk::LightObject +{ +public: + + typedef double* RidgidTransformType; + + mitkClassMacro(RegistrationWrapper, itk::LightObject) + itkNewMacro(Self) + + /** + * @brief ApplyTransformationToImage Applies transformation from GetTransformation to provided image. + * + * Transforms image according to previously calculated transformation. Can be applied to derived resources also (e.g. binary images). + * Handles DWI Data and rotates the gradients according to the transformation. + * Images are resampled to provided reference, if no reference it supplied a copy of the input image is used as reference. + * + * @param img - image on which the transformation is to be applied + * @param transformation - transformation returned from GetTransformation + * @param offset - offset transformation returned from GetTransformation + * @param resampleReference - image to which is to be resampled + * @param binary + */ + void ApplyTransformationToImage(mitk::Image::Pointer& img, const RidgidTransformType& transformation, double *offset, mitk::Image::Pointer resampleReference = NULL , bool binary = false) const; + + /** + * @brief GetTransformation Registeres the moving to the fixed image and returns the according transformation + * + * \note Does not return a registered image \see ApplyTransformationToImage for this. + * + * Both images are set to the same origin (the one of the fixed image), this is supposed to ensure overlapping, + * the correction of the moving image is returned in the offset. + * + * It is possible mask a certain area and thereby excluding it from the registration metric (e.g. a tumor that is operated on), + * this can be set as mitk::Image where all non-zero voxels are excluded. + * + * @param fixedImage + * @param movingImage + * @param transformation + * @param offset - stores offset that has been applied to match origin of both images + * @param mask - optional, provide a mask that is excluded from registration metric + */ + void GetTransformation(mitk::Image::Pointer fixedImage , mitk::Image::Pointer movingImage, RidgidTransformType transformation, double* offset, mitk::Image::Pointer mask = NULL); + + +protected: + RegistrationWrapper(); + ~RegistrationWrapper(){}; + +private: + RegistrationWrapper(const Self &); //purposely not implemented + void operator=(const Self &); //purposely not implemented +}; + +} +#endif // MITKBATCHEDREGISTRATION_H diff --git a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.cpp b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.cpp index 42112e7b0f..9d7a553c3d 100644 --- a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.cpp @@ -1,101 +1,117 @@ /*=================================================================== 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! "; } GradientDirectionContainerPointerType directions = m_SourceImage->GetDirections(); GradientDirectionContainerPointerType corrected_directions = GradientDirectionContainerType::New(); 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 ); } +template< typename TPixelType > +void mitk::DiffusionImageCorrectionFilter +::CorrectDirections( const TransformMatrixType& transformation) +{ + if( m_SourceImage.IsNull() ) + { + mitkThrow() << " No diffusion image given! "; + } + TransformsVectorType transfVec; + for (int i=0; i< m_SourceImage->GetDirections()->Size();i++) + { + transfVec.push_back(transformation); + } + this->CorrectDirections(transfVec); +} + #endif diff --git a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.h b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.h index 159cd5321b..7d6c3b3e59 100644 --- a/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.h +++ b/Modules/DiffusionImaging/DiffusionCore/IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.h @@ -1,90 +1,97 @@ /*=================================================================== 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 > GradientDirectionContainerType; typedef GradientDirectionContainerType::Pointer GradientDirectionContainerPointerType; 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& ); + /** + * @brief Correct all gradient directions according to the given transform + * + * This will apply the same rotation to all directions. + */ + void CorrectDirections( const TransformMatrixType& ); + 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.cpp" #endif // MITKDIFFUSIONIMAGECORRECTIONFILTER_H diff --git a/Modules/DiffusionImaging/DiffusionCore/files.cmake b/Modules/DiffusionImaging/DiffusionCore/files.cmake index 2264c3f07b..fae94626db 100644 --- a/Modules/DiffusionImaging/DiffusionCore/files.cmake +++ b/Modules/DiffusionImaging/DiffusionCore/files.cmake @@ -1,147 +1,146 @@ set(CPP_FILES # DicomImport DicomImport/mitkDicomDiffusionImageReader.cpp # DicomImport/mitkGroupDiffusionHeadersFilter.cpp DicomImport/mitkDicomDiffusionImageHeaderReader.cpp DicomImport/mitkGEDicomDiffusionImageHeaderReader.cpp DicomImport/mitkPhilipsDicomDiffusionImageHeaderReader.cpp DicomImport/mitkSiemensDicomDiffusionImageHeaderReader.cpp DicomImport/mitkSiemensMosaicDicomDiffusionImageHeaderReader.cpp # DataStructures IODataStructures/mitkDiffusionCoreObjectFactory.cpp # DataStructures -> DWI IODataStructures/DiffusionWeightedImages/mitkDiffusionImageHeaderInformation.cpp IODataStructures/DiffusionWeightedImages/mitkDiffusionImageSource.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageReader.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageWriter.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageIOFactory.cpp IODataStructures/DiffusionWeightedImages/mitkNrrdDiffusionImageWriterFactory.cpp IODataStructures/DiffusionWeightedImages/mitkDiffusionImageSerializer.cpp IODataStructures/DiffusionWeightedImages/mitkImageToDiffusionImageSource.cpp IODataStructures/DiffusionWeightedImages/mitkDiffusionImageCorrectionFilter.cpp # DataStructures -> QBall IODataStructures/QBallImages/mitkQBallImageSource.cpp IODataStructures/QBallImages/mitkNrrdQBallImageReader.cpp IODataStructures/QBallImages/mitkNrrdQBallImageWriter.cpp IODataStructures/QBallImages/mitkNrrdQBallImageIOFactory.cpp IODataStructures/QBallImages/mitkNrrdQBallImageWriterFactory.cpp IODataStructures/QBallImages/mitkQBallImage.cpp IODataStructures/QBallImages/mitkQBallImageSerializer.cpp # DataStructures -> Tensor IODataStructures/TensorImages/mitkTensorImageSource.cpp IODataStructures/TensorImages/mitkNrrdTensorImageReader.cpp IODataStructures/TensorImages/mitkNrrdTensorImageWriter.cpp IODataStructures/TensorImages/mitkNrrdTensorImageIOFactory.cpp IODataStructures/TensorImages/mitkNrrdTensorImageWriterFactory.cpp IODataStructures/TensorImages/mitkTensorImage.cpp IODataStructures/TensorImages/mitkTensorImageSerializer.cpp #IODataStructures/mitkRegistrationObject.cpp # Rendering Rendering/vtkMaskedProgrammableGlyphFilter.cpp Rendering/mitkCompositeMapper.cpp Rendering/mitkVectorImageVtkGlyphMapper3D.cpp Rendering/vtkOdfSource.cxx Rendering/vtkThickPlane.cxx Rendering/mitkOdfNormalizationMethodProperty.cpp Rendering/mitkOdfScaleByProperty.cpp Rendering/mitkPlanarFigureMapper3D.cpp # Algorithms Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.cpp Algorithms/mitkPartialVolumeAnalysisClusteringCalculator.cpp Algorithms/itkDwiGradientLengthCorrectionFilter.cpp - - # Registration Algorithms & Co. + Algorithms/Registration/mitkRegistrationWrapper.cpp Algorithms/Registration/mitkPyramidImageRegistrationMethod.cpp # MultishellProcessing Algorithms/Reconstruction/MultishellProcessing/itkADCAverageFunctor.cpp Algorithms/Reconstruction/MultishellProcessing/itkADCFitFunctor.cpp Algorithms/Reconstruction/MultishellProcessing/itkKurtosisFitFunctor.cpp Algorithms/Reconstruction/MultishellProcessing/itkBiExpFitFunctor.cpp # Function Collection mitkDiffusionFunctionCollection.cpp ) set(H_FILES # function Collection mitkDiffusionFunctionCollection.h # Rendering Rendering/mitkDiffusionImageMapper.h Rendering/mitkOdfVtkMapper2D.h Rendering/mitkPlanarFigureMapper3D.h # Reconstruction Algorithms/Reconstruction/itkDiffusionQballReconstructionImageFilter.h Algorithms/Reconstruction/mitkTeemDiffusionTensor3DReconstructionImageFilter.h Algorithms/Reconstruction/itkAnalyticalDiffusionQballReconstructionImageFilter.h Algorithms/Reconstruction/itkDiffusionMultiShellQballReconstructionImageFilter.h Algorithms/Reconstruction/itkPointShell.h Algorithms/Reconstruction/itkOrientationDistributionFunction.h Algorithms/Reconstruction/itkDiffusionIntravoxelIncoherentMotionReconstructionImageFilter.h # MultishellProcessing Algorithms/Reconstruction/MultishellProcessing/itkRadialMultishellToSingleshellImageFilter.h Algorithms/Reconstruction/MultishellProcessing/itkDWIVoxelFunctor.h Algorithms/Reconstruction/MultishellProcessing/itkADCAverageFunctor.h Algorithms/Reconstruction/MultishellProcessing/itkKurtosisFitFunctor.h Algorithms/Reconstruction/MultishellProcessing/itkBiExpFitFunctor.h Algorithms/Reconstruction/MultishellProcessing/itkADCFitFunctor.h # IO Datastructures IODataStructures/DiffusionWeightedImages/mitkDiffusionImage.h # Algorithms Algorithms/itkDiffusionQballGeneralizedFaImageFilter.h Algorithms/itkDiffusionQballPrepareVisualizationImageFilter.h Algorithms/itkTensorDerivedMeasurementsFilter.h Algorithms/itkBrainMaskExtractionImageFilter.h Algorithms/itkB0ImageExtractionImageFilter.h Algorithms/itkB0ImageExtractionToSeparateImageFilter.h Algorithms/itkTensorImageToDiffusionImageFilter.h Algorithms/itkTensorToL2NormImageFilter.h Algorithms/itkGaussianInterpolateImageFunction.h Algorithms/mitkPartialVolumeAnalysisHistogramCalculator.h Algorithms/mitkPartialVolumeAnalysisClusteringCalculator.h Algorithms/itkDiffusionTensorPrincipalDirectionImageFilter.h Algorithms/itkCartesianToPolarVectorImageFilter.h Algorithms/itkPolarToCartesianVectorImageFilter.h Algorithms/itkDistanceMapFilter.h Algorithms/itkProjectionFilter.h Algorithms/itkResidualImageFilter.h Algorithms/itkExtractChannelFromRgbaImageFilter.h Algorithms/itkTensorReconstructionWithEigenvalueCorrectionFilter.h Algorithms/itkMergeDiffusionImagesFilter.h Algorithms/itkDwiPhantomGenerationFilter.h Algorithms/itkFiniteDiffOdfMaximaExtractionFilter.h Algorithms/itkMrtrixPeakImageConverter.h Algorithms/itkFslPeakImageConverter.h Algorithms/itkShCoefficientImageImporter.h Algorithms/itkOdfMaximaExtractionFilter.h Algorithms/itkResampleDwiImageFilter.h Algorithms/itkDwiGradientLengthCorrectionFilter.h Algorithms/itkAdcImageFilter.h Algorithms/itkSplitDWImageFilter.h Algorithms/Registration/mitkDWIHeadMotionCorrectionFilter.h Algorithms/mitkDiffusionImageToDiffusionImageFilter.h ) set( TOOL_FILES )