Copy a CompositeTransform#

Synopsis#

Copy a CompositeTransform.

Results#

Original transform: CompositeTransform (0x173cdb0)
  RTTI typeinfo:   itk::CompositeTransform<float, 3u>
  Reference Count: 2
  Modified Time: 12
  Debug: Off
  Object Name:
  Observers:
    none
  Transforms in queue, from begin to end:
  >>>>>>>>>
  Euler3DTransform (0x173c880)
    RTTI typeinfo:   itk::Euler3DTransform<float>
    Reference Count: 2
    Modified Time: 5
    Debug: Off
    Object Name:
    Observers:
      none
    Matrix:
      0.930432 -0.294044 0.218711
      0.308577 0.950564 -0.0347626
      -0.197677 0.0998334 0.97517
    Offset: [3.63622, 5.66636, 5.62082]
    Center: [-3.5, -4.5, -5.5]
    Translation: [4, 5, 6]
    Inverse:
      0.930432 0.308577 -0.197677
      -0.294044 0.950564 0.0998333
      0.218711 -0.0347626 0.97517
    Singular: 0
    Euler's angles: AngleX=0.1 AngleY=0.2 AngleZ=0.3
    m_ComputeZYX = 0
  >>>>>>>>>
  ScaleTransform (0x173cb10)
    RTTI typeinfo:   itk::ScaleTransform<float, 3u>
    Reference Count: 2
    Modified Time: 9
    Debug: Off
    Object Name:
    Observers:
      none
    Matrix:
      0.6 0 0
      0 0.7 0
      0 0 0.8
    Offset: [0, 0, 0]
    Center: [0, 0, 0]
    Translation: [0, 0, 0]
    Inverse:
      1.66667 0 0
      0 1.42857 0
      0 0 1.25
    Singular: 0
    Scale: [0.6, 0.7, 0.8]
    Center: [0, 0, 0]
  End of MultiTransform.
<<<<<<<<<<
  TransformsToOptimizeFlags, begin() to end():
    1 1
  TransformsToOptimize in queue, from begin to end:
  End of TransformsToOptimizeQueue.
<<<<<<<<<<
  End of CompositeTransform.
<<<<<<<<<<

Transform copy: CompositeTransform (0x173da00)
  RTTI typeinfo:   itk::CompositeTransform<float, 3u>
  Reference Count: 3
  Modified Time: 26
  Debug: Off
  Object Name:
  Observers:
    none
  Transforms in queue, from begin to end:
  >>>>>>>>>
  Euler3DTransform (0x173e2e0)
    RTTI typeinfo:   itk::Euler3DTransform<float>
    Reference Count: 1
    Modified Time: 18
    Debug: Off
    Object Name:
    Observers:
      none
    Matrix:
      0.930432 -0.294044 0.218711
      0.308577 0.950564 -0.0347626
      -0.197677 0.0998334 0.97517
    Offset: [3.63622, 5.66636, 5.62082]
    Center: [-3.5, -4.5, -5.5]
    Translation: [4, 5, 6]
    Inverse:
      0.930432 0.308577 -0.197677
      -0.294044 0.950564 0.0998333
      0.218711 -0.0347626 0.97517
    Singular: 0
    Euler's angles: AngleX=0.1 AngleY=0.2 AngleZ=0.3
    m_ComputeZYX = 0
  >>>>>>>>>
  ScaleTransform (0x173e470)
    RTTI typeinfo:   itk::ScaleTransform<float, 3u>
    Reference Count: 1
    Modified Time: 24
    Debug: Off
    Object Name:
    Observers:
      none
    Matrix:
      0.6 0 0
      0 0.7 0
      0 0 0.8
    Offset: [0, 0, 0]
    Center: [0, 0, 0]
    Translation: [0, 0, 0]
    Inverse:
      1.66667 0 0
      0 1.42857 0
      0 0 1.25
    Singular: 0
    Scale: [0.6, 0.7, 0.8]
    Center: [0, 0, 0]
  End of MultiTransform.
<<<<<<<<<<
  TransformsToOptimizeFlags, begin() to end():
    1 1
  TransformsToOptimize in queue, from begin to end:
  End of TransformsToOptimizeQueue.
<<<<<<<<<<
  End of CompositeTransform.
<<<<<<<<<<

Code#

C++#

#include "itkEuler3DTransform.h"
#include "itkScaleTransform.h"
#include "itkCompositeTransform.h"
#include "itkCompositeTransformIOHelper.h"

int
main()
{
  using ScalarType = float;
  constexpr unsigned int Dimension = 3;

  using EulerTransformType = itk::Euler3DTransform<ScalarType>;
  auto                               eulerTransform = EulerTransformType::New();
  EulerTransformType::ParametersType eulerParameters(6);
  eulerParameters[0] = 0.1;
  eulerParameters[1] = 0.2;
  eulerParameters[2] = 0.3;
  eulerParameters[3] = 4.0;
  eulerParameters[4] = 5.0;
  eulerParameters[5] = 6.0;
  eulerTransform->SetParameters(eulerParameters);

  EulerTransformType::FixedParametersType eulerFixedParameters(Dimension);
  eulerFixedParameters[0] = -3.5;
  eulerFixedParameters[1] = -4.5;
  eulerFixedParameters[2] = -5.5;
  eulerTransform->SetFixedParameters(eulerFixedParameters);

  using ScaleTransformType = itk::ScaleTransform<ScalarType, Dimension>;
  auto                               scaleTransform = ScaleTransformType::New();
  ScaleTransformType::ParametersType scaleParameters(Dimension);
  scaleParameters[0] = 0.6;
  scaleParameters[1] = 0.7;
  scaleParameters[2] = 0.8;
  scaleTransform->SetParameters(scaleParameters);

  using CompositeTransformType = itk::CompositeTransform<ScalarType, Dimension>;
  auto compositeTransform = CompositeTransformType::New();
  compositeTransform->AddTransform(eulerTransform);
  compositeTransform->AddTransform(scaleTransform);
  std::cout << "Original transform: " << compositeTransform << std::endl;


  CompositeTransformType::Pointer transformCopy = compositeTransform->Clone();
  std::cout << "Transform copy: " << transformCopy << std::endl;

  return EXIT_SUCCESS;
}

Classes demonstrated#

template<typename TParametersValueType, unsigned int NInputDimensions = 3, unsigned int NOutputDimensions = 3>
class Transform : public itk::TransformBaseTemplate<TParametersValueType>

Transform points and vectors from an input space to an output space.

This abstract class defines the generic interface for a geometric transformation from one space to another. The class provides methods for mapping points, vectors and covariant vectors from the input space to the output space.

Given that transformations are not necessarily invertible, this basic class does not provide the methods for back transformation. Back transform methods are implemented in derived classes where appropriate.

Another requirement of the registration framework is the computation of the transform Jacobian. In general, an

ImageToImageMetric requires the knowledge of the Jacobian in order to compute the metric derivatives. The Jacobian is a matrix whose element are the partial derivatives of the output point with respect to the array of parameters that defines the transform.
Registration Framework Support

Typically a Transform class has several methods for setting its parameters. For use in the registration framework, the parameters must also be represented by an array of doubles to allow communication with generic optimizers. The Array of transformation parameters is set using the SetParameters() method.

Subclasses must provide implementations for:

virtual OutputPointType

TransformPoint(const InputPointType &) const

virtual OutputVectorType

TransformVector(const InputVectorType &) const

virtual OutputVnlVectorType

TransformVector(const InputVnlVectorType &) const

virtual OutputCovariantVectorType

TransformCovariantVector(const InputCovariantVectorType &) const

virtual void

SetParameters(const ParametersType &)

virtual void

SetFixedParameters(const FixedParametersType &)

virtual void ComputeJacobianWithRespectToParameters( const InputPointType &, JacobianType &) const

virtual void ComputeJacobianWithRespectToPosition( const InputPointType & x, JacobianPositionType &jacobian ) const;

Since TranformVector and TransformCovariantVector have multiple overloaded methods from the base class, subclasses must specify:

using Superclass::TransformVector;

using Superclass::TransformCovariantVector;

Subclassed by itk::MatrixOffsetTransformBase< TParametersValueType, NInputDimensions, NOutputDimensions >, itk::MatrixOffsetTransformBase< TParametersValueType, 2, 2 >, itk::MatrixOffsetTransformBase< TParametersValueType, 3, 3 >, itk::MatrixOffsetTransformBase< TParametersValueType, NDimensions, NDimensions >

See itk::Transform for additional documentation.