diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp index db5f5cdd9a..379eaf622c 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp @@ -1,212 +1,166 @@ #include "mitkBatchedRegistration.h" #include "mitkPyramidImageRegistrationMethod.h" #include "mitkDiffusionImage.h" #include #include #include "itkB0ImageExtractionImageFilter.h" #include #include // VTK #include // DEBUG #include -mitk::BatchedRegistration::BatchedRegistration() : - m_RegisteredImagesValid(false) +mitk::BatchedRegistration::BatchedRegistration() { } -void mitk::BatchedRegistration::SetFixedImage(mitk::Image::Pointer& fixedImage) -{ - m_FixedImage = fixedImage; -} - -void mitk::BatchedRegistration::SetMovingReferenceImage(Image::Pointer &movingImage) -{ - m_MovingReference = movingImage; - m_RegisteredImagesValid = false; -} - -void mitk::BatchedRegistration::SetBatch(std::vector imageBatch) -{ - m_ImageBatch.clear(); - m_ImageBatch = imageBatch; -} - -std::vector mitk::BatchedRegistration::GetRegisteredImages() -{ - if (!m_RegisteredImagesValid) - { - m_RegisteredImages.clear(); - // First transform moving reference image - RidgidTransformType transf = new double(6); - double offset[3]; - //GetTransformation(m_FixedImage, m_MovingReference,transf,NULL,offset); - // store it as first element in vector - // ApplyTransformationToImage(m_MovingReference,transf,NULL,false,offset); - m_RegisteredImages.push_back(m_MovingReference); - // apply transformation to whole batch - std::vector::const_iterator itEnd = m_ImageBatch.end(); - for (std::vector::iterator it = m_ImageBatch.begin(); it != itEnd; ++it) - { - //TODO fixme - // ApplyTransformationToImage(*it,transf); - m_RegisteredImages.push_back(*it); - } - } - return m_RegisteredImages; -} - void mitk::BatchedRegistration::ApplyTransformationToImage(mitk::Image::Pointer &img, const mitk::BatchedRegistration::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(); + mitk::DiffusionImageCorrectionFilter::Pointer correctionFilter = mitk::DiffusionImageCorrectionFilter::New(); - // For Diff. Images: Need to rotate the gradients + // For Diff. Images: Need to rotate the gradients (works in-place) correctionFilter->SetImage(diffImages); - // works direcrky on input image!! 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) { - // Handle case that fixed or moving image is a DWI image + // 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; - - 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); } + + // 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 d14f565e16..c6294e5b2e 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.h +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.h @@ -1,80 +1,49 @@ #ifndef MITKBATCHEDREGISTRATION_H #define MITKBATCHEDREGISTRATION_H // ITK #include // MITK #include #include "mitkCommon.h" #include "mitkImage.h" namespace mitk { /** - * @brief The BatchedRegistration class Wrapper to calculate and apply a reference transformation to several images. + * @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 transformed for the complete + * 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 BatchedRegistration : public itk::LightObject +class DiffusionCore_EXPORT RegistrationWrapper : public itk::LightObject { public: typedef double* RidgidTransformType; mitkClassMacro(BatchedRegistration, itk::LightObject) itkNewMacro(Self) - - void SetFixedImage(Image::Pointer &fixedImage); - - void SetMovingReferenceImage(mitk::Image::Pointer& movingImage); - - void SetBatch(std::vector imageBatch); - - /** - * @brief GetRegisteredImages returns registered images , - * - * at position 0 the registered moving reference image is supplied followed all registered images from the batch. - */ - std::vector GetRegisteredImages(); - void ApplyTransformationToImage(mitk::Image::Pointer& img, const RidgidTransformType& transformation, double *offset, mitk::Image::Pointer resampleReference = NULL , bool binary = false) const; void GetTransformation(mitk::Image::Pointer fixedImage , mitk::Image::Pointer movingImage, RidgidTransformType transformation, double* offset, mitk::Image::Pointer mask = NULL); protected: - BatchedRegistration(); - ~BatchedRegistration(){}; + RegistrationWrapper(); + ~RegistrationWrapper(){}; private: - BatchedRegistration(const Self &); //purposely not implemented + RegistrationWrapper(const Self &); //purposely not implemented void operator=(const Self &); //purposely not implemented - - bool m_RegisteredImagesValid; - - - mitk::Image::Pointer m_FixedImage; - mitk::Image::Pointer m_MovingReference; - - /** - * @brief m_ImageBatch List of images on which that the reference transformation is applied - * - */ - std::vector m_ImageBatch; - - /** - * @brief m_RegisteredImages List of references to registered images. - * - */ - std::vector m_RegisteredImages; - }; } #endif // MITKBATCHEDREGISTRATION_H