diff --git a/Modules/RigidRegistration/Resources/mitkRigidRegistrationPresets.xml b/Modules/RigidRegistration/Resources/mitkRigidRegistrationPresets.xml index a0c21b68ee..87a898a945 100644 --- a/Modules/RigidRegistration/Resources/mitkRigidRegistrationPresets.xml +++ b/Modules/RigidRegistration/Resources/mitkRigidRegistrationPresets.xml @@ -1,54 +1,54 @@ + - + - + - + - + - + - + - - + + - + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - diff --git a/Modules/RigidRegistration/mitkImageRegistrationMethod.cpp b/Modules/RigidRegistration/mitkImageRegistrationMethod.cpp index 502cf27bfc..bcfb22213a 100644 --- a/Modules/RigidRegistration/mitkImageRegistrationMethod.cpp +++ b/Modules/RigidRegistration/mitkImageRegistrationMethod.cpp @@ -1,93 +1,102 @@ /*=================================================================== 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 "mitkImageRegistrationMethod.h" #include "mitkImageRegistrationMethodAccessFunctor.h" namespace mitk { ImageRegistrationMethod::ImageRegistrationMethod() - : m_Interpolator(0) + : m_Interpolator(0), + m_MultiResolutionScales(1) { m_ReferenceImage = Image::New(); m_OptimizerScales.clear(); } ImageRegistrationMethod::~ImageRegistrationMethod() { } void ImageRegistrationMethod::GenerateData() { if (this->GetInput()) { ImageRegistrationMethodAccessFunctor()(this->GetInput(), this); } } void ImageRegistrationMethod::SetObserver(RigidRegistrationObserver::Pointer observer) { m_Observer = observer; } void ImageRegistrationMethod::SetInterpolator(int interpolator) { m_Interpolator = interpolator; } void ImageRegistrationMethod::SetReferenceImage(Image::Pointer fixedImage) { m_ReferenceImage = fixedImage; SetNthInput(1, m_ReferenceImage); Modified(); } void ImageRegistrationMethod::SetMovingMask(Image::Pointer movingMask) { m_MovingMask = movingMask; SetNthInput(3, m_MovingMask); Modified(); } void ImageRegistrationMethod::SetFixedMask(Image::Pointer FixedMask) { m_FixedMask = FixedMask; SetNthInput(4, m_FixedMask); Modified(); } void ImageRegistrationMethod::SetTransform(itk::Object::Pointer transform) { m_Transform = transform; + + MITK_INFO("Image.Registration.Method") << "Transform : " << m_Transform; } void ImageRegistrationMethod::SetMetric(itk::Object::Pointer metric) { m_Metric = metric; } void ImageRegistrationMethod::SetOptimizer(itk::Object::Pointer optimizer) { m_Optimizer = optimizer; } void ImageRegistrationMethod::SetOptimizerScales(itk::Array scales) { - m_OptimizerScales = scales; + m_OptimizerScales.set_size( scales.size() ); + m_OptimizerScales.copy_in( scales.data_block() ); + } + + void ImageRegistrationMethod::SetNumberOfLevels(unsigned int levels) + { + m_MultiResolutionScales = levels; } } // end namespace diff --git a/Modules/RigidRegistration/mitkImageRegistrationMethod.h b/Modules/RigidRegistration/mitkImageRegistrationMethod.h index 09a32f9a93..02689167b3 100644 --- a/Modules/RigidRegistration/mitkImageRegistrationMethod.h +++ b/Modules/RigidRegistration/mitkImageRegistrationMethod.h @@ -1,100 +1,104 @@ /*=================================================================== 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. ===================================================================*/ #ifndef MITKIMAGEREGISTRATIONMETHOD_H #define MITKIMAGEREGISTRATIONMETHOD_H #include "itkImageRegistrationMethod.h" #include "MitkRigidRegistrationExports.h" #include "itkSingleValuedNonLinearOptimizer.h" #include "mitkImageToImageFilter.h" #include "mitkImageAccessByItk.h" #include "mitkRigidRegistrationObserver.h" #include "mitkCommon.h" #include "itkImageMaskSpatialObject.h" #include "mitkRigidRegistrationPreset.h" namespace mitk { /*! \brief Main class for the rigid registration pipeline. \ingroup RigidRegistration \author Daniel Stein */ class MITKRIGIDREGISTRATION_EXPORT ImageRegistrationMethod : public ImageToImageFilter { public: typedef itk::SingleValuedNonLinearOptimizer OptimizerType; typedef itk::ImageMaskSpatialObject< 3 > MaskType; mitkClassMacro(ImageRegistrationMethod, ImageToImageFilter); itkFactorylessNewMacro(Self) itkCloneMacro(Self) static const int LINEARINTERPOLATOR = 0; static const int NEARESTNEIGHBORINTERPOLATOR = 1; void SetObserver(RigidRegistrationObserver::Pointer observer); void SetInterpolator(int interpolator); virtual void GenerateData() override; virtual void SetReferenceImage( Image::Pointer fixedImage); virtual void SetFixedMask( Image::Pointer fixedMask); virtual void SetMovingMask( Image::Pointer movingMask); void SetOptimizerScales(itk::Array scales); void SetTransform(itk::Object::Pointer transform); void SetMetric(itk::Object::Pointer metric); void SetOptimizer(itk::Object::Pointer optimizer); + void SetNumberOfLevels( unsigned int levels ); + protected: ImageRegistrationMethod(); virtual ~ImageRegistrationMethod(); friend struct ImageRegistrationMethodAccessFunctor; RigidRegistrationObserver::Pointer m_Observer; int m_Interpolator; Image::Pointer m_ReferenceImage; Image::Pointer m_FixedMask; Image::Pointer m_MovingMask; - virtual void GenerateOutputInformation() override{}; + virtual void GenerateOutputInformation() override {} private: itk::Object::Pointer m_Transform; itk::Object::Pointer m_Metric; itk::Object::Pointer m_Optimizer; itk::Array m_OptimizerScales; + + unsigned int m_MultiResolutionScales; }; } #endif // MITKIMAGEREGISTRATIONMETHOD_H diff --git a/Modules/RigidRegistration/mitkImageRegistrationMethodAccessFunctor.txx b/Modules/RigidRegistration/mitkImageRegistrationMethodAccessFunctor.txx index 1cf0a16f78..d4f315faef 100644 --- a/Modules/RigidRegistration/mitkImageRegistrationMethodAccessFunctor.txx +++ b/Modules/RigidRegistration/mitkImageRegistrationMethodAccessFunctor.txx @@ -1,157 +1,181 @@ /*=================================================================== 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 "mitkImageRegistrationMethodAccessFunctor.h" #include "mitkImageRegistrationMethod.h" #include #include +#include namespace mitk { template void ImageRegistrationMethodAccessFunctor::AccessItkImage(const itk::Image* itkImage1, ImageRegistrationMethod* method) { + + + //convert mitk masks to itk masks typedef typename itk::Image FixedImageType; typedef typename itk::Image MovingImageType; typedef typename itk::Image< unsigned char, VImageDimension > MaskImageType; typedef typename itk::ImageMaskSpatialObject< VImageDimension > ImageMaskType; typename ImageMaskType::Pointer movingImageMask; if(method->m_MovingMask.IsNotNull()) { typename MovingImageType::Pointer movingMask = MovingImageType::New(); mitk::CastToItkImage(method->m_MovingMask, movingMask); typename itk::CastImageFilter::Pointer maskImageCaster = itk::CastImageFilter::New(); maskImageCaster->SetInput(movingMask); maskImageCaster->UpdateLargestPossibleRegion(); movingImageMask = ImageMaskType::New(); movingImageMask->SetImage(maskImageCaster->GetOutput()); } + typename ImageMaskType::Pointer fixedImageMask; if(method->m_FixedMask.IsNotNull()) { typename FixedImageType::Pointer fixedMask = FixedImageType::New(); mitk::CastToItkImage(method->m_FixedMask, fixedMask); typename itk::CastImageFilter::Pointer maskImageCaster = itk::CastImageFilter::New(); maskImageCaster->SetInput(fixedMask); maskImageCaster->UpdateLargestPossibleRegion(); fixedImageMask = ImageMaskType::New(); fixedImageMask->SetImage(maskImageCaster->GetOutput()); } + // typedefs typedef typename itk::Image FixedImageType; typedef typename itk::Image MovingImageType; typedef typename itk::LinearInterpolateImageFunction InterpolatorType; typedef itk::NearestNeighborInterpolateImageFunction InterpolatorType2; - typedef typename itk::ImageRegistrationMethod RegistrationType; + //typedef typename itk::ImageRegistrationMethod RegistrationType; + typedef typename itk::MultiResolutionImageRegistrationMethod< FixedImageType, MovingImageType > RegistrationType; typedef typename itk::Transform< double, VImageDimension, VImageDimension > TransformType; typedef typename itk::MatrixOffsetTransformBase< double, VImageDimension, VImageDimension > MatrixTransformType; typedef typename TransformType::Pointer TransformPointer; typedef typename itk::ImageToImageMetric MetricType; typedef typename MetricType::Pointer MetricPointer; typedef typename itk::SingleValuedNonLinearOptimizer OptimizerType; // the fixed and the moving image typename FixedImageType::Pointer fixedImage = FixedImageType::New(); typename MovingImageType::ConstPointer movingImage = itkImage1; mitk::CastToItkImage(method->m_ReferenceImage, fixedImage); // the metric MetricPointer metric = dynamic_cast(method->m_Metric.GetPointer()); if(movingImageMask.IsNotNull()) metric->SetMovingImageMask(movingImageMask); if(fixedImageMask.IsNotNull()) metric->SetFixedImageMask(fixedImageMask); // the transform TransformPointer transform = dynamic_cast(method->m_Transform.GetPointer()); if( transform.IsNull() ) mitkThrow() << "Failed to retrieve registration transform, dynamic cast failed"; // the optimizer typename OptimizerType::Pointer optimizer = dynamic_cast(method->m_Optimizer.GetPointer()); // optimizer scales if (method->m_OptimizerScales.Size() != 0) { typename OptimizerType::ScalesType scales( transform->GetNumberOfParameters() ); for (unsigned int i = 0; i < scales.Size(); i++) { scales[i] = method->m_OptimizerScales[i]; } optimizer->SetScales( scales ); } // the registration method typename RegistrationType::Pointer registration = RegistrationType::New(); + registration->SetNumberOfLevels( method->m_MultiResolutionScales ); registration->SetMetric(metric); registration->SetOptimizer(optimizer); registration->SetTransform(transform); registration->SetFixedImage(fixedImage); registration->SetMovingImage(movingImage); registration->SetFixedImageRegion(fixedImage->GetBufferedRegion()); // set initial position to identity by first setting the transformation to identity // and then using its parameters typename TransformType::ParametersType identityParameters = transform->GetParameters(); // the SetIdentity avialable only for a transform subset (of type matrix offset) MatrixTransformType* matrix_transform = dynamic_cast< MatrixTransformType* >( method->m_Transform.GetPointer() ); if( matrix_transform != nullptr) { matrix_transform->SetIdentity(); identityParameters = matrix_transform->GetParameters(); } registration->SetInitialTransformParameters( identityParameters ); optimizer->SetInitialPosition( identityParameters ); if (method->m_Interpolator == ImageRegistrationMethod::LINEARINTERPOLATOR) { typename InterpolatorType::Pointer interpolator = InterpolatorType::New(); registration->SetInterpolator(interpolator); } else if (method->m_Interpolator == ImageRegistrationMethod::NEARESTNEIGHBORINTERPOLATOR) { typename InterpolatorType2::Pointer interpolator = InterpolatorType2::New(); registration->SetInterpolator(interpolator); } + + // registering command observer with the optimizer + unsigned int pyramid_observer_tag = 0; if (method->m_Observer.IsNotNull()) { method->m_Observer->AddStepsToDo(20); - optimizer->AddObserver(itk::AnyEvent(), method->m_Observer); - registration->AddObserver(itk::AnyEvent(), method->m_Observer); - transform->AddObserver(itk::AnyEvent(), method->m_Observer); + optimizer->AddObserver(itk::IterationEvent(), method->m_Observer); + //registration->AddObserver(itk::IterationEvent(), method->m_Observer); + transform->AddObserver(itk::IterationEvent(), method->m_Observer); + + typename mitk::RigidRegistrationPyramidObserver::Pointer pyramid_observer = + mitk::RigidRegistrationPyramidObserver::New(); + + pyramid_observer_tag = registration->AddObserver( itk::IterationEvent(), pyramid_observer ); } + registration->Update(); + + if( pyramid_observer_tag ) + { + registration->RemoveObserver( pyramid_observer_tag ); + } + if (method->m_Observer.IsNotNull()) { optimizer->RemoveAllObservers(); registration->RemoveAllObservers(); transform->RemoveAllObservers(); method->m_Observer->SetRemainingProgress(15); } + if (method->m_Observer.IsNotNull()) { method->m_Observer->SetRemainingProgress(5); } } } // end namespace diff --git a/Modules/RigidRegistration/mitkRigidRegistrationObserver.cpp b/Modules/RigidRegistration/mitkRigidRegistrationObserver.cpp index 2b66a85fea..e2e4524e16 100644 --- a/Modules/RigidRegistration/mitkRigidRegistrationObserver.cpp +++ b/Modules/RigidRegistration/mitkRigidRegistrationObserver.cpp @@ -1,288 +1,164 @@ /*=================================================================== 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 "mitkRigidRegistrationObserver.h" #include "mitkProgressBar.h" mitk::RigidRegistrationObserver::RigidRegistrationObserver() : m_OptimizerValue(0), m_StopOptimization(false) { + } -void mitk::RigidRegistrationObserver::Execute(itk::Object *caller, const itk::EventObject & event) +void mitk::RigidRegistrationObserver::HandleOptimizationIterationEvent(OptimizerType *optimizer) { - if (typeid(event) == typeid(itk::IterationEvent)) + unsigned int iteration = 0; + + itk::RegularStepGradientDescentBaseOptimizer* rsgdbase = dynamic_cast< itk::RegularStepGradientDescentBaseOptimizer* >( optimizer ); + if( rsgdbase != nullptr ) { - OptimizerPointer optimizer = dynamic_cast(caller); - ExhaustiveOptimizerPointer ExhaustiveOptimizer = dynamic_cast(optimizer); - GradientDescentOptimizerPointer GradientDescentOptimizer = dynamic_cast(optimizer); - QuaternionRigidTransformGradientDescentOptimizerPointer QuaternionRigidTransformGradientDescentOptimizer = dynamic_cast(optimizer); - LBFGSBOptimizerPointer LBFGSBOptimizer = dynamic_cast(optimizer); - OnePlusOneEvolutionaryOptimizerPointer OnePlusOneEvolutionaryOptimizer = dynamic_cast(optimizer); - PowellOptimizerPointer PowellOptimizer = dynamic_cast(optimizer); - FRPROptimizerPointer FRPROptimizer = dynamic_cast(optimizer); - RegularStepGradientDescentOptimizerPointer RegularStepGradientDescentOptimizer = dynamic_cast(optimizer); - VersorRigid3DTransformOptimizerPointer VersorRigid3DTransformOptimizer = dynamic_cast(optimizer); - VersorTransformOptimizerPointer VersorTransformOptimizer = dynamic_cast(optimizer); - AmoebaOptimizerPointer AmoebaOptimizer = dynamic_cast(optimizer); - ConjugateGradientOptimizerPointer ConjugateGradientOptimizer = dynamic_cast(optimizer); - LBFGSOptimizerPointer LBFGSOptimizer = dynamic_cast(optimizer); - SPSAOptimizerPointer SPSAOptimizer = dynamic_cast(optimizer); - if (ExhaustiveOptimizer != nullptr) - { - m_OptimizerValue = ExhaustiveOptimizer->GetValue(ExhaustiveOptimizer->GetCurrentPosition()); - MITK_INFO << ExhaustiveOptimizer->GetValue(ExhaustiveOptimizer->GetCurrentPosition()) << " " - << ExhaustiveOptimizer->GetCurrentPosition() << std::endl; - m_Params = ExhaustiveOptimizer->GetCurrentPosition(); - if(m_StopOptimization) - { - //ExhaustiveOptimizer->StopOptimization(); - m_StopOptimization = false; - } - InvokeEvent(itk::ModifiedEvent()); - } - else if (GradientDescentOptimizer != nullptr) - { - m_OptimizerValue = GradientDescentOptimizer->GetValue(); - MITK_INFO << GradientDescentOptimizer->GetCurrentIteration() << " " - << GradientDescentOptimizer->GetValue() << " " - << GradientDescentOptimizer->GetCurrentPosition() << std::endl; - m_Params = GradientDescentOptimizer->GetCurrentPosition(); - if(m_StopOptimization) - { - GradientDescentOptimizer->StopOptimization(); - m_StopOptimization = false; - } - InvokeEvent(itk::ModifiedEvent()); - } - else if (QuaternionRigidTransformGradientDescentOptimizer != nullptr) - { - m_OptimizerValue = QuaternionRigidTransformGradientDescentOptimizer->GetValue(); - MITK_INFO << QuaternionRigidTransformGradientDescentOptimizer->GetCurrentIteration() << " " - << QuaternionRigidTransformGradientDescentOptimizer->GetValue() << " " - << QuaternionRigidTransformGradientDescentOptimizer->GetCurrentPosition() << std::endl; - m_Params = QuaternionRigidTransformGradientDescentOptimizer->GetCurrentPosition(); - if(m_StopOptimization) - { - QuaternionRigidTransformGradientDescentOptimizer->StopOptimization(); - m_StopOptimization = false; - } - InvokeEvent(itk::ModifiedEvent()); - } - else if (LBFGSBOptimizer != nullptr) - { - m_OptimizerValue = LBFGSBOptimizer->GetValue(); - MITK_INFO << LBFGSBOptimizer->GetCurrentIteration() << " " - << LBFGSBOptimizer->GetValue() << " " - << LBFGSBOptimizer->GetCurrentPosition() << std::endl; - m_Params = LBFGSBOptimizer->GetCurrentPosition(); - if(m_StopOptimization) - { - //LBFGSBOptimizer->StopOptimization(); - m_StopOptimization = false; - } - InvokeEvent(itk::ModifiedEvent()); - } - else if (OnePlusOneEvolutionaryOptimizer != nullptr) - { - m_OptimizerValue = OnePlusOneEvolutionaryOptimizer->GetValue(); - MITK_INFO << OnePlusOneEvolutionaryOptimizer->GetCurrentIteration() << " " - << OnePlusOneEvolutionaryOptimizer->GetValue() << " " - << OnePlusOneEvolutionaryOptimizer->GetCurrentPosition() << std::endl; - m_Params = OnePlusOneEvolutionaryOptimizer->GetCurrentPosition(); - if(m_StopOptimization) - { - OnePlusOneEvolutionaryOptimizer->StopOptimization(); - m_StopOptimization = false; - } - InvokeEvent(itk::ModifiedEvent()); - } - else if (PowellOptimizer != nullptr) - { - m_OptimizerValue = PowellOptimizer->GetValue(); - MITK_INFO << PowellOptimizer->GetCurrentIteration() << " " - << PowellOptimizer->GetValue() << " " - << PowellOptimizer->GetCurrentPosition() << std::endl; - m_Params = PowellOptimizer->GetCurrentPosition(); - if(m_StopOptimization) - { - PowellOptimizer->StopOptimization(); - m_StopOptimization = false; - } - InvokeEvent(itk::ModifiedEvent()); - } - else if (FRPROptimizer != nullptr) - { - m_OptimizerValue = FRPROptimizer->GetValue(); - MITK_INFO << FRPROptimizer->GetCurrentIteration() << " " - << FRPROptimizer->GetValue() << " " - << FRPROptimizer->GetCurrentPosition() << std::endl; - m_Params = FRPROptimizer->GetCurrentPosition(); - if(m_StopOptimization) - { - FRPROptimizer->StopOptimization(); - m_StopOptimization = false; - } - InvokeEvent(itk::ModifiedEvent()); - } - else if (RegularStepGradientDescentOptimizer != nullptr) - { - m_OptimizerValue = RegularStepGradientDescentOptimizer->GetValue(); - MITK_INFO << RegularStepGradientDescentOptimizer->GetCurrentIteration() << " " - << RegularStepGradientDescentOptimizer->GetValue() << " " - << RegularStepGradientDescentOptimizer->GetCurrentPosition() << std::endl; - m_Params = RegularStepGradientDescentOptimizer->GetCurrentPosition(); - if(m_StopOptimization) - { - RegularStepGradientDescentOptimizer->StopOptimization(); - m_StopOptimization = false; - } - InvokeEvent(itk::ModifiedEvent()); - } - else if (VersorRigid3DTransformOptimizer != nullptr) - { - m_OptimizerValue = VersorRigid3DTransformOptimizer->GetValue(); - MITK_INFO << VersorRigid3DTransformOptimizer->GetCurrentIteration() << " " - << VersorRigid3DTransformOptimizer->GetValue() << " " - << VersorRigid3DTransformOptimizer->GetCurrentPosition() << std::endl; - m_Params = VersorRigid3DTransformOptimizer->GetCurrentPosition(); - if(m_StopOptimization) - { - VersorRigid3DTransformOptimizer->StopOptimization(); - m_StopOptimization = false; - } - InvokeEvent(itk::ModifiedEvent()); - } - else if (VersorTransformOptimizer != nullptr) + m_OptimizerValue = rsgdbase->GetValue(); + m_Params = rsgdbase->GetCurrentPosition(); + iteration = rsgdbase->GetCurrentIteration(); + + MITK_INFO << "("<< iteration << ") " << m_OptimizerValue << " :: "<< m_Params << std::endl; + + if( this->m_StopOptimization ) { - m_OptimizerValue = VersorTransformOptimizer->GetValue(); - MITK_INFO << VersorTransformOptimizer->GetCurrentIteration() << " " - << VersorTransformOptimizer->GetValue() << " " - << VersorTransformOptimizer->GetCurrentPosition() << std::endl; - m_Params = VersorTransformOptimizer->GetCurrentPosition(); - if(m_StopOptimization) - { - VersorTransformOptimizer->StopOptimization(); - m_StopOptimization = false; - } - InvokeEvent(itk::ModifiedEvent()); + rsgdbase->StopOptimization(); + m_StopOptimization = false; } - else if (AmoebaOptimizer != nullptr) + return; + } + + itk::GradientDescentOptimizer* gdbase = dynamic_cast< itk::GradientDescentOptimizer* >( optimizer ); + if( gdbase != nullptr ) + { + m_OptimizerValue = gdbase->GetValue(); + m_Params = gdbase->GetCurrentPosition(); + iteration = gdbase->GetCurrentIteration(); + + MITK_INFO << "("<< iteration << ") " << m_OptimizerValue << " :: "<< m_Params << std::endl; + + if( this->m_StopOptimization ) { - m_OptimizerValue = AmoebaOptimizer->GetCachedValue(); - MITK_INFO << AmoebaOptimizer->GetCachedValue() << " " - << AmoebaOptimizer->GetCachedCurrentPosition() << std::endl; - m_Params = AmoebaOptimizer->GetCurrentPosition(); - if(m_StopOptimization) - { - //AmoebaOptimizer->StopOptimization(); - m_StopOptimization = false; - } - InvokeEvent(itk::ModifiedEvent()); + gdbase->StopOptimization(); + m_StopOptimization = false; } - else if (ConjugateGradientOptimizer != nullptr) + return; + } + + itk::PowellOptimizer* powbase = dynamic_cast< itk::PowellOptimizer* >( optimizer ); + if( powbase != nullptr ) + { + m_OptimizerValue = powbase->GetValue(); + m_Params = powbase->GetCurrentPosition(); + iteration = powbase->GetCurrentIteration(); + + MITK_INFO << "("<< iteration << ") " << m_OptimizerValue << " :: "<< m_Params << std::endl; + + if( this->m_StopOptimization ) { - m_OptimizerValue = ConjugateGradientOptimizer->GetValue(); - MITK_INFO << ConjugateGradientOptimizer->GetCurrentIteration() << " " - << ConjugateGradientOptimizer->GetValue() << " " - << ConjugateGradientOptimizer->GetCurrentPosition() << std::endl; - m_Params = ConjugateGradientOptimizer->GetCurrentPosition(); - if(m_StopOptimization) - { - //ConjugateGradientOptimizer->StopOptimization(); - m_StopOptimization = false; - } - InvokeEvent(itk::ModifiedEvent()); + powbase->StopOptimization(); + m_StopOptimization = false; } - else if (LBFGSOptimizer != nullptr) + return; + } + + itk::OnePlusOneEvolutionaryOptimizer* opluso = dynamic_cast< itk::OnePlusOneEvolutionaryOptimizer* >( optimizer ); + if( opluso != nullptr ) + { + m_OptimizerValue = opluso->GetValue(); + m_Params = opluso->GetCurrentPosition(); + iteration = opluso->GetCurrentIteration(); + + MITK_INFO << "("<< iteration << ") " << m_OptimizerValue << " :: "<< m_Params << std::endl; + + if( this->m_StopOptimization ) { - if(m_StopOptimization) - { - //LBFGSOptimizer->StopOptimization(); - m_StopOptimization = false; - } - //m_OptimizerValue = LBFGSOptimizer->GetValue(); - /*MITK_INFO << LBFGSOptimizer->GetCurrentIteration() << " "; - MITK_INFO << LBFGSOptimizer->GetValue() << " "; - MITK_INFO << LBFGSOptimizer->GetInfinityNormOfProjectedGradient() << std::endl;*/ - InvokeEvent(itk::ModifiedEvent()); + powbase->StopOptimization(); + m_StopOptimization = false; } - else if (SPSAOptimizer != nullptr) + return; + } + +} + +void mitk::RigidRegistrationObserver::Execute(itk::Object *caller, const itk::EventObject & event) +{ + if (typeid(event) == typeid(itk::IterationEvent)) + { + OptimizerPointer optimizer = dynamic_cast(caller); + + if (optimizer != nullptr) { - m_OptimizerValue = SPSAOptimizer->GetValue(); - MITK_INFO << SPSAOptimizer->GetCurrentIteration() << " " - << SPSAOptimizer->GetValue() << " " - << SPSAOptimizer->GetCurrentPosition() << std::endl; - m_Params = SPSAOptimizer->GetCurrentPosition(); - if(m_StopOptimization) - { - SPSAOptimizer->StopOptimization(); - m_StopOptimization = false; - } - InvokeEvent(itk::ModifiedEvent()); + this->HandleOptimizationIterationEvent(optimizer); + + InvokeEvent( itk::ModifiedEvent() ); } + } else if (typeid(event) == typeid(itk::FunctionEvaluationIterationEvent)) { OptimizerPointer optimizer = dynamic_cast(caller); - AmoebaOptimizerPointer AmoebaOptimizer = dynamic_cast(optimizer); + itk::AmoebaOptimizer* AmoebaOptimizer = dynamic_cast(optimizer); if (AmoebaOptimizer != nullptr) { m_OptimizerValue = AmoebaOptimizer->GetCachedValue(); MITK_INFO << AmoebaOptimizer->GetCachedValue() << " " << AmoebaOptimizer->GetCachedCurrentPosition() << std::endl; m_Params = AmoebaOptimizer->GetCachedCurrentPosition(); if(m_StopOptimization) { //AmoebaOptimizer->StopOptimization(); m_StopOptimization = false; } InvokeEvent(itk::ModifiedEvent()); } } mitk::ProgressBar::GetInstance()->AddStepsToDo(1); mitk::ProgressBar::GetInstance()->Progress(); } void mitk::RigidRegistrationObserver::Execute(const itk::Object* /*caller*/, const itk::EventObject& /*event*/) { } void mitk::RigidRegistrationObserver::AddStepsToDo(int steps) { mitk::ProgressBar::GetInstance()->AddStepsToDo(steps); } void mitk::RigidRegistrationObserver::SetRemainingProgress(int steps) { mitk::ProgressBar::GetInstance()->Progress(steps); } double mitk::RigidRegistrationObserver::GetCurrentOptimizerValue() { return m_OptimizerValue; } itk::Array mitk::RigidRegistrationObserver::GetCurrentTranslation() { return m_Params; } // Sets the stop optimization flag, which is used to call the StopOptimization() method of the optimizer. // Unfortunately it is not implemented for ExhaustiveOptimizer, LBFGSBOptimizer, AmoebaOptimizer, ConjugateGradientOptimizer and LBFGSOptimizer in ITK. void mitk::RigidRegistrationObserver::SetStopOptimization(bool stopOptimization) { m_StopOptimization = stopOptimization; } diff --git a/Modules/RigidRegistration/mitkRigidRegistrationObserver.h b/Modules/RigidRegistration/mitkRigidRegistrationObserver.h index 731d1bf62e..e68a87b79b 100644 --- a/Modules/RigidRegistration/mitkRigidRegistrationObserver.h +++ b/Modules/RigidRegistration/mitkRigidRegistrationObserver.h @@ -1,175 +1,191 @@ /*=================================================================== 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. ===================================================================*/ #ifndef MITKRIGIDREGISTRATIONOBSERVER_H #define MITKRIGIDREGISTRATIONOBSERVER_H #include "itkSingleValuedNonLinearOptimizer.h" #include "MitkRigidRegistrationExports.h" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "itkCommand.h" #include "mitkCommon.h" namespace mitk { /** * \brief Observer to react on rigid registration optimizer events. * * \sa ProgressBar * * \ingroup RigidRegistration * * This class reacts on events sent by ITK optimizers. These events will be sent for every iteration the optimizer performs. * This class also takes care for the progress bar for every iteration step. * * The current optimizer values will be stored and a modified event will be sent to listeners registered to this observer. * These listeners have the possibility to get the current optimizer parameters. * * The optimization process can be stopped by setting stopOptimization to true. The optimization will be stopped after the next * iteration step of the optimizer. Unfortunately this is not implemented for ExhaustiveOptimizer, LBFGSBOptimizer, AmoebaOptimizer, * ConjugateGradientOptimizer and LBFGSOptimizer in ITK. * * \author Daniel Stein */ class MITKRIGIDREGISTRATION_EXPORT RigidRegistrationObserver : public itk::Command { public: typedef RigidRegistrationObserver Self; typedef itk::Command Superclass; typedef itk::SmartPointer Pointer; itkFactorylessNewMacro(Self) itkCloneMacro(Self) typedef itk::SingleValuedNonLinearOptimizer OptimizerType; typedef OptimizerType * OptimizerPointer; - typedef itk::ExhaustiveOptimizer ExhaustiveOptimizerType; - typedef ExhaustiveOptimizerType * ExhaustiveOptimizerPointer; - - typedef itk::GradientDescentOptimizer GradientDescentOptimizerType; - typedef GradientDescentOptimizerType * GradientDescentOptimizerPointer; - - typedef itk::QuaternionRigidTransformGradientDescentOptimizer QuaternionRigidTransformGradientDescentOptimizerType; - typedef QuaternionRigidTransformGradientDescentOptimizerType * QuaternionRigidTransformGradientDescentOptimizerPointer; - - typedef itk::LBFGSBOptimizer LBFGSBOptimizerType; - typedef LBFGSBOptimizerType * LBFGSBOptimizerPointer; - - typedef itk::OnePlusOneEvolutionaryOptimizer OnePlusOneEvolutionaryOptimizerType; - typedef OnePlusOneEvolutionaryOptimizerType * OnePlusOneEvolutionaryOptimizerPointer; - - typedef itk::PowellOptimizer PowellOptimizerType; - typedef PowellOptimizerType * PowellOptimizerPointer; - - typedef itk::FRPROptimizer FRPROptimizerType; - typedef FRPROptimizerType * FRPROptimizerPointer; - - typedef itk::RegularStepGradientDescentOptimizer RegularStepGradientDescentOptimizerType; - typedef RegularStepGradientDescentOptimizerType * RegularStepGradientDescentOptimizerPointer; - - typedef itk::VersorRigid3DTransformOptimizer VersorRigid3DTransformOptimizerType; - typedef VersorRigid3DTransformOptimizerType * VersorRigid3DTransformOptimizerPointer; - - typedef itk::VersorTransformOptimizer VersorTransformOptimizerType; - typedef VersorTransformOptimizerType * VersorTransformOptimizerPointer; - - typedef itk::AmoebaOptimizer AmoebaOptimizerType; - typedef AmoebaOptimizerType * AmoebaOptimizerPointer; - - typedef itk::ConjugateGradientOptimizer ConjugateGradientOptimizerType; - typedef ConjugateGradientOptimizerType * ConjugateGradientOptimizerPointer; - - typedef itk::LBFGSOptimizer LBFGSOptimizerType; - typedef LBFGSOptimizerType * LBFGSOptimizerPointer; - - typedef itk::SPSAOptimizer SPSAOptimizerType; - typedef SPSAOptimizerType * SPSAOptimizerPointer; - /** * \brief Reacts on events from ITK optimizers. * * Stores the optimizer values, adds progress to the progress bar and sends a stop flag to stop the optimization process if it is * set in this class. Also emits a signal to inform listeners about new optimizer values. */ void Execute(itk::Object *caller, const itk::EventObject & event) override; /** * \brief Not implemented... * */ void Execute(const itk::Object * object, const itk::EventObject & event) override; /** * \brief Add new steps to the progress bar. * */ void AddStepsToDo(int steps); /** * \brief Sets the remaining progress to the progress bar when the optimization process is done. * */ void SetRemainingProgress(int steps); /** * \brief Returns the current optimizer value. This value is calculated by the used metric and shows, how good the images are aligned. * * */ double GetCurrentOptimizerValue(); /** * \brief Returns the current transformation parameters for the moving image to this iteration step. * * These can include parameters for translation, scaling, rotation and shearing. */ itk::Array GetCurrentTranslation(); /** * \brief Sets the stop optimization flag, which is used to call the StopOptimization() method of the optimizer. * * Unfortunately it is not implemented for ExhaustiveOptimizer, LBFGSBOptimizer, AmoebaOptimizer, * ConjugateGradientOptimizer and LBFGSOptimizer in ITK. */ void SetStopOptimization(bool stopOptimization); protected: RigidRegistrationObserver(); + void HandleOptimizationIterationEvent(OptimizerType *optimizer ); + private: double m_OptimizerValue; itk::Array m_Params; bool m_StopOptimization; }; + template < class RegistrationType > + class MITKRIGIDREGISTRATION_EXPORT RigidRegistrationPyramidObserver : public itk::Command + { + public: + typedef itk::RegularStepGradientDescentBaseOptimizer OptimizerType; + + mitkClassMacroItkParent( RigidRegistrationPyramidObserver, itk::Command) + itkFactorylessNewMacro(Self) + itkCloneMacro(Self) + + void Execute(itk::Object *caller, const itk::EventObject & /*event*/) override + { + RegistrationType* registration = dynamic_cast< RegistrationType* >( caller ); + + if( registration == NULL) + return; + + OptimizerType* optimizer = dynamic_cast< OptimizerType* >(registration->GetOptimizer()); + + if( optimizer == NULL) + { + MITK_WARN("Pyramid.Registration.Command") << "No step adaptation possible with given optimizer, cast failed! "; + return; + } + + + MITK_DEBUG << "\t - Pyramid level " << registration->GetCurrentLevel(); + + if( registration->GetCurrentLevel() == 0 ) + { + MITK_INFO("Pyramid.Registration.Command") << "First pyramid resolution level: "; + MITK_INFO("Pyramid.Registration.Command") << " Current settings: \n" + << " Step length: (" << optimizer->GetMinimumStepLength() + << "," << optimizer->GetMaximumStepLength() << "), Tolerance: " + << optimizer->GetGradientMagnitudeTolerance() << " Iterations: " + << optimizer->GetNumberOfIterations(); + return; + } + + optimizer->SetMaximumStepLength( optimizer->GetMaximumStepLength() * 0.25f ); + optimizer->SetMinimumStepLength( optimizer->GetMinimumStepLength() * 0.1f ); + optimizer->SetGradientMagnitudeTolerance( optimizer->GetGradientMagnitudeTolerance() * 0.1f ); + optimizer->SetNumberOfIterations( optimizer->GetNumberOfIterations() * 1.5f ); + + MITK_INFO("Pyramid.Registration.Command") << " Current settings: \n" + << " Step length: (" << optimizer->GetMinimumStepLength() + << "," << optimizer->GetMaximumStepLength() << "), Tolerance: " + << optimizer->GetGradientMagnitudeTolerance() << " Iterations: " + << optimizer->GetNumberOfIterations(); + + } + + void Execute(const itk::Object * /*object*/, const itk::EventObject & /*event*/) override {} + }; + + } // namespace mitk #endif // MITKRIGIDREGISTRATIONOBSERVER_H diff --git a/Modules/RigidRegistration/mitkRigidRegistrationPreset.cpp b/Modules/RigidRegistration/mitkRigidRegistrationPreset.cpp index dcc5a95898..6016ec8d50 100644 --- a/Modules/RigidRegistration/mitkRigidRegistrationPreset.cpp +++ b/Modules/RigidRegistration/mitkRigidRegistrationPreset.cpp @@ -1,792 +1,795 @@ /*=================================================================== 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 "mitkRigidRegistrationPreset.h" #include "mitkMetricParameters.h" #include "mitkOptimizerParameters.h" #include "mitkTransformParameters.h" #include "usGetModuleContext.h" #include "usModuleContext.h" #include "usModule.h" #include "usModuleResource.h" #include "usModuleResourceStream.h" namespace mitk { RigidRegistrationPreset::RigidRegistrationPreset() { m_Name = ""; m_XmlFileName = "mitkRigidRegistrationPresets.xml"; } RigidRegistrationPreset::~RigidRegistrationPreset() { } bool RigidRegistrationPreset::LoadPreset() { return LoadPreset("mitkRigidRegistrationPresets.xml"); } bool RigidRegistrationPreset::LoadPreset(std::string fileName) { if ( fileName.empty() ) return false; us::ModuleResource presetResource = us::GetModuleContext()->GetModule()->GetResource(fileName); if (!presetResource) return false; us::ModuleResourceStream presetStream(presetResource); vtkXMLParser::SetStream(&presetStream); if ( !vtkXMLParser::Parse() ) { #ifdef INTERDEBUG MITK_INFO<<"RigidRegistrationPreset::LoadPreset xml file cannot parse!"< > newTransformValues, std::map > newMetricValues, std::map > newOptimizerValues, std::map > newInterpolatorValues, std::string fileName) { if ( !fileName.empty() ) { m_XmlFileName = fileName; } m_TransformValues = newTransformValues; m_MetricValues = newMetricValues; m_OptimizerValues = newOptimizerValues; m_InterpolatorValues = newInterpolatorValues; return save(); } void RigidRegistrationPreset::StartElement (const char *elementName, const char **atts) { std::string elementNameString = elementName; if ( elementNameString == "preset" ) { m_Name = ReadXMLStringAttribut( "NAME", atts ); } else if (elementNameString == "transform") { itk::Array transformValues; transformValues.SetSize(25); transformValues.fill(0); std::string transform = ReadXMLStringAttribut( "TRANSFORM", atts ); double trans = atof(transform.c_str()); transformValues[0] = trans; + MITK_DEBUG("RigidRegistration.Preset.StartElement ") << "Name tag: " << m_Name; transformValues = this->loadTransformValues(transformValues, trans, atts); m_TransformValues[m_Name] = transformValues; } else if (elementNameString == "metric") { itk::Array metricValues; metricValues.SetSize(25); metricValues.fill(0); std::string metric = ReadXMLStringAttribut( "METRIC", atts ); double met = atof(metric.c_str()); metricValues[0] = met; metricValues = this->loadMetricValues(metricValues, met, atts); m_MetricValues[m_Name] = metricValues; } else if (elementNameString == "optimizer") { itk::Array optimizerValues; optimizerValues.SetSize(25); optimizerValues.fill(0); std::string optimizer = ReadXMLStringAttribut( "OPTIMIZER", atts ); double opt = atof(optimizer.c_str()); optimizerValues[0] = opt; optimizerValues = this->loadOptimizerValues(optimizerValues, opt, atts); m_OptimizerValues[m_Name] = optimizerValues; } else if (elementNameString == "interpolator") { itk::Array interpolatorValues; interpolatorValues.SetSize(25); interpolatorValues.fill(0); std::string interpolator = ReadXMLStringAttribut( "INTERPOLATOR", atts ); double inter = atof(interpolator.c_str()); interpolatorValues[0] = inter; interpolatorValues = this->loadInterpolatorValues(interpolatorValues/*, inter, atts*/); m_InterpolatorValues[m_Name] = interpolatorValues; } } std::string RigidRegistrationPreset::ReadXMLStringAttribut( std::string name, const char** atts ) { if(atts) { const char** attsIter = atts; while(*attsIter) { if ( name == *attsIter ) { attsIter++; return *attsIter; } attsIter++; attsIter++; } } return std::string(); } itk::Array RigidRegistrationPreset::getTransformValues(std::string name) { return m_TransformValues[name]; } itk::Array RigidRegistrationPreset::getMetricValues(std::string name) { return m_MetricValues[name]; } itk::Array RigidRegistrationPreset::getOptimizerValues(std::string name) { return m_OptimizerValues[name]; } itk::Array RigidRegistrationPreset::getInterpolatorValues(std::string name) { return m_InterpolatorValues[name]; } std::list &RigidRegistrationPreset::getAvailablePresets() { // use the loaded transoform values to access the names for( auto preset : m_TransformValues) { m_LoadedPresets.push_back( preset.first ); } return m_LoadedPresets; } std::map >& RigidRegistrationPreset::getTransformValuesPresets() { return m_TransformValues; } std::map >& RigidRegistrationPreset::getMetricValuesPresets() { return m_MetricValues; } std::map >& RigidRegistrationPreset::getOptimizerValuesPresets() { return m_OptimizerValues; } std::map >& RigidRegistrationPreset::getInterpolatorValuesPresets() { return m_InterpolatorValues; } bool RigidRegistrationPreset::save() { // falsely removed return value, the previous implementation was also empty (and only returning false) return false; } itk::Array RigidRegistrationPreset::loadTransformValues(itk::Array transformValues, double transform, const char **atts) { if (transform == mitk::TransformParameters::TRANSLATIONTRANSFORM || transform == mitk::TransformParameters::SCALETRANSFORM || transform == mitk::TransformParameters::SCALELOGARITHMICTRANSFORM || transform == mitk::TransformParameters::VERSORTRANSFORM || transform == mitk::TransformParameters::RIGID2DTRANSFORM || transform == mitk::TransformParameters::EULER2DTRANSFORM) { std::string useScales = ReadXMLStringAttribut( "USESCALES", atts ); double useSca = atof(useScales.c_str()); transformValues[1] = useSca; std::string scale1 = ReadXMLStringAttribut( "SCALE1", atts ); double sca1 = atof(scale1.c_str()); transformValues[2] = sca1; std::string scale2 = ReadXMLStringAttribut( "SCALE2", atts ); double sca2 = atof(scale2.c_str()); transformValues[3] = sca2; std::string scale3 = ReadXMLStringAttribut( "SCALE3", atts ); double sca3 = atof(scale3.c_str()); transformValues[4] = sca3; } else if (transform == mitk::TransformParameters::AFFINETRANSFORM || transform == mitk::TransformParameters::FIXEDCENTEROFROTATIONAFFINETRANSFORM) { std::string useScales = ReadXMLStringAttribut( "USESCALES", atts ); double useSca = atof(useScales.c_str()); transformValues[1] = useSca; std::string scale1 = ReadXMLStringAttribut( "SCALE1", atts ); double sca1 = atof(scale1.c_str()); transformValues[2] = sca1; std::string scale2 = ReadXMLStringAttribut( "SCALE2", atts ); double sca2 = atof(scale2.c_str()); transformValues[3] = sca2; std::string scale3 = ReadXMLStringAttribut( "SCALE3", atts ); double sca3 = atof(scale3.c_str()); transformValues[4] = sca3; std::string scale4 = ReadXMLStringAttribut( "SCALE4", atts ); double sca4 = atof(scale4.c_str()); transformValues[5] = sca4; std::string scale5 = ReadXMLStringAttribut( "SCALE5", atts ); double sca5 = atof(scale5.c_str()); transformValues[6] = sca5; std::string scale6 = ReadXMLStringAttribut( "SCALE6", atts ); double sca6 = atof(scale6.c_str()); transformValues[7] = sca6; std::string scale7 = ReadXMLStringAttribut( "SCALE7", atts ); double sca7 = atof(scale7.c_str()); transformValues[8] = sca7; std::string scale8 = ReadXMLStringAttribut( "SCALE8", atts ); double sca8 = atof(scale8.c_str()); transformValues[9] = sca8; std::string scale9 = ReadXMLStringAttribut( "SCALE9", atts ); double sca9 = atof(scale9.c_str()); transformValues[10] = sca9; std::string scale10 = ReadXMLStringAttribut( "SCALE10", atts ); double sca10 = atof(scale10.c_str()); transformValues[11] = sca10; std::string scale11 = ReadXMLStringAttribut( "SCALE11", atts ); double sca11 = atof(scale11.c_str()); transformValues[12] = sca11; std::string scale12 = ReadXMLStringAttribut( "SCALE12", atts ); double sca12 = atof(scale12.c_str()); transformValues[13] = sca12; std::string useInitializer = ReadXMLStringAttribut( "USEINITIALIZER", atts ); double useIni = atof(useInitializer.c_str()); transformValues[14] = useIni; std::string useMoments = ReadXMLStringAttribut( "USEMOMENTS", atts ); double useMo = atof(useMoments.c_str()); transformValues[15] = useMo; } else if (transform == mitk::TransformParameters::EULER3DTRANSFORM || transform == mitk::TransformParameters::CENTEREDEULER3DTRANSFORM || transform == mitk::TransformParameters::VERSORRIGID3DTRANSFORM) { std::string useScales = ReadXMLStringAttribut( "USESCALES", atts ); double useSca = atof(useScales.c_str()); transformValues[1] = useSca; std::string scale1 = ReadXMLStringAttribut( "SCALE1", atts ); double sca1 = atof(scale1.c_str()); transformValues[2] = sca1; std::string scale2 = ReadXMLStringAttribut( "SCALE2", atts ); double sca2 = atof(scale2.c_str()); transformValues[3] = sca2; std::string scale3 = ReadXMLStringAttribut( "SCALE3", atts ); double sca3 = atof(scale3.c_str()); transformValues[4] = sca3; std::string scale4 = ReadXMLStringAttribut( "SCALE4", atts ); double sca4 = atof(scale4.c_str()); transformValues[5] = sca4; std::string scale5 = ReadXMLStringAttribut( "SCALE5", atts ); double sca5 = atof(scale5.c_str()); transformValues[6] = sca5; std::string scale6 = ReadXMLStringAttribut( "SCALE6", atts ); double sca6 = atof(scale6.c_str()); transformValues[7] = sca6; std::string useInitializer = ReadXMLStringAttribut( "USEINITIALIZER", atts ); double useIni = atof(useInitializer.c_str()); transformValues[8] = useIni; std::string useMoments = ReadXMLStringAttribut( "USEMOMENTS", atts ); double useMo = atof(useMoments.c_str()); transformValues[9] = useMo; } else if (transform == mitk::TransformParameters::QUATERNIONRIGIDTRANSFORM || transform == mitk::TransformParameters::SIMILARITY3DTRANSFORM) { std::string useScales = ReadXMLStringAttribut( "USESCALES", atts ); double useSca = atof(useScales.c_str()); transformValues[1] = useSca; std::string scale1 = ReadXMLStringAttribut( "SCALE1", atts ); double sca1 = atof(scale1.c_str()); transformValues[2] = sca1; std::string scale2 = ReadXMLStringAttribut( "SCALE2", atts ); double sca2 = atof(scale2.c_str()); transformValues[3] = sca2; std::string scale3 = ReadXMLStringAttribut( "SCALE3", atts ); double sca3 = atof(scale3.c_str()); transformValues[4] = sca3; std::string scale4 = ReadXMLStringAttribut( "SCALE4", atts ); double sca4 = atof(scale4.c_str()); transformValues[5] = sca4; std::string scale5 = ReadXMLStringAttribut( "SCALE5", atts ); double sca5 = atof(scale5.c_str()); transformValues[6] = sca5; std::string scale6 = ReadXMLStringAttribut( "SCALE6", atts ); double sca6 = atof(scale6.c_str()); transformValues[7] = sca6; std::string scale7 = ReadXMLStringAttribut( "SCALE7", atts ); double sca7 = atof(scale7.c_str()); transformValues[8] = sca7; std::string useInitializer = ReadXMLStringAttribut( "USEINITIALIZER", atts ); double useIni = atof(useInitializer.c_str()); transformValues[9] = useIni; std::string useMoments = ReadXMLStringAttribut( "USEMOMENTS", atts ); double useMo = atof(useMoments.c_str()); transformValues[10] = useMo; } else if (transform == mitk::TransformParameters::SCALESKEWVERSOR3DTRANSFORM) { std::string useScales = ReadXMLStringAttribut( "USESCALES", atts ); double useSca = atof(useScales.c_str()); transformValues[1] = useSca; std::string scale1 = ReadXMLStringAttribut( "SCALE1", atts ); double sca1 = atof(scale1.c_str()); transformValues[2] = sca1; std::string scale2 = ReadXMLStringAttribut( "SCALE2", atts ); double sca2 = atof(scale2.c_str()); transformValues[3] = sca2; std::string scale3 = ReadXMLStringAttribut( "SCALE3", atts ); double sca3 = atof(scale3.c_str()); transformValues[4] = sca3; std::string scale4 = ReadXMLStringAttribut( "SCALE4", atts ); double sca4 = atof(scale4.c_str()); transformValues[5] = sca4; std::string scale5 = ReadXMLStringAttribut( "SCALE5", atts ); double sca5 = atof(scale5.c_str()); transformValues[6] = sca5; std::string scale6 = ReadXMLStringAttribut( "SCALE6", atts ); double sca6 = atof(scale6.c_str()); transformValues[7] = sca6; std::string scale7 = ReadXMLStringAttribut( "SCALE7", atts ); double sca7 = atof(scale7.c_str()); transformValues[8] = sca7; std::string scale8 = ReadXMLStringAttribut( "SCALE8", atts ); double sca8 = atof(scale8.c_str()); transformValues[9] = sca8; std::string scale9 = ReadXMLStringAttribut( "SCALE9", atts ); double sca9 = atof(scale9.c_str()); transformValues[10] = sca9; std::string scale10 = ReadXMLStringAttribut( "SCALE10", atts ); double sca10 = atof(scale10.c_str()); transformValues[11] = sca10; std::string scale11 = ReadXMLStringAttribut( "SCALE11", atts ); double sca11 = atof(scale11.c_str()); transformValues[12] = sca11; std::string scale12 = ReadXMLStringAttribut( "SCALE12", atts ); double sca12 = atof(scale12.c_str()); transformValues[13] = sca12; std::string scale13 = ReadXMLStringAttribut( "SCALE13", atts ); double sca13 = atof(scale13.c_str()); transformValues[14] = sca13; std::string scale14 = ReadXMLStringAttribut( "SCALE14", atts ); double sca14 = atof(scale14.c_str()); transformValues[15] = sca14; std::string scale15 = ReadXMLStringAttribut( "SCALE15", atts ); double sca15 = atof(scale15.c_str()); transformValues[16] = sca15; std::string useInitializer = ReadXMLStringAttribut( "USEINITIALIZER", atts ); double useIni = atof(useInitializer.c_str()); transformValues[17] = useIni; std::string useMoments = ReadXMLStringAttribut( "USEMOMENTS", atts ); double useMo = atof(useMoments.c_str()); transformValues[18] = useMo; } else if (transform == mitk::TransformParameters::CENTEREDRIGID2DTRANSFORM) { std::string useScales = ReadXMLStringAttribut( "USESCALES", atts ); double useSca = atof(useScales.c_str()); transformValues[1] = useSca; std::string scale1 = ReadXMLStringAttribut( "SCALE1", atts ); double sca1 = atof(scale1.c_str()); transformValues[2] = sca1; std::string scale2 = ReadXMLStringAttribut( "SCALE2", atts ); double sca2 = atof(scale2.c_str()); transformValues[3] = sca2; std::string scale3 = ReadXMLStringAttribut( "SCALE3", atts ); double sca3 = atof(scale3.c_str()); transformValues[4] = sca3; std::string scale4 = ReadXMLStringAttribut( "SCALE4", atts ); double sca4 = atof(scale4.c_str()); transformValues[5] = sca4; std::string scale5 = ReadXMLStringAttribut( "SCALE5", atts ); double sca5 = atof(scale5.c_str()); transformValues[6] = sca5; std::string angle = ReadXMLStringAttribut( "ANGLE", atts ); double ang = atof(angle.c_str()); transformValues[7] = ang; std::string useInitializer = ReadXMLStringAttribut( "USEINITIALIZER", atts ); double useIni = atof(useInitializer.c_str()); transformValues[8] = useIni; std::string useMoments = ReadXMLStringAttribut( "USEMOMENTS", atts ); double useMo = atof(useMoments.c_str()); transformValues[9] = useMo; } else if (transform == mitk::TransformParameters::SIMILARITY2DTRANSFORM) { std::string useScales = ReadXMLStringAttribut( "USESCALES", atts ); double useSca = atof(useScales.c_str()); transformValues[1] = useSca; std::string scale1 = ReadXMLStringAttribut( "SCALE1", atts ); double sca1 = atof(scale1.c_str()); transformValues[2] = sca1; std::string scale2 = ReadXMLStringAttribut( "SCALE2", atts ); double sca2 = atof(scale2.c_str()); transformValues[3] = sca2; std::string scale3 = ReadXMLStringAttribut( "SCALE3", atts ); double sca3 = atof(scale3.c_str()); transformValues[4] = sca3; std::string scale4 = ReadXMLStringAttribut( "SCALE4", atts ); double sca4 = atof(scale4.c_str()); transformValues[5] = sca4; std::string scale = ReadXMLStringAttribut( "SCALE", atts ); double sca = atof(scale.c_str()); transformValues[6] = sca; std::string angle = ReadXMLStringAttribut( "ANGLE", atts ); double ang = atof(angle.c_str()); transformValues[7] = ang; std::string useInitializer = ReadXMLStringAttribut( "USEINITIALIZER", atts ); double useIni = atof(useInitializer.c_str()); transformValues[8] = useIni; std::string useMoments = ReadXMLStringAttribut( "USEMOMENTS", atts ); double useMo = atof(useMoments.c_str()); transformValues[9] = useMo; } else if (transform == mitk::TransformParameters::CENTEREDSIMILARITY2DTRANSFORM) { std::string useScales = ReadXMLStringAttribut( "USESCALES", atts ); double useSca = atof(useScales.c_str()); transformValues[1] = useSca; std::string scale1 = ReadXMLStringAttribut( "SCALE1", atts ); double sca1 = atof(scale1.c_str()); transformValues[2] = sca1; std::string scale2 = ReadXMLStringAttribut( "SCALE2", atts ); double sca2 = atof(scale2.c_str()); transformValues[3] = sca2; std::string scale3 = ReadXMLStringAttribut( "SCALE3", atts ); double sca3 = atof(scale3.c_str()); transformValues[4] = sca3; std::string scale4 = ReadXMLStringAttribut( "SCALE4", atts ); double sca4 = atof(scale4.c_str()); transformValues[5] = sca4; std::string scale5 = ReadXMLStringAttribut( "SCALE5", atts ); double sca5 = atof(scale5.c_str()); transformValues[6] = sca5; std::string scale6 = ReadXMLStringAttribut( "SCALE6", atts ); double sca6 = atof(scale6.c_str()); transformValues[7] = sca6; std::string scale = ReadXMLStringAttribut( "SCALE", atts ); double sca = atof(scale.c_str()); transformValues[8] = sca; std::string angle = ReadXMLStringAttribut( "ANGLE", atts ); double ang = atof(angle.c_str()); transformValues[9] = ang; std::string useInitializer = ReadXMLStringAttribut( "USEINITIALIZER", atts ); double useIni = atof(useInitializer.c_str()); transformValues[10] = useIni; std::string useMoments = ReadXMLStringAttribut( "USEMOMENTS", atts ); double useMo = atof(useMoments.c_str()); transformValues[11] = useMo; } + + MITK_DEBUG("RigidRegistration.Preset.LoadValue ") << transformValues; return transformValues; } itk::Array RigidRegistrationPreset::loadMetricValues(itk::Array metricValues, double metric, const char **atts) { std::string computeGradient = ReadXMLStringAttribut( "COMPUTEGRADIENT", atts ); double compGra = atof(computeGradient.c_str()); metricValues[1] = compGra; if (metric == mitk::MetricParameters::MEANSQUARESIMAGETOIMAGEMETRIC || metric == mitk::MetricParameters::NORMALIZEDCORRELATIONIMAGETOIMAGEMETRIC || metric == mitk::MetricParameters::GRADIENTDIFFERENCEIMAGETOIMAGEMETRIC || metric == mitk::MetricParameters::MATCHCARDINALITYIMAGETOIMAGEMETRIC || metric == mitk::MetricParameters::KAPPASTATISTICIMAGETOIMAGEMETRIC) { } else if (metric == mitk::MetricParameters::KULLBACKLEIBLERCOMPAREHISTOGRAMIMAGETOIMAGEMETRIC || metric == mitk::MetricParameters::CORRELATIONCOEFFICIENTHISTOGRAMIMAGETOIMAGEMETRIC || metric == mitk::MetricParameters::MEANSQUARESHISTOGRAMIMAGETOIMAGEMETRIC || metric == mitk::MetricParameters::MUTUALINFORMATIONHISTOGRAMIMAGETOIMAGEMETRIC || metric == mitk::MetricParameters::NORMALIZEDMUTUALINFORMATIONHISTOGRAMIMAGETOIMAGEMETRIC) { std::string histogramBins = ReadXMLStringAttribut( "HISTOGRAMBINS", atts ); double histBins = atof(histogramBins.c_str()); metricValues[2] = histBins; } else if (metric == mitk::MetricParameters::MATTESMUTUALINFORMATIONIMAGETOIMAGEMETRIC) { std::string useSampling = ReadXMLStringAttribut( "USESAMPLING", atts ); double useSamp = atof(useSampling.c_str()); metricValues[2] = useSamp; std::string spatialSamples = ReadXMLStringAttribut( "SPATIALSAMPLES", atts ); double spatSamp = atof(spatialSamples.c_str()); metricValues[3] = spatSamp; std::string histogramBins = ReadXMLStringAttribut( "HISTOGRAMBINS", atts ); double histBins = atof(histogramBins.c_str()); metricValues[4] = histBins; } else if (metric == mitk::MetricParameters::MEANRECIPROCALSQUAREDIFFERENCEIMAGETOIMAGEMETRIC) { std::string lambda = ReadXMLStringAttribut( "LAMBDA", atts ); double lamb = atof(lambda.c_str()); metricValues[2] = lamb; } else if (metric == mitk::MetricParameters::MUTUALINFORMATIONIMAGETOIMAGEMETRIC) { std::string spatialSamples = ReadXMLStringAttribut( "SPATIALSAMPLES", atts ); double spatSamp = atof(spatialSamples.c_str()); metricValues[2] = spatSamp; std::string fixedStandardDeviation = ReadXMLStringAttribut( "FIXEDSTANDARDDEVIATION", atts ); double fiStaDev = atof(fixedStandardDeviation.c_str()); metricValues[3] = fiStaDev; std::string movingStandardDeviation = ReadXMLStringAttribut( "MOVINGSTANDARDDEVIATION", atts ); double moStaDev = atof(movingStandardDeviation.c_str()); metricValues[4] = moStaDev; std::string useNormalizer = ReadXMLStringAttribut( "USENORMALIZERANDSMOOTHER", atts ); double useNormal = atof(useNormalizer.c_str()); metricValues[5] = useNormal; std::string fixedSmootherVariance = ReadXMLStringAttribut( "FIXEDSMOOTHERVARIANCE", atts ); double fiSmoVa = atof(fixedSmootherVariance.c_str()); metricValues[6] = fiSmoVa; std::string movingSmootherVariance = ReadXMLStringAttribut( "MOVINGSMOOTHERVARIANCE", atts ); double moSmoVa = atof(movingSmootherVariance.c_str()); metricValues[7] = moSmoVa; } return metricValues; } itk::Array RigidRegistrationPreset::loadOptimizerValues(itk::Array optimizerValues, double optimizer, const char **atts) { std::string maximize = ReadXMLStringAttribut( "MAXIMIZE", atts ); double max = atof(maximize.c_str()); optimizerValues[1] = max; if (optimizer == mitk::OptimizerParameters::EXHAUSTIVEOPTIMIZER) { std::string stepLength = ReadXMLStringAttribut( "STEPLENGTH", atts ); double stepLe = atof(stepLength.c_str()); optimizerValues[2] = stepLe; std::string numberOfSteps = ReadXMLStringAttribut( "NUMBEROFSTEPS", atts ); double numSteps = atof(numberOfSteps.c_str()); optimizerValues[3] = numSteps; } else if (optimizer == mitk::OptimizerParameters::GRADIENTDESCENTOPTIMIZER || optimizer == mitk::OptimizerParameters::QUATERNIONRIGIDTRANSFORMGRADIENTDESCENTOPTIMIZER) { std::string learningRate = ReadXMLStringAttribut( "LEARNINGRATE", atts ); double learn = atof(learningRate.c_str()); optimizerValues[2] = learn; std::string numberIterations = ReadXMLStringAttribut( "NUMBERITERATIONS", atts ); double numIt = atof(numberIterations.c_str()); optimizerValues[3] = numIt; } else if (optimizer == mitk::OptimizerParameters::LBFGSBOPTIMIZER) { } else if (optimizer == mitk::OptimizerParameters::ONEPLUSONEEVOLUTIONARYOPTIMIZER) { std::string shrinkFactor = ReadXMLStringAttribut( "SHRINKFACTOR", atts ); double shrink = atof(shrinkFactor.c_str()); optimizerValues[2] = shrink; std::string growthFactor = ReadXMLStringAttribut( "GROWTHFACTOR", atts ); double growth = atof(growthFactor.c_str()); optimizerValues[3] = growth; std::string epsilon = ReadXMLStringAttribut( "EPSILON", atts ); double eps = atof(epsilon.c_str()); optimizerValues[4] = eps; std::string initialRadius = ReadXMLStringAttribut( "INITIALRADIUS", atts ); double initRad = atof(initialRadius.c_str()); optimizerValues[5] = initRad; std::string numberIterations = ReadXMLStringAttribut( "NUMBERITERATIONS", atts ); double numIt = atof(numberIterations.c_str()); optimizerValues[6] = numIt; } else if (optimizer == mitk::OptimizerParameters::POWELLOPTIMIZER) { std::string stepLength = ReadXMLStringAttribut( "STEPLENGTH", atts ); double stepLe = atof(stepLength.c_str()); optimizerValues[2] = stepLe; std::string stepTolerance = ReadXMLStringAttribut( "STEPTOLERANCE", atts ); double stepTo = atof(stepTolerance.c_str()); optimizerValues[3] = stepTo; std::string valueTolerance = ReadXMLStringAttribut( "VALUETOLERANCE", atts ); double valTo = atof(valueTolerance.c_str()); optimizerValues[4] = valTo; std::string numberIterations = ReadXMLStringAttribut( "NUMBERITERATIONS", atts ); double numIt = atof(numberIterations.c_str()); optimizerValues[5] = numIt; } else if (optimizer == mitk::OptimizerParameters::FRPROPTIMIZER) { std::string useFletchReeves = ReadXMLStringAttribut( "USEFLETCHREEVES", atts ); double useFleRe = atof(useFletchReeves.c_str()); optimizerValues[2] = useFleRe; std::string stepLength = ReadXMLStringAttribut( "STEPLENGTH", atts ); double stepLe = atof(stepLength.c_str()); optimizerValues[3] = stepLe; std::string numberIterations = ReadXMLStringAttribut( "NUMBERITERATIONS", atts ); double numIt = atof(numberIterations.c_str()); optimizerValues[4] = numIt; } else if (optimizer == mitk::OptimizerParameters::REGULARSTEPGRADIENTDESCENTOPTIMIZER) { std::string gradientMagnitudeTolerance = ReadXMLStringAttribut( "GRADIENTMAGNITUDETOLERANCE", atts ); double graMagTo = atof(gradientMagnitudeTolerance.c_str()); optimizerValues[2] = graMagTo; std::string minStepLength = ReadXMLStringAttribut( "MINSTEPLENGTH", atts ); double minStep = atof(minStepLength.c_str()); optimizerValues[3] = minStep; std::string maxStepLength = ReadXMLStringAttribut( "MAXSTEPLENGTH", atts ); double maxStep = atof(maxStepLength.c_str()); optimizerValues[4] = maxStep; std::string relaxationFactor = ReadXMLStringAttribut( "RELAXATIONFACTOR", atts ); double relFac = atof(relaxationFactor.c_str()); optimizerValues[5] = relFac; std::string numberIterations = ReadXMLStringAttribut( "NUMBERITERATIONS", atts ); double numIt = atof(numberIterations.c_str()); optimizerValues[6] = numIt; } else if (optimizer == mitk::OptimizerParameters::VERSORTRANSFORMOPTIMIZER || optimizer == mitk::OptimizerParameters::VERSORRIGID3DTRANSFORMOPTIMIZER) { std::string gradientMagnitudeTolerance = ReadXMLStringAttribut( "GRADIENTMAGNITUDETOLERANCE", atts ); double graMagTo = atof(gradientMagnitudeTolerance.c_str()); optimizerValues[2] = graMagTo; std::string minStepLength = ReadXMLStringAttribut( "MINSTEPLENGTH", atts ); double minStep = atof(minStepLength.c_str()); optimizerValues[3] = minStep; std::string maxStepLength = ReadXMLStringAttribut( "MAXSTEPLENGTH", atts ); double maxStep = atof(maxStepLength.c_str()); optimizerValues[4] = maxStep; std::string numberIterations = ReadXMLStringAttribut( "NUMBERITERATIONS", atts ); double numIt = atof(numberIterations.c_str()); optimizerValues[5] = numIt; } else if (optimizer == mitk::OptimizerParameters::AMOEBAOPTIMIZER) { std::string simplexDelta1 = ReadXMLStringAttribut( "SIMPLEXDELTA1", atts ); double simpDel1 = atof(simplexDelta1.c_str()); optimizerValues[2] = simpDel1; std::string simplexDelta2 = ReadXMLStringAttribut( "SIMPLEXDELTA2", atts ); double simpDel2 = atof(simplexDelta2.c_str()); optimizerValues[3] = simpDel2; std::string simplexDelta3 = ReadXMLStringAttribut( "SIMPLEXDELTA3", atts ); double simpDel3 = atof(simplexDelta3.c_str()); optimizerValues[4] = simpDel3; std::string simplexDelta4 = ReadXMLStringAttribut( "SIMPLEXDELTA4", atts ); double simpDel4 = atof(simplexDelta4.c_str()); optimizerValues[5] = simpDel4; std::string simplexDelta5 = ReadXMLStringAttribut( "SIMPLEXDELTA5", atts ); double simpDel5 = atof(simplexDelta5.c_str()); optimizerValues[6] = simpDel5; std::string simplexDelta6 = ReadXMLStringAttribut( "SIMPLEXDELTA6", atts ); double simpDel6 = atof(simplexDelta6.c_str()); optimizerValues[7] = simpDel6; std::string simplexDelta7 = ReadXMLStringAttribut( "SIMPLEXDELTA7", atts ); double simpDel7 = atof(simplexDelta7.c_str()); optimizerValues[8] = simpDel7; std::string simplexDelta8 = ReadXMLStringAttribut( "SIMPLEXDELTA8", atts ); double simpDel8 = atof(simplexDelta8.c_str()); optimizerValues[9] = simpDel8; std::string simplexDelta9 = ReadXMLStringAttribut( "SIMPLEXDELTA9", atts ); double simpDel9 = atof(simplexDelta9.c_str()); optimizerValues[10] = simpDel9; std::string simplexDelta10 = ReadXMLStringAttribut( "SIMPLEXDELTA10", atts ); double simpDel10 = atof(simplexDelta10.c_str()); optimizerValues[11] = simpDel10; std::string simplexDelta11 = ReadXMLStringAttribut( "SIMPLEXDELTA11", atts ); double simpDel11 = atof(simplexDelta11.c_str()); optimizerValues[12] = simpDel11; std::string simplexDelta12 = ReadXMLStringAttribut( "SIMPLEXDELTA12", atts ); double simpDel12 = atof(simplexDelta12.c_str()); optimizerValues[13] = simpDel12; std::string simplexDelta13 = ReadXMLStringAttribut( "SIMPLEXDELTA13", atts ); double simpDel13 = atof(simplexDelta13.c_str()); optimizerValues[14] = simpDel13; std::string simplexDelta14 = ReadXMLStringAttribut( "SIMPLEXDELTA14", atts ); double simpDel14 = atof(simplexDelta14.c_str()); optimizerValues[15] = simpDel14; std::string simplexDelta15 = ReadXMLStringAttribut( "SIMPLEXDELTA15", atts ); double simpDel15 = atof(simplexDelta15.c_str()); optimizerValues[16] = simpDel15; std::string simplexDelta16 = ReadXMLStringAttribut( "SIMPLEXDELTA16", atts ); double simpDel16 = atof(simplexDelta16.c_str()); optimizerValues[17] = simpDel16; std::string parametersConvergenceTolerance = ReadXMLStringAttribut( "PARAMETERSCONVERGENCETOLERANCE", atts ); double paramConv = atof(parametersConvergenceTolerance.c_str()); optimizerValues[18] = paramConv; std::string functionConvergenceTolerance = ReadXMLStringAttribut( "FUNCTIONCONVERGENCETOLERANCE", atts ); double funcConv = atof(functionConvergenceTolerance.c_str()); optimizerValues[19] = funcConv; std::string numberIterations = ReadXMLStringAttribut( "NUMBERITERATIONS", atts ); double numIt = atof(numberIterations.c_str()); optimizerValues[20] = numIt; } else if (optimizer == mitk::OptimizerParameters::CONJUGATEGRADIENTOPTIMIZER) { } else if (optimizer == mitk::OptimizerParameters::LBFGSOPTIMIZER) { std::string GradientConvergenceTolerance = ReadXMLStringAttribut( "GRADIENTCONVERGENCETOLERANCE", atts ); double graConTo = atof(GradientConvergenceTolerance.c_str()); optimizerValues[2] = graConTo; std::string lineSearchAccuracy = ReadXMLStringAttribut( "LINESEARCHACCURACY", atts ); double lineSearch = atof(lineSearchAccuracy.c_str()); optimizerValues[3] = lineSearch; std::string defaultStepLength = ReadXMLStringAttribut( "DEFAULTSTEPLENGTH", atts ); double defStep = atof(defaultStepLength.c_str()); optimizerValues[4] = defStep; std::string numberIterations = ReadXMLStringAttribut( "NUMBERITERATIONS", atts ); double numIt = atof(numberIterations.c_str()); optimizerValues[5] = numIt; std::string useTrace = ReadXMLStringAttribut( "USETRACE", atts ); double useTr = atof(useTrace.c_str()); optimizerValues[6] = useTr; } else if (optimizer == mitk::OptimizerParameters::SPSAOPTIMIZER) { std::string a = ReadXMLStringAttribut( "a", atts ); double a1 = atof(a.c_str()); optimizerValues[2] = a1; std::string a2 = ReadXMLStringAttribut( "A", atts ); double a3 = atof(a2.c_str()); optimizerValues[3] = a3; std::string alpha = ReadXMLStringAttribut( "ALPHA", atts ); double alp = atof(alpha.c_str()); optimizerValues[4] = alp; std::string c = ReadXMLStringAttribut( "c", atts ); double c1 = atof(c.c_str()); optimizerValues[5] = c1; std::string gamma = ReadXMLStringAttribut( "GAMMA", atts ); double gam = atof(gamma.c_str()); optimizerValues[6] = gam; std::string tolerance = ReadXMLStringAttribut( "TOLERANCE", atts ); double tol = atof(tolerance.c_str()); optimizerValues[7] = tol; std::string stateOfConvergenceDecayRate = ReadXMLStringAttribut( "STATEOFCONVERGENCEDECAYRATE", atts ); double stateOfConvergence = atof(stateOfConvergenceDecayRate.c_str()); optimizerValues[8] = stateOfConvergence; std::string minNumberIterations = ReadXMLStringAttribut( "MINNUMBERITERATIONS", atts ); double minNumIt = atof(minNumberIterations.c_str()); optimizerValues[9] = minNumIt; std::string numberPerturbations = ReadXMLStringAttribut( "NUMBERPERTURBATIONS", atts ); double numPer = atof(numberPerturbations.c_str()); optimizerValues[10] = numPer; std::string numberIterations = ReadXMLStringAttribut( "NUMBERITERATIONS", atts ); double numIt = atof(numberIterations.c_str()); optimizerValues[11] = numIt; } return optimizerValues; } itk::Array RigidRegistrationPreset::loadInterpolatorValues(itk::Array interpolatorValues/*, double interpolator, const char **atts*/) { return interpolatorValues; } } diff --git a/Modules/RigidRegistration/mitkTransformParameters.h b/Modules/RigidRegistration/mitkTransformParameters.h index 3b5479d76f..c602aebbc8 100644 --- a/Modules/RigidRegistration/mitkTransformParameters.h +++ b/Modules/RigidRegistration/mitkTransformParameters.h @@ -1,212 +1,211 @@ /*=================================================================== 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. ===================================================================*/ #ifndef MITKTRANSFORMPARAMETERS_H #define MITKTRANSFORMPARAMETERS_H #include #include "MitkRigidRegistrationExports.h" #include #include "mitkCommon.h" namespace mitk { /*! \brief This class is used to hold all transform parameters needed for a rigid registration process. To use the rigid registration framework you have to create an instance of this class and fill it with the parameters belonging to the selected transformation. To let the rigid registration work properly, this instance has to be given to mitkImageRegistrationMethod before calling the update() method in mitkImageRegistrationMethod. Also instances of the classes mitkMetricParameters and mitkOptimizerParameters have to be set in mitkImageRegistrationMethod before calling the update() method. \ingroup RigidRegistration \author Daniel Stein */ class MITKRIGIDREGISTRATION_EXPORT TransformParameters : public itk::Object { public: mitkClassMacroItkParent(TransformParameters, ::itk::Object); itkFactorylessNewMacro(Self) itkCloneMacro(Self) /** \brief Unique integer value for every transform. */ enum TransformType { TRANSLATIONTRANSFORM = 0, - SCALETRANSFORM = 1, - SCALELOGARITHMICTRANSFORM = 2, - AFFINETRANSFORM = 3, - FIXEDCENTEROFROTATIONAFFINETRANSFORM = 4, - RIGID3DTRANSFORM = 5, //TODO remove rigid3dTrassform - EULER3DTRANSFORM = 6, - CENTEREDEULER3DTRANSFORM = 7, - QUATERNIONRIGIDTRANSFORM = 8, - VERSORTRANSFORM = 9, - VERSORRIGID3DTRANSFORM = 10, - SCALESKEWVERSOR3DTRANSFORM = 11, - SIMILARITY3DTRANSFORM = 12, - RIGID2DTRANSFORM = 13, - CENTEREDRIGID2DTRANSFORM = 14, - EULER2DTRANSFORM = 15, - SIMILARITY2DTRANSFORM = 16, - CENTEREDSIMILARITY2DTRANSFORM = 17 + SCALETRANSFORM, + SCALELOGARITHMICTRANSFORM, + AFFINETRANSFORM, + FIXEDCENTEROFROTATIONAFFINETRANSFORM, + EULER3DTRANSFORM, + CENTEREDEULER3DTRANSFORM, + QUATERNIONRIGIDTRANSFORM, + VERSORTRANSFORM, + VERSORRIGID3DTRANSFORM, + SCALESKEWVERSOR3DTRANSFORM, + SIMILARITY3DTRANSFORM, + RIGID2DTRANSFORM, + CENTEREDRIGID2DTRANSFORM, + EULER2DTRANSFORM, + SIMILARITY2DTRANSFORM, + CENTEREDSIMILARITY2DTRANSFORM }; /** \brief Sets the transform used for registration by its unique integer value. */ itkSetMacro( Transform, int ); /** \brief Returns the transform used for registration by its unique integer value. */ itkGetMacro( Transform, int ); /** \brief Sets an array that holds the magnitudes of changes for the transforms degrees of freedom. The optimizer changes the transforms values corresponding to this array values. */ void SetScales(itk::Array scales); /** \brief Returns an array that holds the magnitudes of changes for the transforms degrees of freedom. The optimizer changes the transforms values corresponding to this array values. */ itk::Array GetScales(); /** \brief Sets an array that holds the initial transform parameters. */ void SetInitialParameters(itk::Array initialParameters); /** \brief Returns an array that holds the initial transform parameters. */ itk::Array GetInitialParameters(); /** \brief Sets whether a transform initializer will be used. True = initializer is used, initializer is not used. */ itkSetMacro( TransformInitializerOn, bool ); /** \brief Returns whether a transform initializer will be used. True = initializer is used, false = initializer is not used. */ itkGetMacro( TransformInitializerOn, bool ); /** \brief Sets whether the transform initializer will be used to align the images moments or their centers. True = image moments will be aligned, false = image centers will be aligned. */ itkSetMacro( MomentsOn, bool ); /** \brief Returns whether the transform initializer will be used to align the images moments or their centers. True = image moments will be aligned, false = image centers will be aligned. */ itkGetMacro( MomentsOn, bool ); /** \brief Sets whether the optimizer scales will be used to let the optimizer know about different magnitudes for the transforms degrees of freedom. True = optimizer scales will be used, false = optimizer scales will not be used. */ itkSetMacro( UseOptimizerScales, bool ); /** \brief Returns whether the optimizer scales will be used to let the optimizer know about different magnitudes for the transforms degrees of freedom. True = optimizer scales will be used, false = optimizer scales will not be used. */ itkGetMacro( UseOptimizerScales, bool ); /** \brief Sets the initial angle for transforms. */ itkSetMacro( Angle, float ); /** \brief Returns the initial angle for transforms. */ itkGetMacro( Angle, float ); /** \brief Sets the transforms initial scale. */ itkSetMacro( Scale, float ); /** \brief Returns the transforms initial scale. */ itkGetMacro( Scale, float ); /** \brief This setter is used by the mitkTransformFactory to set the transforms initial center in X direction. */ itkSetMacro( TransformCenterX, double ); /** \brief Returns the transforms initial center in X direction. */ itkGetMacro( TransformCenterX, double ); /** \brief This setter is used by the mitkTransformFactory to set the transforms initial center in Y direction. */ itkSetMacro( TransformCenterY, double ); /** \brief Returns the transforms initial center in Y direction. */ itkGetMacro( TransformCenterY, double ); /** \brief This setter is used by the mitkTransformFactory to set the transforms initial center in Z direction. */ itkSetMacro( TransformCenterZ, double ); /** \brief Returns the transforms initial center in Z direction. */ itkGetMacro( TransformCenterZ, double ); protected: TransformParameters(); ~TransformParameters() {}; int m_Transform; float m_Angle; float m_Scale; bool m_TransformInitializerOn; bool m_MomentsOn; bool m_UseOptimizerScales; double m_TransformCenterX; double m_TransformCenterY; double m_TransformCenterZ; itk::Array m_Scales; itk::Array m_InitialParameters; }; } // namespace mitk #endif // MITKTRANSFORMPARAMETERS_H diff --git a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationSelectorView.cpp b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationSelectorView.cpp index 1606abbeac..920786aaee 100644 --- a/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationSelectorView.cpp +++ b/Plugins/org.mitk.gui.qt.registration/src/internal/QmitkRigidRegistrationSelectorView.cpp @@ -1,764 +1,773 @@ /*=================================================================== 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 "mitkImageTimeSelector.h" #include #include #include #include "mitkMatrixConvert.h" #include #include #include "QmitkLoadPresetDialog.h" #include #include "mitkRigidRegistrationPreset.h" #include "mitkProgressBar.h" #include "QmitkRigidRegistrationSelectorView.h" #include "QmitkTranslationTransformView.h" #include "QmitkScaleTransformView.h" #include "QmitkScaleLogarithmicTransformView.h" #include "QmitkAffineTransformView.h" #include "QmitkFixedCenterOfRotationAffineTransformView.h" #include "QmitkEuler3DTransformView.h" #include "QmitkCenteredEuler3DTransformView.h" #include "QmitkQuaternionRigidTransformView.h" #include "QmitkVersorTransformView.h" #include "QmitkVersorRigid3DTransformView.h" #include "QmitkScaleSkewVersor3DTransformView.h" #include "QmitkSimilarity3DTransformView.h" #include "QmitkRigid2DTransformView.h" #include "QmitkCenteredRigid2DTransformView.h" #include "QmitkEuler2DTransformView.h" #include "QmitkSimilarity2DTransformView.h" #include "QmitkCenteredSimilarity2DTransformView.h" #include "QmitkMeanSquaresMetricView.h" #include "QmitkNormalizedCorrelationMetricView.h" #include "QmitkGradientDifferenceMetricView.h" #include "QmitkKullbackLeiblerCompareHistogramMetricView.h" #include "QmitkCorrelationCoefficientHistogramMetricView.h" #include "QmitkMeanSquaresHistogramMetricView.h" #include "QmitkMutualInformationHistogramMetricView.h" #include "QmitkNormalizedMutualInformationHistogramMetricView.h" #include "QmitkMattesMutualInformationMetricView.h" #include "QmitkMeanReciprocalSquareDifferenceMetricView.h" #include "QmitkMutualInformationMetricView.h" #include "QmitkMatchCardinalityMetricView.h" #include "QmitkKappaStatisticMetricView.h" #include "QmitkExhaustiveOptimizerView.h" #include "QmitkGradientDescentOptimizerView.h" #include "QmitkQuaternionRigidTransformGradientDescentOptimizerView.h" #include "QmitkLBFGSBOptimizerView.h" #include "QmitkOnePlusOneEvolutionaryOptimizerView.h" #include "QmitkPowellOptimizerView.h" #include "QmitkFRPROptimizerView.h" #include "QmitkRegularStepGradientDescentOptimizerView.h" #include "QmitkVersorTransformOptimizerView.h" #include "QmitkAmoebaOptimizerView.h" #include "QmitkConjugateGradientOptimizerView.h" #include "QmitkLBFGSOptimizerView.h" #include "QmitkSPSAOptimizerView.h" #include "QmitkVersorRigid3DTransformOptimizerView.h" QmitkRigidRegistrationSelectorView::QmitkRigidRegistrationSelectorView(QWidget* parent, Qt::WindowFlags f ) : QWidget( parent, f ), m_FixedNode(nullptr), m_FixedMaskNode(nullptr), m_MovingNode(nullptr), m_MovingMaskNode(nullptr), m_FixedDimension(0), m_MovingDimension(0), m_StopOptimization(false), m_GeometryItkPhysicalToWorldTransform(nullptr), m_GeometryWorldToItkPhysicalTransform(nullptr), m_MovingGeometry(nullptr), m_ImageGeometry(nullptr) { m_Controls.setupUi(parent); this->AddTransform(new QmitkTranslationTransformView(this, f)); this->AddTransform(new QmitkScaleTransformView(this, f)); this->AddTransform(new QmitkScaleLogarithmicTransformView(this, f)); this->AddTransform(new QmitkAffineTransformView(this, f)); this->AddTransform(new QmitkFixedCenterOfRotationAffineTransformView(this, f)); this->AddTransform(new QmitkEuler3DTransformView(this, f)); this->AddTransform(new QmitkCenteredEuler3DTransformView(this, f)); this->AddTransform(new QmitkQuaternionRigidTransformView(this, f)); this->AddTransform(new QmitkVersorTransformView(this, f)); this->AddTransform(new QmitkVersorRigid3DTransformView(this, f)); this->AddTransform(new QmitkScaleSkewVersor3DTransformView(this, f)); this->AddTransform(new QmitkSimilarity3DTransformView(this, f)); this->AddTransform(new QmitkRigid2DTransformView(this, f)); this->AddTransform(new QmitkCenteredRigid2DTransformView(this, f)); this->AddTransform(new QmitkEuler2DTransformView(this, f)); this->AddTransform(new QmitkSimilarity2DTransformView(this, f)); this->AddTransform(new QmitkCenteredSimilarity2DTransformView(this, f)); this->AddMetric(new QmitkMeanSquaresMetricView(this, f)); this->AddMetric(new QmitkNormalizedCorrelationMetricView(this, f)); this->AddMetric(new QmitkGradientDifferenceMetricView(this, f)); this->AddMetric(new QmitkKullbackLeiblerCompareHistogramMetricView(this, f)); this->AddMetric(new QmitkCorrelationCoefficientHistogramMetricView(this, f)); this->AddMetric(new QmitkMeanSquaresHistogramMetricView(this, f)); this->AddMetric(new QmitkMutualInformationHistogramMetricView(this, f)); this->AddMetric(new QmitkNormalizedMutualInformationHistogramMetricView(this, f)); this->AddMetric(new QmitkMattesMutualInformationMetricView(this, f)); this->AddMetric(new QmitkMeanReciprocalSquareDifferenceMetricView(this, f)); this->AddMetric(new QmitkMutualInformationMetricView(this, f)); this->AddMetric(new QmitkMatchCardinalityMetricView(this, f)); this->AddMetric(new QmitkKappaStatisticMetricView(this, f)); this->AddOptimizer(new QmitkExhaustiveOptimizerView(this, f)); this->AddOptimizer(new QmitkGradientDescentOptimizerView(this, f)); this->AddOptimizer(new QmitkQuaternionRigidTransformGradientDescentOptimizerView(this, f)); this->AddOptimizer(new QmitkLBFGSBOptimizerView(this, f)); this->AddOptimizer(new QmitkOnePlusOneEvolutionaryOptimizerView(this, f)); this->AddOptimizer(new QmitkPowellOptimizerView(this, f)); this->AddOptimizer(new QmitkFRPROptimizerView(this, f)); this->AddOptimizer(new QmitkRegularStepGradientDescentOptimizerView(this, f)); this->AddOptimizer(new QmitkVersorTransformOptimizerView(this, f)); this->AddOptimizer(new QmitkAmoebaOptimizerView(this, f)); this->AddOptimizer(new QmitkConjugateGradientOptimizerView(this, f)); this->AddOptimizer(new QmitkLBFGSOptimizerView(this, f)); this->AddOptimizer(new QmitkSPSAOptimizerView(this, f)); this->AddOptimizer(new QmitkVersorRigid3DTransformOptimizerView(this, f)); m_Observer = mitk::RigidRegistrationObserver::New(); m_Controls.m_TransformFrame->setEnabled(true); m_Controls.m_MetricFrame->setEnabled(true); m_Controls.m_OptimizerFrame->setEnabled(true); m_Controls.m_InterpolatorFrame->setEnabled(true); m_Controls.m_TransformFrame->hide(); m_Controls.m_MetricFrame->hide(); m_Controls.m_OptimizerFrame->hide(); m_Controls.m_InterpolatorFrame->hide(); m_Controls.m_TransformBox->setCurrentIndex(0); m_Controls.m_MetricBox->setCurrentIndex(0); m_Controls.m_OptimizerBox->setCurrentIndex(0); m_Controls.m_TransformWidgetStack->setCurrentIndex(0); m_Controls.m_MetricWidgetStack->setCurrentIndex(0); m_Controls.m_OptimizerWidgetStack->setCurrentIndex(0); /// and show the selected views this->TransformSelected(m_Controls.m_TransformBox->currentIndex()); this->MetricSelected(m_Controls.m_MetricBox->currentIndex()); this->OptimizerSelected(m_Controls.m_OptimizerBox->currentIndex()); //// create connections connect( m_Controls.m_TransformGroup, SIGNAL(clicked(bool)), m_Controls.m_TransformFrame, SLOT(setVisible(bool))); connect( m_Controls.m_TransformBox, SIGNAL(activated(int)), m_Controls.m_TransformWidgetStack, SLOT(setCurrentIndex(int))); connect( m_Controls.m_TransformBox, SIGNAL(activated(int)), this, SLOT(TransformSelected(int))); connect( m_Controls.m_MetricBox, SIGNAL(activated(int)), this, SLOT(MetricSelected(int))); connect( m_Controls.m_OptimizerBox, SIGNAL(activated(int)), this, SLOT(OptimizerSelected(int))); connect( m_Controls.m_MetricGroup, SIGNAL(clicked(bool)), m_Controls.m_MetricFrame, SLOT(setVisible(bool))); connect( m_Controls.m_MetricBox, SIGNAL(activated(int)), m_Controls.m_MetricWidgetStack, SLOT(setCurrentIndex(int))); connect( m_Controls.m_OptimizerGroup, SIGNAL(clicked(bool)), m_Controls.m_OptimizerFrame, SLOT(setVisible(bool))); connect( m_Controls.m_OptimizerBox, SIGNAL(activated(int)), m_Controls.m_OptimizerWidgetStack, SLOT(setCurrentIndex(int))); connect( m_Controls.m_InterpolatorGroup, SIGNAL(toggled(bool)), m_Controls.m_InterpolatorFrame, SLOT(setVisible(bool))); m_Preset = new mitk::RigidRegistrationPreset(); m_Preset->LoadPreset(); - this->DoLoadRigidRegistrationPreset("Affine3DMutualInformation_LinearInterp"); + this->DoLoadRigidRegistrationPreset("Affine3D_MattesMutualInf_LinearInterp"); } QmitkRigidRegistrationSelectorView::~QmitkRigidRegistrationSelectorView() { } /// this method starts the registration process void QmitkRigidRegistrationSelectorView::CalculateTransformation(unsigned int timestep) { if (m_FixedNode.IsNotNull() && m_MovingNode.IsNotNull()) { emit AddNewTransformationToUndoList(); mitk::Image::Pointer fimage = dynamic_cast(m_FixedNode->GetData())->Clone(); mitk::Image::Pointer mimage = dynamic_cast(m_MovingNode->GetData())->Clone(); mitk::Image::Pointer mmimage = nullptr; mitk::Image::Pointer fmimage = nullptr; if (m_MovingMaskNode.IsNotNull()) { mmimage = dynamic_cast(m_MovingMaskNode->GetData()); } if (m_FixedMaskNode.IsNotNull()) { fmimage = dynamic_cast(m_FixedMaskNode->GetData()); } mitk::ImageTimeSelector::Pointer its = mitk::ImageTimeSelector::New(); if(fimage->GetDimension()>3) { its->SetInput(fimage); its->SetTimeNr(timestep); its->Update(); fimage = its->GetOutput(); } if(mimage->GetDimension()>3) { its->SetInput(mimage); its->SetTimeNr(timestep); its->Update(); mimage = its->GetOutput(); } // Initial moving image geometry m_ImageGeometry = m_MovingNode->GetData()->GetGeometry()->Clone(); std::cout << "Moving Image Geometry (IndexToWorldTransform)" << std::endl; std::cout << m_ImageGeometry->GetIndexToWorldTransform()->GetMatrix(); mitk::BaseGeometry::TransformType::InputPointType center = m_ImageGeometry->GetIndexToWorldTransform()->GetCenter(); std::cout << "center " << center[0] << " " << center[1] << " " << center[2] << std::endl; mitk::BaseGeometry::TransformType::OutputVectorType offset = m_ImageGeometry->GetIndexToWorldTransform()->GetOffset(); std::cout << "offset " << offset[0] << " " << offset[1] << " " << offset[2] << std::endl; std::cout << std::endl; // Calculate the World to ITK-Physical transform for the moving image m_MovingGeometry = m_MovingNode->GetData()->GetGeometry(); // container that holds all derived moving data, that needs to be transformed with the transformation found by registration if(m_MovingMaskNode.IsNotNull()) { m_ChildNodes.insert(std::pair(m_MovingMaskNode, m_MovingMaskNode->GetData()->GetGeometry()));; m_ChildNodes2.insert(std::pair(m_MovingMaskNode, m_MovingMaskNode->GetData()->GetGeometry()->Clone())); } if(m_MovingNodeChildren.IsNotNull()) { unsigned long size = 0; size = m_MovingNodeChildren->Size(); for (unsigned long i = 0; i < size; ++i) { m_ChildNodes.insert(std::pair(m_MovingNodeChildren->GetElement(i), m_MovingNodeChildren->GetElement(i)->GetData()->GetGeometry())); mitk::BaseGeometry::Pointer lopointer = m_MovingNodeChildren->GetElement(i)->GetData()->GetGeometry()->Clone(); m_ChildNodes2.insert(std::pair(m_MovingNodeChildren->GetElement(i), lopointer)); } } m_GeometryWorldToItkPhysicalTransform = mitk::BaseGeometry::TransformType::New(); GetWorldToItkPhysicalTransform(m_MovingGeometry, m_GeometryWorldToItkPhysicalTransform.GetPointer()); // Calculate the ITK-Physical to World transform for the fixed image m_GeometryItkPhysicalToWorldTransform = mitk::BaseGeometry::TransformType::New(); mitk::BaseGeometry::TransformType::Pointer fixedWorld2Phys = mitk::BaseGeometry::TransformType::New(); GetWorldToItkPhysicalTransform(m_FixedNode->GetData()->GetGeometry(), fixedWorld2Phys.GetPointer()); fixedWorld2Phys->GetInverse(m_GeometryItkPhysicalToWorldTransform); // init callback itk::ReceptorMemberCommand::Pointer command = itk::ReceptorMemberCommand::New(); command->SetCallbackFunction(this, &QmitkRigidRegistrationSelectorView::SetOptimizerValue); int observer = m_Observer->AddObserver( itk::AnyEvent(), command ); std::vector presets; // init registration method mitk::ImageRegistrationMethod::Pointer registration = mitk::ImageRegistrationMethod::New(); registration->SetNumberOfLevels(3); registration->SetObserver(m_Observer); registration->SetInterpolator(m_Controls.m_InterpolatorBox->currentIndex()); registration->SetReferenceImage(fimage); registration->SetInput(mimage); if (mmimage.IsNotNull()) { registration->SetMovingMask(mmimage); } if (fmimage.IsNotNull()) { registration->SetFixedMask(fmimage); } - dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->SetFixedImage(dynamic_cast(m_FixedNode->GetData())); - dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->SetMovingImage(dynamic_cast(m_MovingNode->GetData())); - registration->SetOptimizerScales(dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->GetScales()); - registration->SetTransform(dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->GetTransform() ); + QmitkRigidRegistrationTransformsGUIBase* current_transform = dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget()); + QmitkRigidRegistrationMetricsGUIBase* current_metric = dynamic_cast(m_Controls.m_MetricWidgetStack->currentWidget()); - dynamic_cast(m_Controls.m_MetricWidgetStack->currentWidget())->SetMovingImage(dynamic_cast(m_MovingNode->GetData())); - registration->SetMetric(dynamic_cast(m_Controls.m_MetricWidgetStack->currentWidget())->GetMetric()); + current_transform->SetFixedImage( dynamic_cast( m_FixedNode->GetData()) ); + current_transform->SetMovingImage( dynamic_cast( m_MovingNode->GetData()) ); + registration->SetOptimizerScales( current_transform->GetScales() ); + registration->SetTransform( current_transform->GetTransform() ); - registration->SetOptimizer(dynamic_cast(m_Controls.m_OptimizerWidgetStack->currentWidget())->GetOptimizer()); + current_metric->SetMovingImage( dynamic_cast( m_MovingNode->GetData()) ); + registration->SetMetric( current_metric->GetMetric() ); + + registration->SetOptimizer( dynamic_cast(m_Controls.m_OptimizerWidgetStack->currentWidget())->GetOptimizer() ); double time(0.0); double tstart(0.0); tstart = clock(); try { registration->Update(); } catch (itk::ExceptionObject e) { - MITK_INFO << "Caught exception: "<Progress(20); } time += clock() - tstart; time = time / CLOCKS_PER_SEC; //printOut of the Time MITK_INFO << "Registration Time: " << time; m_Observer->RemoveObserver(observer); mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } } void QmitkRigidRegistrationSelectorView::SetFixedNode( mitk::DataNode * fixedNode ) { m_FixedNode = fixedNode; m_Controls.m_TransformBox->setCurrentIndex(m_Controls.m_TransformBox->currentIndex()); } void QmitkRigidRegistrationSelectorView::SetFixedDimension( int dimension ) { m_FixedDimension = dimension; } void QmitkRigidRegistrationSelectorView::SetMovingNode( mitk::DataNode * movingNode ) { m_MovingNode = movingNode; this->TransformSelected(m_Controls.m_TransformBox->currentIndex()); } void QmitkRigidRegistrationSelectorView::SetMovingDimension(int dimension ) { m_MovingDimension = dimension; } // this is a callback function that retrieves the current transformation // parameters after every step of progress in the optimizer. // depending on the choosen transformation, we construct a vtktransform // that will be applied to the geometry of the moving image. // the values are delivered by mitkRigidRgistrationObserver.cpp void QmitkRigidRegistrationSelectorView::SetOptimizerValue( const itk::EventObject & ) { if (m_StopOptimization) { m_Observer->SetStopOptimization(true); m_StopOptimization = false; } // retreive optimizer value for the current transformation double value = m_Observer->GetCurrentOptimizerValue(); // retreive current parameterset of the transformation itk::Array transformParams = m_Observer->GetCurrentTranslation(); // init an empty affine transformation that will be filled with // the corresponding transformation parameters in the following vtkMatrix4x4* vtkmatrix = vtkMatrix4x4::New(); vtkmatrix->Identity(); // init a transform that will be initialized with the vtkmatrix later vtkTransform* vtktransform = vtkTransform::New(); if (m_MovingNode.IsNotNull()) { vtktransform = dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->Transform(vtkmatrix, vtktransform, transformParams); // the retrieved transform goes from fixed to moving space. // invert the transform in order to go from moving to fixed space. vtkMatrix4x4* vtkmatrix_inv = vtkMatrix4x4::New(); vtktransform->GetInverse(vtkmatrix_inv); // now adapt the moving geometry accordingly m_MovingGeometry->GetIndexToWorldTransform()->SetIdentity(); // the next view lines: Phi(Phys2World)*Phi(Result)*Phi(World2Phy)*Phi(Initial) // set moving image geometry to registration result m_MovingGeometry->SetIndexToWorldTransformByVtkMatrix(vtkmatrix_inv); /*std::cout << std::endl; std::cout << m_MovingGeometry->GetIndexToWorldTransform()->GetMatrix(); mitk::Geometry3D::TransformType::OutputVectorType offset = m_MovingGeometry->GetIndexToWorldTransform()->GetOffset(); std::cout << "offset " << offset[0] << " " << offset[1] << " " << offset[2] << std::endl;*/ #if !defined(ITK_IMAGE_BEHAVES_AS_ORIENTED_IMAGE) // the next few lines: Phi(Phys2World)*Phi(Result)*Phi(World2Phy)*Phi(Initial) // go to itk physical space before applying the registration result m_MovingGeometry->Compose(m_GeometryWorldToItkPhysicalTransform, 1); // right in the beginning, transform by initial moving image geometry m_MovingGeometry->Compose(m_ImageGeometry->GetIndexToWorldTransform(), 1); // in the end, go back to world space m_MovingGeometry->Compose(m_GeometryItkPhysicalToWorldTransform, 0); #else m_MovingGeometry->Compose(m_ImageGeometry->GetIndexToWorldTransform(), 1); #endif /*std::cout << std::endl << m_MovingGeometry->GetIndexToWorldTransform()->GetMatrix(); offset = m_MovingGeometry->GetIndexToWorldTransform()->GetOffset(); std::cout << "offset " << offset[0] << " " << offset[1] << " " << offset[2] << std::endl << std::endl;*/ // now adapt all children geometries accordingly if children exist std::map::iterator iter; std::map::iterator iter2; mitk::DataNode::Pointer childNode; for( iter = m_ChildNodes.begin(); iter != m_ChildNodes.end(); iter++ ) { childNode = (*iter).first; if (childNode.IsNotNull()) { mitk::BaseGeometry* childGeometry; mitk::BaseGeometry::Pointer childImageGeometry; // Calculate the World to ITK-Physical transform for the moving mask childGeometry = (*iter).second; iter2 = m_ChildNodes2.find(childNode); childImageGeometry = (*iter2).second; childGeometry->GetIndexToWorldTransform()->SetIdentity(); // the next view lines: Phi(Phys2World)*Phi(Result)*Phi(World2Phy)*Phi(Initial) // set moving mask geometry to registration result childGeometry->SetIndexToWorldTransformByVtkMatrix(vtkmatrix_inv); #if !defined(ITK_IMAGE_BEHAVES_AS_ORIENTED_IMAGE) // the next few lines: Phi(Phys2World)*Phi(Result)*Phi(World2Phy)*Phi(Initial) // go to itk physical space before applying the registration result childGeometry->Compose(m_GeometryWorldToItkPhysicalTransform, 1); // right in the beginning, transform by initial moving image geometry childGeometry->Compose(childImageGeometry->GetIndexToWorldTransform(), 1); // in the end, go back to world space childGeometry->Compose(m_GeometryItkPhysicalToWorldTransform, 0); #else childGeometry->Compose(childImageGeometry->GetIndexToWorldTransform(), 1); #endif } } mitk::RenderingManager::GetInstance()->RequestUpdateAll(); } emit OptimizerChanged(value); } /// this method is called whenever the combobox with the selectable transforms changes /// responsible for showing the selected transform parameters void QmitkRigidRegistrationSelectorView::TransformSelected( int transform ) { if (m_FixedNode.IsNotNull()) { dynamic_cast(m_Controls.m_TransformWidgetStack->widget(transform))->SetFixedImage(dynamic_cast(m_FixedNode->GetData())); } if (m_MovingNode.IsNotNull()) { dynamic_cast(m_Controls.m_TransformWidgetStack->widget(transform))->SetMovingImage(dynamic_cast(m_MovingNode->GetData())); } int numberOfTransformParameters = dynamic_cast(m_Controls.m_TransformWidgetStack->widget(transform))->GetNumberOfTransformParameters(); dynamic_cast(m_Controls.m_OptimizerWidgetStack->currentWidget())->SetNumberOfTransformParameters(numberOfTransformParameters); //set fixed height m_Controls.m_TransformWidgetStack->setFixedHeight( dynamic_cast(m_Controls.m_TransformWidgetStack->widget(transform))->minimumSizeHint().height() ); this->OptimizerSelected(m_Controls.m_OptimizerWidgetStack->currentIndex()); } /// this method is called whenever the combobox with the selectable metrics changes /// responsible for showing the selected metric parameters void QmitkRigidRegistrationSelectorView::MetricSelected( int metric ) { if (m_FixedNode.IsNotNull()) { dynamic_cast(m_Controls.m_MetricWidgetStack->widget(metric))->SetMovingImage(dynamic_cast(m_MovingNode->GetData())); } //set fixed height m_Controls.m_MetricWidgetStack->setFixedHeight( dynamic_cast(m_Controls.m_MetricWidgetStack->widget(metric))->minimumSizeHint().height() ); } /// this method is called whenever the combobox with the selectable optimizers changes /// responsible for showing the selected optimizer parameters void QmitkRigidRegistrationSelectorView::OptimizerSelected( int optimizer ) { int numberOfTransformParameters = dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->GetNumberOfTransformParameters(); dynamic_cast(m_Controls.m_OptimizerWidgetStack->widget(optimizer))->SetNumberOfTransformParameters(numberOfTransformParameters); //set fixed height m_Controls.m_OptimizerWidgetStack->setFixedHeight( dynamic_cast(m_Controls.m_OptimizerWidgetStack->widget(optimizer))->minimumSizeHint().height() ); } void QmitkRigidRegistrationSelectorView::LoadRigidRegistrationParameter() { this->DoLoadRigidRegistrationParameter(); } void QmitkRigidRegistrationSelectorView::DoLoadRigidRegistrationParameter() { std::map > existingPresets; existingPresets = m_Preset->getTransformValuesPresets(); std::map >::iterator iter; std::list presets; for( iter = existingPresets.begin(); iter != existingPresets.end(); iter++ ) { presets.push_back( (*iter).first ); } if (presets.empty()) { QMessageBox::warning( nullptr, "RigidRegistrationParameters.xml", "RigidRegistrationParameters.xml is empty/does not exist. There are no presets to select."); return; } presets.sort(); // ask about the name to load a preset QmitkLoadPresetDialog dialog( this, nullptr, "Load Preset", presets ); // needs a QWidget as parent int dialogReturnValue = dialog.exec(); if ( dialogReturnValue == QDialog::Rejected ) return; // user clicked cancel or pressed Esc or something similar this->DoLoadRigidRegistrationPreset(dialog.GetPresetName()); } void QmitkRigidRegistrationSelectorView::LoadRigidRegistrationPresetParameter(QString preset_name) { this->DoLoadRigidRegistrationPreset(preset_name.toStdString() ); } void QmitkRigidRegistrationSelectorView::DoLoadRigidRegistrationPreset(std::string presetName) { itk::Array transformValues; transformValues = m_Preset->getTransformValues(presetName); + if( transformValues.size() == 0 ) + { + MITK_ERROR("RigidRegistration.Selector.View") << "Failed to load preset : " << presetName; + return; + } + m_Controls.m_TransformGroup->setChecked(true); m_Controls.m_TransformFrame->setVisible(true); m_Controls.m_TransformBox->setCurrentIndex((int)transformValues[0]); m_Controls.m_TransformWidgetStack->setCurrentIndex((int)transformValues[0]); this->TransformSelected((int)transformValues[0]); itk::Array transformValuesForGUI; transformValuesForGUI.SetSize(transformValues.Size()); transformValuesForGUI.fill(0); for (unsigned int i = 1; i < transformValues.Size(); i++) { transformValuesForGUI[i-1] = transformValues[i]; } dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->SetTransformParameters(transformValuesForGUI); itk::Array metricValues; metricValues = m_Preset->getMetricValues(presetName); m_Controls.m_MetricGroup->setChecked(true); m_Controls.m_MetricFrame->setVisible(true); m_Controls.m_MetricBox->setCurrentIndex((int)metricValues[0]); m_Controls.m_MetricWidgetStack->setCurrentIndex((int)metricValues[0]); this->MetricSelected((int)metricValues[0]); itk::Array metricValuesForGUI; metricValuesForGUI.SetSize(metricValues.Size()); metricValuesForGUI.fill(0); for (unsigned int i = 1; i < metricValues.Size(); i++) { metricValuesForGUI[i-1] = metricValues[i]; } dynamic_cast(m_Controls.m_MetricWidgetStack->currentWidget())->SetMetricParameters(metricValuesForGUI); itk::Array optimizerValues; optimizerValues = m_Preset->getOptimizerValues(presetName); m_Controls.m_OptimizerGroup->setChecked(true); m_Controls.m_OptimizerFrame->setVisible(true); m_Controls.m_OptimizerBox->setCurrentIndex((int)optimizerValues[0]); m_Controls.m_OptimizerWidgetStack->setCurrentIndex((int)optimizerValues[0]); this->OptimizerSelected((int)optimizerValues[0]); itk::Array optimizerValuesForGUI; optimizerValuesForGUI.SetSize(optimizerValues.Size()); optimizerValuesForGUI.fill(0); for (unsigned int i = 1; i < optimizerValues.Size(); i++) { optimizerValuesForGUI[i-1] = optimizerValues[i]; } dynamic_cast(m_Controls.m_OptimizerWidgetStack->currentWidget())->SetOptimizerParameters(optimizerValuesForGUI); itk::Array interpolatorValues; interpolatorValues = m_Preset->getInterpolatorValues(presetName); m_Controls.m_InterpolatorGroup->setChecked(true); m_Controls.m_InterpolatorFrame->setVisible(true); m_Controls.m_InterpolatorBox->setCurrentIndex((int)interpolatorValues[0]); } void QmitkRigidRegistrationSelectorView::SaveRigidRegistrationParameter() { this->DoSaveRigidRegistrationParameter(); } void QmitkRigidRegistrationSelectorView::DoSaveRigidRegistrationParameter() { bool ok; QString text = QInputDialog::getText(this, "Save Parameter Preset", "Enter name for preset:", QLineEdit::Normal, QString::null, &ok ); if ( ok ) { std::map > existingPresets; existingPresets = m_Preset->getTransformValuesPresets(); auto iter = existingPresets.find(std::string((const char*)text.toLatin1())); if (iter != existingPresets.end()) { QMessageBox::critical( this, "Preset definition", "Presetname already exists."); return; } if (text.isEmpty()) { QMessageBox::critical( this, "Preset definition", "Presetname has to be set.\n" "You have to enter a Presetname." ); return; } itk::Array transformValues; transformValues.SetSize(25); transformValues.fill(0); transformValues[0] = m_Controls.m_TransformBox->currentIndex(); itk::Array transformValuesFromGUI = dynamic_cast(m_Controls.m_TransformWidgetStack->currentWidget())->GetTransformParameters(); for (unsigned int i = 0; i < transformValuesFromGUI.Size(); i++) { transformValues[i+1] = transformValuesFromGUI[i]; } std::map > transformMap; transformMap = m_Preset->getTransformValuesPresets(); transformMap[std::string((const char*)text.toLatin1())] = transformValues; itk::Array metricValues; metricValues.SetSize(25); metricValues.fill(0); metricValues[0] = m_Controls.m_MetricBox->currentIndex(); itk::Array metricValuesFromGUI = dynamic_cast(m_Controls.m_MetricWidgetStack->currentWidget())->GetMetricParameters(); for (unsigned int i = 0; i < metricValuesFromGUI.Size(); i++) { metricValues[i+1] = metricValuesFromGUI[i]; } std::map > metricMap; metricMap = m_Preset->getMetricValuesPresets(); metricMap[std::string((const char*)text.toLatin1())] = metricValues; itk::Array optimizerValues; optimizerValues.SetSize(25); optimizerValues.fill(0); optimizerValues[0] = m_Controls.m_OptimizerBox->currentIndex(); itk::Array optimizerValuesFromGUI = dynamic_cast(m_Controls.m_OptimizerWidgetStack->currentWidget())->GetOptimizerParameters(); for (unsigned int i = 0; i < optimizerValuesFromGUI.Size(); i++) { optimizerValues[i+1] = optimizerValuesFromGUI[i]; } std::map > optimizerMap; optimizerMap = m_Preset->getOptimizerValuesPresets(); optimizerMap[std::string((const char*)text.toLatin1())] = optimizerValues; itk::Array interpolatorValues; interpolatorValues.SetSize(25); interpolatorValues.fill(0); interpolatorValues[0] = m_Controls.m_InterpolatorBox->currentIndex(); std::map > interpolatorMap; interpolatorMap = m_Preset->getInterpolatorValuesPresets(); interpolatorMap[std::string((const char*)text.toLatin1())] = interpolatorValues; m_Preset->newPresets(transformMap, metricMap, optimizerMap, interpolatorMap); } else { // user pressed Cancel } } void QmitkRigidRegistrationSelectorView::StopOptimization(bool stopOptimization) { m_StopOptimization = stopOptimization; } int QmitkRigidRegistrationSelectorView::GetSelectedTransform() { return m_Controls.m_TransformBox->currentIndex(); } void QmitkRigidRegistrationSelectorView::SetFixedMaskNode( mitk::DataNode * fixedMaskNode ) { m_FixedMaskNode = fixedMaskNode; this->TransformSelected(m_Controls.m_TransformBox->currentIndex()); } void QmitkRigidRegistrationSelectorView::SetMovingMaskNode( mitk::DataNode * movingMaskNode ) { m_MovingMaskNode = movingMaskNode; this->TransformSelected(m_Controls.m_TransformBox->currentIndex()); } void QmitkRigidRegistrationSelectorView::SetMovingNodeChildren(mitk::DataStorage::SetOfObjects::ConstPointer children) { m_MovingNodeChildren = children; } void QmitkRigidRegistrationSelectorView::AddTransform(QmitkRigidRegistrationTransformsGUIBase* transform) { m_Controls.m_TransformBox->addItem(transform->GetName()); int i = 0; if (!dynamic_cast(m_Controls.m_TransformWidgetStack->widget(i))) { m_Controls.m_TransformWidgetStack->addWidget(transform); m_Controls.m_TransformWidgetStack->removeWidget(m_Controls.m_TransformWidgetStack->widget(i)); transform->SetupUI(m_Controls.m_TransformWidgetStack->widget(i)); } else { i = m_Controls.m_TransformWidgetStack->addWidget(transform); transform->SetupUI(m_Controls.m_TransformWidgetStack->widget(i)); } } void QmitkRigidRegistrationSelectorView::AddMetric(QmitkRigidRegistrationMetricsGUIBase* metric) { m_Controls.m_MetricBox->addItem(metric->GetName()); int i = 0; if (!dynamic_cast(m_Controls.m_MetricWidgetStack->widget(i))) { m_Controls.m_MetricWidgetStack->addWidget(metric); m_Controls.m_MetricWidgetStack->removeWidget(m_Controls.m_MetricWidgetStack->widget(i)); metric->SetupUI(m_Controls.m_MetricWidgetStack->widget(i)); } else { i = m_Controls.m_MetricWidgetStack->addWidget(metric); metric->SetupUI(m_Controls.m_MetricWidgetStack->widget(i)); } } void QmitkRigidRegistrationSelectorView::AddOptimizer(QmitkRigidRegistrationOptimizerGUIBase* optimizer) { m_Controls.m_OptimizerBox->addItem(optimizer->GetName()); int i = 0; if (!dynamic_cast(m_Controls.m_OptimizerWidgetStack->widget(i))) { m_Controls.m_OptimizerWidgetStack->addWidget(optimizer); m_Controls.m_OptimizerWidgetStack->removeWidget(m_Controls.m_OptimizerWidgetStack->widget(i)); optimizer->SetupUI(m_Controls.m_OptimizerWidgetStack->widget(i)); } else { i = m_Controls.m_OptimizerWidgetStack->addWidget(optimizer); optimizer->SetupUI(m_Controls.m_OptimizerWidgetStack->widget(i)); } }