diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp index da32c6ca8d..878b052d89 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp @@ -1,74 +1,111 @@ #include "mitkBatchedRegistration.h" #include "mitkPyramidImageRegistrationMethod.h" #include "mitkDiffusionImage.h" +#include +#include + mitk::BatchedRegistration::BatchedRegistration() : m_RegisteredImagesValid(false) { } 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 TransformType transf = GetTransformation(m_FixedImage, m_MovingReference); // store it as first element in vector m_RegisteredImages.push_back(ApplyTransformationToImage(m_MovingReference,transf)); // apply transformation to whole batch std::vector::const_iterator itEnd = m_ImageBatch.end(); for (std::vector::iterator it = m_ImageBatch.begin(); it != itEnd; ++it) { m_RegisteredImages.push_back(ApplyTransformationToImage(*it,transf)); } } return m_RegisteredImages; } mitk::Image::Pointer mitk::BatchedRegistration::ApplyTransformationToImage(mitk::Image::Pointer &img, const mitk::BatchedRegistration::TransformType &transformation) const { // TODO: perform some magic! + mitk::Vector3D translateVector; + translateVector[0] = transformation.get(0,3); + translateVector[1] = transformation.get(1,3); + translateVector[2] = transformation.get(2,3); + img->GetGeometry()->Translate(translateVector); + + itk::ScalableAffineTransform::Pointer rotationTransform; + itk::Matrix rotationMatrix; + for (int i = 0; i < 3;++i) + for (int j = 0; j < 3;++j) + rotationMatrix[i][j] = transformation.get(i,j); + rotationTransform = itk::ScalableAffineTransform::New(); + rotationTransform->SetMatrix(rotationMatrix); + itk::ScalableAffineTransform::Pointer geometryTransform = img->GetGeometry()->GetIndexToWorldTransform(); + geometryTransform->Compose(rotationTransform); + img->GetGeometry()->SetIndexToWorldTransform(geometryTransform); - if (dynamic_cast*> (img.GetPointer()) != NULL) // gaaaaahh template mist! + if (dynamic_cast*> (img.GetPointer()) != NULL) { // apply transformation to image geometry as well as to all gradients !? } else { // do regular stuff } return NULL; } mitk::BatchedRegistration::TransformType mitk::BatchedRegistration::GetTransformation(mitk::Image::Pointer fixedImage, mitk::Image::Pointer movingImage) { + mitk::Point3D startingOrigin = movingImage->GetGeometry()->GetOrigin(); + mitk::PyramidImageRegistrationMethod::Pointer registrationMethod = mitk::PyramidImageRegistrationMethod::New(); registrationMethod->SetFixedImage( fixedImage ); registrationMethod->SetTransformToRigid(); registrationMethod->SetCrossModalityOn(); registrationMethod->SetMovingImage(movingImage); registrationMethod->Update(); // TODO fancy shit, where you query and create a transformation type object thingy + + mitk::Point3D endingOrigin = registrationMethod->GetResampledMovingImage()->GetGeometry()->GetOrigin(); + TransformType transformation; + mitk::PyramidImageRegistrationMethod::TransformMatrixType rotationMatrix; + rotationMatrix = registrationMethod->GetLastRotationMatrix(); + for (unsigned int i = 0; i < 3; i++) + { + for (unsigned int j = 0; j < 3; ++j) + { + transformation.set(i,j, *rotationMatrix[i,j]); + } + } + transformation.set(0,3,endingOrigin[0] - startingOrigin[0]); + transformation.set(1,3,endingOrigin[1] - startingOrigin[1]); + transformation.set(2,3,endingOrigin[2] - startingOrigin[2]); + transformation.set(3,3,1); return transformation; -} +} \ No newline at end of file diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.h b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.h index 093742c8e8..8389a3f5c3 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.h +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.h @@ -1,74 +1,74 @@ #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. * * 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 * 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. */ class DiffusionCore_EXPORT BatchedRegistration : public itk::LightObject { public: - typedef vnl_matrix TransformType; + typedef vnl_matrix_fixed TransformType; BatchedRegistration(); 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(); mitk::Image::Pointer ApplyTransformationToImage(mitk::Image::Pointer& img, const TransformType& transformation) const; TransformType GetTransformation(mitk::Image::Pointer fixedImage, mitk::Image::Pointer movingImage); protected: private: BatchedRegistration(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 diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkPyramidImageRegistrationMethod.cpp b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkPyramidImageRegistrationMethod.cpp index ec983dad04..7ebb3958f9 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkPyramidImageRegistrationMethod.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkPyramidImageRegistrationMethod.cpp @@ -1,140 +1,139 @@ /*=================================================================== 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_EstimatedParameters(NULL), m_Verbose(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::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; }