Skip to content

Commit

Permalink
BUG: Fix ElastixRegistrationMethod GetNumberOfTransforms GetNthTransform
Browse files Browse the repository at this point in the history
ElastixRegistrationMethod member functions `GetNumberOfTransforms`, `GetNthTransform`, and `GetCombinationTransform` did always just return zero or null, erroneously, when the pixel type of the input images (specified by `TFixedImage` and `TMovingImage`) would be different from the internal pixel type (specified by "FixedInternalImagePixelType" and "MovingInternalImagePixelType", `float` by default). The code incorrectly assumed that the objects stored in the ElastixBase `TransformContainer` are always of type `elx::TransformBase<ElastixTemplate<TFixedImage, TMovingImage>>`.

This commit just assumes that the objects stored in `TransformContainer` are of type `AdvancedCombinationTransform<double, FixedImageDimension>`.

The commit aims to fix issue #965 "ElastixRegistrationMethod GetNumberOfTransforms, GetCombinationTransform, etc. does not work with non-float ImageType", reported by Matt McCormick.

Extended the GoogleTest `itkElastixRegistrationMethod.CheckMinimumMovingImageUsingAnyInternalPixelType` unit test to check this issue.
  • Loading branch information
N-Dekker committed Sep 27, 2023
1 parent 03bf078 commit c96f026
Show file tree
Hide file tree
Showing 3 changed files with 32 additions and 36 deletions.
3 changes: 3 additions & 0 deletions Core/Main/GTesting/itkElastixRegistrationMethodGTest.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -2306,6 +2306,9 @@ GTEST_TEST(itkElastixRegistrationMethod, CheckMinimumMovingImageUsingAnyInternal
registration.Update();

EXPECT_EQ(DerefRawPointer(registration.GetOutput()), DerefSmartPointer(movingImage));
EXPECT_EQ(registration.GetNumberOfTransforms(), 1);
EXPECT_NE(registration.GetNthTransform(0), nullptr);
EXPECT_NE(registration.GetCombinationTransform(), nullptr);
});
};

Expand Down
8 changes: 7 additions & 1 deletion Core/Main/itkElastixRegistrationMethod.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,10 +36,12 @@
#define itkElastixRegistrationMethod_h

#include "itkImageSource.h"
#include "itkAdvancedCombinationTransform.h"
#include "itkElastixLogLevel.h"

#include "elxElastixMain.h"
#include "elxElastixTemplate.h"
#include "elxElastixBase.h"
#include "elxTransformBase.h"
#include "elxParameterObject.h"

Expand Down Expand Up @@ -373,7 +375,11 @@ class ITK_TEMPLATE_EXPORT ElastixRegistrationMethod : public itk::ImageSource<TF
/** Private using-declaration, just to avoid GCC compilation warnings: '...' was hidden [-Woverloaded-virtual] */
using Superclass::SetInput;

using ElastixTransformBaseType = elx::TransformBase<elx::ElastixTemplate<TFixedImage, TMovingImage>>;
using AdvancedCombinationTransformType =
AdvancedCombinationTransform<elx::ElastixBase::CoordRepType, FixedImageDimension>;

AdvancedCombinationTransformType *
GetAdvancedCombinationTransform() const;

SmartPointer<const elx::ElastixMain> m_ElastixMain{};

Expand Down
57 changes: 22 additions & 35 deletions Core/Main/itkElastixRegistrationMethod.hxx
Original file line number Diff line number Diff line change
Expand Up @@ -979,60 +979,47 @@ template <typename TFixedImage, typename TMovingImage>
unsigned int
ElastixRegistrationMethod<TFixedImage, TMovingImage>::GetNumberOfTransforms() const
{
const auto * const transformContainer = m_ElastixMain->GetElastixBase().GetTransformContainer();

if ((transformContainer == nullptr) || transformContainer->empty())
{
return 0;
}

const auto * const elxTransformBase =
dynamic_cast<ElastixTransformBaseType *>(transformContainer->front().GetPointer());

return (elxTransformBase == nullptr) ? 0 : elxTransformBase->GetAsITKBaseType()->GetNumberOfTransforms();
const auto advancedCombinationTransform = GetAdvancedCombinationTransform();
return advancedCombinationTransform ? advancedCombinationTransform->GetNumberOfTransforms() : 0;
}


template <typename TFixedImage, typename TMovingImage>
auto
ElastixRegistrationMethod<TFixedImage, TMovingImage>::GetNthTransform(const unsigned int n) const -> TransformType *
{
const auto * const transformContainer = m_ElastixMain->GetElastixBase().GetTransformContainer();

if ((transformContainer == nullptr) || transformContainer->empty())
{
return nullptr;
}
const auto advancedCombinationTransform = GetAdvancedCombinationTransform();
return advancedCombinationTransform ? advancedCombinationTransform->GetNthTransform(n) : nullptr;
}

const auto * const elxTransformBase =
dynamic_cast<ElastixTransformBaseType *>(transformContainer->front().GetPointer());

if (elxTransformBase == nullptr)
template <typename TFixedImage, typename TMovingImage>
auto
ElastixRegistrationMethod<TFixedImage, TMovingImage>::GetAdvancedCombinationTransform() const
-> AdvancedCombinationTransformType *
{
{
if (m_ElastixMain)
{
if (const auto transformContainer = m_ElastixMain->GetElastixBase().GetTransformContainer();
(transformContainer != nullptr) && !transformContainer->empty())
{
if (const auto firstTransform = transformContainer->front().GetPointer())
{
return static_cast<AdvancedCombinationTransformType *>(firstTransform);
}
}
}
return nullptr;
}
return elxTransformBase->GetAsITKBaseType()->GetNthTransform(n);
}


template <typename TFixedImage, typename TMovingImage>
auto
ElastixRegistrationMethod<TFixedImage, TMovingImage>::GetCombinationTransform() const -> TransformType *
{
const auto * const transformContainer = m_ElastixMain->GetElastixBase().GetTransformContainer();

if ((transformContainer == nullptr) || transformContainer->empty())
{
return nullptr;
}

auto * const elxTransformBase = dynamic_cast<ElastixTransformBaseType *>(transformContainer->front().GetPointer());

if (elxTransformBase == nullptr)
{
return nullptr;
}
return elxTransformBase->GetAsITKBaseType();
return GetAdvancedCombinationTransform();
}


Expand Down

0 comments on commit c96f026

Please sign in to comment.