/*========================================================================= Program: vtkINRIA3D Module: $Id: itkDisplacementFieldTransform.h 1 2008-01-22 19:01:33Z ntoussaint $ Language: C++ Author: $Author: ntoussaint vgarcia $ Date: $Date: 2008-01-22 20:01:33 +0100 (Tue, 22 Jan 2008) $ Version: $Revision: 1 $ Copyright (c) 2007 INRIA - Asclepios Project. All rights reserved. See Copyright.txt for details. This software is distributed WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the above copyright notices for more information. =========================================================================*/ #ifndef _rpiDisplacementFieldTransform_h_ #define _rpiDisplacementFieldTransform_h_ #include #include #include #include #include "itkVectorLinearInterpolateNearestNeighborExtrapolateImageFunction.h" namespace rpi { /** * * This class defines the non-linear displacement field transformation. * * There are two templates for this class: * * TScalarType Type of the transformation parameters. Can be "float" or "double". * * NDimensions Dimension of the transformation space. * * The parameters of a displacement field is a vector field. Since a vector field cannot be simply * represented by an simple linear array, we store this vector field into a VectorFieldType which is * simply an itk::Image where the type of voxels is itk::Vector. The methods * SetParametersAsVectorField and GetParametersAsVectorField respectively allow to set and get the * vector field. * * This transform is only able to transform points and vectors. Transforming a covariant vector has * no meaning in the sense that we need to transform the vector with the jacobian of the * transformation with respect to the parameters, which cannot be computed. * * The user can compute the Jacobian of the transformation with respect to the coordinates * at a specific location with the method GetJacobianWithRespectToCoordinates(), and its determinant * (scalar) with the method GetJacobianDeterminantWithRespectToCoordinates(). However, the * determinant of the transformation with respect its parameters can not be computed as there is no * parametric handling. * * There is no I/O support as there is no parameters, the user might save the * vector field instead. * * @brief Displacement field transformation * * @class DisplacementFieldTransform (itk) * * @author Nicolas Toussaint, Vincent Garcia INRIA */ template class ITK_EXPORT DisplacementFieldTransform : public itk::Transform { public: typedef DisplacementFieldTransform Self; typedef itk::Transform Superclass; typedef itk::SmartPointer Pointer; typedef itk::SmartPointer ConstPointer; typedef Superclass TransformType; typedef typename TransformType::ConstPointer TransformPointerType; /** * Base inverse transform type. This type should not be changed to the concrete inverse * transform type or inheritance would be lost. */ typedef typename Superclass::InverseTransformBaseType InverseTransformBaseType; typedef typename InverseTransformBaseType::Pointer InverseTransformBasePointer; /** * Type of the scalar representing coordinate and vector elements */ typedef TScalarType ScalarType; /** * Type of the input parameters */ typedef typename Superclass::ParametersType ParametersType; typedef typename Superclass::FixedParametersType FixedParametersType; /** * Type of the Jacobian matrix */ typedef typename Superclass::JacobianType JacobianType; /** * Standard vector type for this class */ typedef typename Superclass::InputVectorType InputVectorType; typedef typename Superclass::OutputVectorType OutputVectorType; /** * Standard covariant vector type for this class */ typedef typename Superclass::InputCovariantVectorType InputCovariantVectorType; typedef typename Superclass::OutputCovariantVectorType OutputCovariantVectorType; /** * Standard vnl_vector type for this class */ typedef typename Superclass::InputVnlVectorType InputVnlVectorType; typedef typename Superclass::OutputVnlVectorType OutputVnlVectorType; /** * Standard coordinate point type for this class */ typedef typename Superclass::InputPointType InputPointType; typedef typename Superclass::OutputPointType OutputPointType; /** * Type related to the container of field */ typedef itk::Vector VectorType; typedef itk::Image VectorFieldType; typedef typename VectorFieldType::Pointer VectorFieldPointerType; typedef typename VectorFieldType::ConstPointer VectorFieldConstPointerType; typedef typename VectorFieldType::IndexType VectortFieldIndexType; /** * Type relative to the field geometry */ typedef typename VectorFieldType::PointType OriginType; typedef typename VectorFieldType::SpacingType SpacingType; typedef typename VectorFieldType::DirectionType DirectionType; typedef typename VectorFieldType::RegionType RegionType; /** * Interpolation type */ typedef itk::VectorLinearInterpolateNearestNeighborExtrapolateImageFunction InterpolateFunctionType; typedef typename InterpolateFunctionType::Pointer InterpolateFunctionPointerType; /** * Dimension of the domain space */ itkStaticConstMacro(SpaceDimension, unsigned int, NDimensions); itkStaticConstMacro(ParametersDimension, unsigned int, NDimensions); /** * Generic constructors. */ itkNewMacro( Self ); itkTypeMacro( DisplacementFieldTransform, Transform ); /** * Gets the transformation parameters. */ virtual const ParametersType& GetParameters(void) const ITK_OVERRIDE { itkExceptionMacro("This type of transform does not handle any parameters."); } /** * Sets the transformation parameters. */ virtual void SetParameters( const ParametersType & ) ITK_OVERRIDE { itkExceptionMacro("This type of transform does not handle any parameters."); } /** * Sets the fixed transformation parameters. */ virtual void SetFixedParameters( const FixedParametersType & ) ITK_OVERRIDE { itkExceptionMacro("This type of transform does not handle any parameters."); } /** * Sets the transformation parameters. */ virtual void SetParametersByValue( const ParametersType & p ) ITK_OVERRIDE { itkExceptionMacro("This type of transform does not handle any parameters."); } /** * Sets the transform to identity. */ virtual void SetIdentity(void); /** * Gets the parameters as vector field. */ virtual const VectorFieldType * GetParametersAsVectorField(void) const; /** * Sets the parameters as vector field. */ virtual void SetParametersAsVectorField(const VectorFieldType * field); /** * Gets an inverse of this transformation. */ virtual bool GetInverse(Self* inverse) const; /** * Gets an inverse of this transformation. */ virtual InverseTransformBasePointer GetInverseTransform(void) const ITK_OVERRIDE; /** * Transforms a point. */ virtual OutputPointType TransformPoint(const InputPointType & point) const ITK_OVERRIDE; /** * Transforms a vector. */ virtual OutputVectorType TransformVector(const InputVectorType & vector) const ITK_OVERRIDE; /** * Transforms a vnl_vector. */ virtual OutputVnlVectorType TransformVector(const InputVnlVectorType & vector) const ITK_OVERRIDE; /** * Transform a CovariantVector. */ virtual OutputCovariantVectorType TransformCovariantVector(const InputCovariantVectorType &) const ITK_OVERRIDE { itkExceptionMacro("Cannot transform covariant vector!"); } /** * Gets the origin of the field. */ OriginType GetOrigin(void); /** * Gets the spacing of the field. */ SpacingType GetSpacing(void); /** * Gets the direction of the field. */ DirectionType GetDirection(void); /** * Gets the region object that defines the size and starting index for the largest possible * region this image could represent. */ RegionType GetLargestPossibleRegion(void); /** * This method computes the Jacobian matrix of the transformation * at a given input point. The rank of the Jacobian will also indicate * if the transform is invertible at this point. */ virtual const JacobianType & GetJacobian(const InputPointType & point) const { itkExceptionMacro("This type of transform does not handle Jacobian!"); } /** * Gets the jacobian of the transformation with respect to the coordinates at a specific point. */ virtual vnl_matrix_fixed GetSpatialJacobian(const InputPointType & point) const; /** * Gets the jacobian determinant of transformation with respect to the coordinates at a specific point. */ virtual ScalarType GetSpatialJacobianDeterminant(const InputPointType & point) const; // Purposedly not implemented void ComputeJacobianWithRespectToParameters(const InputPointType & itkNotUsed(p), JacobianType & itkNotUsed(jacobian) ) const ITK_OVERRIDE {} protected: /** * Prints contents. */ void PrintSelf(std::ostream &os, itk::Indent indent) const ITK_OVERRIDE; /** * Default constructor. */ DisplacementFieldTransform(void); /** * Destructor. */ virtual ~DisplacementFieldTransform(){}; private: /** * Parameters = vector field */ VectorFieldConstPointerType m_VectorField; /** * Interpolation function */ InterpolateFunctionPointerType m_InterpolateFunction; /** * Weights used to scale partial derivatives during Jacobian computation */ double m_DerivativeWeights[NDimensions]; }; } // end of namespace itk #ifndef ITK_MANUAL_INSTANTIATION #include "rpiDisplacementFieldTransform.txx" #endif #endif