diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkRegistrationWrapper.cpp b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkRegistrationWrapper.cpp index 2819afa622..c992d4b417 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkRegistrationWrapper.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkRegistrationWrapper.cpp @@ -1,183 +1,183 @@ #include "mitkRegistrationWrapper.h" #include "mitkPyramidImageRegistrationMethod.h" #include "mitkDiffusionImage.h" #include #include "itkB0ImageExtractionImageFilter.h" #include #include #include #include void mitk::RegistrationWrapper::ApplyTransformationToImage(mitk::Image::Pointer img, const mitk::RegistrationWrapper::RidgidTransformType &transformation,double* offset, mitk::Image* resampleReference, bool binary) { typedef mitk::DiffusionImage DiffusionImageType; if (dynamic_cast (img.GetPointer()) == NULL) { ItkImageType::Pointer itkImage = ItkImageType::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); // Perform Resampling if reference image is provided if (resampleReference != NULL) { typedef itk::ResampleImageFilter ResampleFilterType; ItkImageType::Pointer itkReference = ItkImageType::New(); CastToItkImage(resampleReference,itkReference); typedef itk::WindowedSincInterpolateImageFunction< ItkImageType, 3> WindowedSincInterpolatorType; WindowedSincInterpolatorType::Pointer sinc_interpolator = WindowedSincInterpolatorType::New(); typedef itk::NearestNeighborInterpolateImageFunction< ItkImageType, double > NearestNeighborInterpolatorType; NearestNeighborInterpolatorType::Pointer nn_interpolator = NearestNeighborInterpolatorType::New(); ResampleFilterType::Pointer resampler = ResampleFilterType::New(); resampler->SetInput(itkImage); resampler->SetReferenceImage( itkReference ); resampler->UseReferenceImageOn(); if (binary) resampler->SetInterpolator(nn_interpolator); else resampler->SetInterpolator(sinc_interpolator); resampler->Update(); GrabItkImageMemory(resampler->GetOutput(), img); } else { // !! CastToItk behaves very differently depending on the original data type // if the target type is the same as the original, only a pointer to the data is set // and an additional GrabItkImageMemory will cause a segfault when the image is destroyed // GrabItkImageMemory - is not necessary in this case since we worked on the original data // See Bug 17538. if (img->GetPixelType().GetComponentTypeAsString() != "double") img = GrabItkImageMemory(itkImage); } } 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* fixedImage, mitk::Image* movingImage, RidgidTransformType transformation,double* offset, mitk::Image* mask) +void mitk::RegistrationWrapper::GetTransformation(mitk::Image::Pointer fixedImage, mitk::Image::Pointer movingImage, RidgidTransformType transformation,double* offset, mitk::Image* mask) { // Handle the case that fixed/moving image is a DWI image - mitk::DiffusionImage* fixedDwi = dynamic_cast*> (fixedImage); - mitk::DiffusionImage* movingDwi = dynamic_cast*> (movingImage); + 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 != NULL) { 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 index 894c0117e2..2a12b5416e 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkRegistrationWrapper.h +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkRegistrationWrapper.h @@ -1,69 +1,69 @@ #ifndef MITKBATCHEDREGISTRATION_H #define MITKBATCHEDREGISTRATION_H // 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 MitkDiffusionCore_EXPORT RegistrationWrapper { public: typedef itk::Image ItkImageType; typedef itk::Image ItkBinaryImageType; typedef double* RidgidTransformType; /** * @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 */ static void ApplyTransformationToImage(mitk::Image::Pointer img, const RidgidTransformType& transformation, double *offset, mitk::Image* resampleReference = NULL , bool binary = false); /** * @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 */ - static void GetTransformation(mitk::Image* fixedImage , mitk::Image* movingImage, RidgidTransformType transformation, double* offset, mitk::Image* mask = NULL); + static void GetTransformation(Image::Pointer fixedImage , Image::Pointer movingImage, RidgidTransformType transformation, double* offset, mitk::Image* mask = NULL); }; } #endif // MITKBATCHEDREGISTRATION_H