diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp index 379eaf622c..f51c11d3ff 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp @@ -1,166 +1,160 @@ #include "mitkBatchedRegistration.h" #include "mitkPyramidImageRegistrationMethod.h" #include "mitkDiffusionImage.h" -#include +//#include #include #include "itkB0ImageExtractionImageFilter.h" -#include #include -// VTK -#include -// DEBUG -#include - -mitk::BatchedRegistration::BatchedRegistration() +mitk::RegistrationWrapper::RegistrationWrapper() { } -void mitk::BatchedRegistration::ApplyTransformationToImage(mitk::Image::Pointer &img, const mitk::BatchedRegistration::RidgidTransformType &transformation,double* offset, mitk::Image::Pointer resampleReference, bool binary) const +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::BatchedRegistration::GetTransformation(mitk::Image::Pointer fixedImage, mitk::Image::Pointer movingImage, RidgidTransformType transformation,double* offset, mitk::Image::Pointer mask) +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]; movingImage->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(movingImage); registrationMethod->Update(); registrationMethod->GetParameters(transformation); // first three: euler angles, last three translation } diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.h b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.h index c6294e5b2e..85e92a21ae 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.h +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.h @@ -1,49 +1,66 @@ #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(BatchedRegistration, itk::LightObject) + mitkClassMacro(RegistrationWrapper, itk::LightObject) itkNewMacro(Self) 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 - + * @param mask + */ 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