diff --git a/Core/Code/DataManagement/mitkImageCastPart3.cpp b/Core/Code/DataManagement/mitkImageCastPart3.cpp index 7051b758da..8302172b09 100644 --- a/Core/Code/DataManagement/mitkImageCastPart3.cpp +++ b/Core/Code/DataManagement/mitkImageCastPart3.cpp @@ -1,132 +1,130 @@ /*=================================================================== 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 #include #include #include #include #include namespace mitk { #ifndef DOXYGEN_SKIP template < typename TPixel, unsigned int VImageDimension, class ItkOutputImageType > void _CastToItkImage2Access( itk::Image* itkInputImage, itk::SmartPointer& itkOutputImage) { typedef itk::Image ItkInputImageType; if(typeid(ItkInputImageType) == typeid(ItkOutputImageType)) { itkOutputImage = reinterpret_cast(itkInputImage); return; } typedef itk::CastImageFilter< ItkInputImageType, ItkOutputImageType > CastImageFilterType; typename CastImageFilterType::Pointer castImageFilter = CastImageFilterType::New(); castImageFilter->SetInput( itkInputImage ); castImageFilter->Update(); itkOutputImage = castImageFilter->GetOutput(); } #endif //DOXYGEN_SKIP typedef itk::Image, 2> itkImageRGBUC2; +typedef itk::Image, 2> itkImageRGBUS2; typedef itk::Image, 2> itkImageRGBF2; typedef itk::Image, 2> itkImageRGBS2; -typedef itk::Image, 2> itkImageRGBUS2; typedef itk::Image, 2> itkImageDTIF2; typedef itk::Image, 2> itkImageDTID2; template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageRGBUC2*, itk::SmartPointer&); template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageRGBF2*, itk::SmartPointer&); template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageRGBS2*, itk::SmartPointer&); template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageRGBUS2*, itk::SmartPointer&); template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageDTIF2*, itk::SmartPointer&); template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageDTID2*, itk::SmartPointer&); typedef itk::Image, 3> itkImageRGBUC3; -typedef itk::Image, 3> itkImageRGBUS3; typedef itk::Image, 3> itkImageRGBF3; typedef itk::Image, 2> itkImageRGBF2; typedef itk::Image, 3> itkImageDTIF3; typedef itk::Image, 3> itkImageDTID3; template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageRGBUC3*, itk::SmartPointer&); template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageRGBF3*, itk::SmartPointer&); -template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageRGBUS3*, itk::SmartPointer&); template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageDTIF3*, itk::SmartPointer&); template void MITK_CORE_EXPORT _CastToItkImage2Access(itkImageDTID3*, itk::SmartPointer&); #define CAST_HUNDRED_VECS(HUN) \ CAST_TEN_VECS(HUN) \ CAST_TEN_VECS(HUN+10) \ CAST_TEN_VECS(HUN+20) \ CAST_TEN_VECS(HUN+30) \ CAST_TEN_VECS(HUN+40) \ CAST_TEN_VECS(HUN+50) \ CAST_TEN_VECS(HUN+60) \ CAST_TEN_VECS(HUN+70) \ CAST_TEN_VECS(HUN+80) \ CAST_TEN_VECS(HUN+90) \ #define CAST_TEN_VECS(TEN) \ CAST_N_VEC(TEN+ 1) \ CAST_N_VEC(TEN+ 2) \ CAST_N_VEC(TEN+ 3) \ CAST_N_VEC(TEN+ 4) \ CAST_N_VEC(TEN+ 5) \ CAST_N_VEC(TEN+ 6) \ CAST_N_VEC(TEN+ 7) \ CAST_N_VEC(TEN+ 8) \ CAST_N_VEC(TEN+ 9) \ CAST_N_VEC(TEN+10) \ #define CAST_N_VEC(N_DIRS) \ _CAST_N_VEC(N_DIRS,double) \ _CAST_N_VEC(N_DIRS,float) \ _CAST_N_VEC(N_DIRS,short) \ #define _CAST_N_VEC(N_DIRS,PIXTYPE) \ template void MITK_CORE_EXPORT _CastToItkImage2Access(itk::Image, 2> *, itk::SmartPointer, 2> >&); \ template void MITK_CORE_EXPORT _CastToItkImage2Access(itk::Image, 3> *, itk::SmartPointer, 3> >&); \ // the following lines allow for fixed-size vector images up to a certain size limit // (commented out for shorter compile times) //CAST_HUNDRED_VECS(0) //CAST_HUNDRED_VECS(100) //CAST_HUNDRED_VECS(200) //CAST_HUNDRED_VECS(300) // allow for fixed-size vectors of specific length // (inspired by itkPointshell.cpp, precompiled q-ball configs) //CAST_TEN_VECS(0) //CAST_N_VEC(11) //CAST_N_VEC(12) CAST_N_VEC(2) CAST_N_VEC(3) CAST_N_VEC(6) CAST_N_VEC(42) CAST_N_VEC(92) CAST_N_VEC(162) CAST_N_VEC(252) CAST_N_VEC(362) CAST_N_VEC(492) CAST_N_VEC(642) CAST_N_VEC(812) CAST_N_VEC(1002) } diff --git a/Core/Code/DataManagement/mitkImageCastPart4.cpp b/Core/Code/DataManagement/mitkImageCastPart4.cpp index da268440de..c27174ad22 100644 --- a/Core/Code/DataManagement/mitkImageCastPart4.cpp +++ b/Core/Code/DataManagement/mitkImageCastPart4.cpp @@ -1,177 +1,170 @@ /*=================================================================== 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 #include #include #include #include #include namespace mitk { #ifndef DOXYGEN_SKIP template void CastToItkImage(const mitk::Image * mitkImage, itk::SmartPointer& itkOutputImage) { AccessFixedDimensionByItk_1(mitkImage, _CastToItkImage2Access, (ItkOutputImageType::ImageDimension), itkOutputImage); } #endif //DOXYGEN_SKIP typedef itk::Image, 2> itkImageRGBUC2; typedef itk::Image, 2> itkImageDTIF2; typedef itk::Image, 2> itkImageDTID2; template <> void MITK_CORE_EXPORT CastToItkImage(const mitk::Image * mitkImage, itk::SmartPointer& itkOutputImage) { typedef itkImageRGBUC2 ItkOutputImageType; AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (itk::RGBPixel), (ItkOutputImageType::ImageDimension), itkOutputImage); } template <> void MITK_CORE_EXPORT CastToItkImage(const mitk::Image * mitkImage, itk::SmartPointer& itkOutputImage) { typedef itkImageDTIF2 ItkOutputImageType; AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (itk::DiffusionTensor3D), (ItkOutputImageType::ImageDimension), itkOutputImage); } template <> void MITK_CORE_EXPORT CastToItkImage(const mitk::Image * mitkImage, itk::SmartPointer& itkOutputImage) { typedef itkImageDTID2 ItkOutputImageType; AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (itk::DiffusionTensor3D), (ItkOutputImageType::ImageDimension), itkOutputImage); } typedef itk::Image, 3> itkImageRGBUC3; -typedef itk::Image, 3> itkImageRGBUS3; typedef itk::Image, 3> itkImageRGBF3; typedef itk::Image, 2> itkImageRGBF2; typedef itk::Image, 3> itkImageDTIF3; typedef itk::Image, 3> itkImageDTID3; template <> void MITK_CORE_EXPORT CastToItkImage(const mitk::Image * mitkImage, itk::SmartPointer& itkOutputImage) { typedef itkImageRGBUC3 ItkOutputImageType; AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (itk::RGBPixel), (ItkOutputImageType::ImageDimension), itkOutputImage); } template <> void MITK_CORE_EXPORT CastToItkImage(const mitk::Image * mitkImage, itk::SmartPointer& itkOutputImage) { typedef itkImageRGBF3 ItkOutputImageType; AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (itk::RGBPixel), (ItkOutputImageType::ImageDimension), itkOutputImage); } -template <> void MITK_CORE_EXPORT CastToItkImage(const mitk::Image * mitkImage, itk::SmartPointer& itkOutputImage) -{ - typedef itkImageRGBUS3 ItkOutputImageType; - AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (itk::RGBPixel), (ItkOutputImageType::ImageDimension), itkOutputImage); -} - template <> void MITK_CORE_EXPORT CastToItkImage(const mitk::Image * mitkImage, itk::SmartPointer& itkOutputImage) { typedef itkImageRGBF2 ItkOutputImageType; AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (itk::RGBPixel), (ItkOutputImageType::ImageDimension), itkOutputImage); } template <> void MITK_CORE_EXPORT CastToItkImage(const mitk::Image * mitkImage, itk::SmartPointer& itkOutputImage) { typedef itkImageDTIF3 ItkOutputImageType; AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (itk::DiffusionTensor3D), (ItkOutputImageType::ImageDimension), itkOutputImage); } template <> void MITK_CORE_EXPORT CastToItkImage(const mitk::Image * mitkImage, itk::SmartPointer& itkOutputImage) { typedef itkImageDTID3 ItkOutputImageType; AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (itk::DiffusionTensor3D), (ItkOutputImageType::ImageDimension), itkOutputImage); } #define TYPE_VECS(HUN) \ TYPE_TEN_VECS(HUN) \ TYPE_TEN_VECS(HUN + 10) \ TYPE_TEN_VECS(HUN + 20) \ TYPE_TEN_VECS(HUN + 30) \ TYPE_TEN_VECS(HUN + 40) \ TYPE_TEN_VECS(HUN + 50) \ TYPE_TEN_VECS(HUN + 60) \ TYPE_TEN_VECS(HUN + 70) \ TYPE_TEN_VECS(HUN + 80) \ TYPE_TEN_VECS(HUN + 90) \ #define TYPE_TEN_VECS(HUN) \ TYPE_N_VEC(HUN + 1) \ TYPE_N_VEC(HUN + 2) \ TYPE_N_VEC(HUN + 3) \ TYPE_N_VEC(HUN + 4) \ TYPE_N_VEC(HUN + 5) \ TYPE_N_VEC(HUN + 6) \ TYPE_N_VEC(HUN + 7) \ TYPE_N_VEC(HUN + 8) \ TYPE_N_VEC(HUN + 9) \ TYPE_N_VEC(HUN + 10) \ #define TYPE_N_VEC(N_DIRS) \ _TYPE_N_VEC(N_DIRS,double) \ _TYPE_N_VEC(N_DIRS,float) \ _TYPE_N_VEC(N_DIRS,short) \ #define _TYPE_N_VEC(N_DIRS,PIXTYPE) \ template <> void MITK_CORE_EXPORT CastToItkImage, 2> >(const mitk::Image * mitkImage, itk::SmartPointer, 2> >& itkOutputImage) \ { \ typedef itk::Vector VECTORTYPE; \ typedef itk::Image ItkOutputImageType2; \ AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (VECTORTYPE), (ItkOutputImageType2::ImageDimension), itkOutputImage); \ } \ template <> void MITK_CORE_EXPORT CastToItkImage, 3> >(const mitk::Image * mitkImage, itk::SmartPointer, 3> >& itkOutputImage) \ { \ typedef itk::Vector VECTORTYPE; \ typedef itk::Image ItkOutputImageType3; \ AccessFixedTypeByItk_1(mitkImage, _CastToItkImage2Access, (VECTORTYPE), (ItkOutputImageType3::ImageDimension), itkOutputImage); \ } \ // the following lines allow for fixed-size vector images up to a certain size limit // (commented out for shorter compile times) //TYPE_VECS(000) //TYPE_VECS(100) //TYPE_VECS(200) //TYPE_VECS(300) //TYPE_VECS(400) //TYPE_VECS(500) //TYPE_VECS(600) //TYPE_VECS(700) // allow for fixed-size vectors of specific length // (inspired by itkPointshell.cpp, precompiled q-ball configs) //TYPE_TEN_VECS(0) //TYPE_N_VEC(11) //TYPE_N_VEC(12) TYPE_N_VEC(2) TYPE_N_VEC(3) TYPE_N_VEC(6) TYPE_N_VEC(42) TYPE_N_VEC(92) TYPE_N_VEC(162) TYPE_N_VEC(252) TYPE_N_VEC(362) TYPE_N_VEC(492) TYPE_N_VEC(642) TYPE_N_VEC(812) TYPE_N_VEC(1002) #ifndef DOXYGEN_SKIP #endif //DOXYGEN_SKIP } diff --git a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp index ebf711cb15..0eb088c4be 100644 --- a/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp +++ b/Modules/DiffusionImaging/DiffusionCore/Algorithms/Registration/mitkBatchedRegistration.cpp @@ -1,184 +1,214 @@ #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) { } 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) { img = registrationMethod->GetResampledMovingImage(img, transformation); + + 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 = img->GetOrigin(); + origin[0]-=offset[0]; + origin[1]-=offset[1]; + origin[2]-=offset[2]; + + mitk::Point3D newOrigin = rtransform->GetInverseTransform()->TransformPoint(origin); + + itk::Matrix dir = img->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 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 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) { 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) { 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); } // 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 }