|
| 1 | +/*========================================================================= |
| 2 | + * |
| 3 | + * Copyright UMC Utrecht and contributors |
| 4 | + * |
| 5 | + * Licensed under the Apache License, Version 2.0 (the "License"); |
| 6 | + * you may not use this file except in compliance with the License. |
| 7 | + * You may obtain a copy of the License at |
| 8 | + * |
| 9 | + * http://www.apache.org/licenses/LICENSE-2.0.txt |
| 10 | + * |
| 11 | + * Unless required by applicable law or agreed to in writing, software |
| 12 | + * distributed under the License is distributed on an "AS IS" BASIS, |
| 13 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 14 | + * See the License for the specific language governing permissions and |
| 15 | + * limitations under the License. |
| 16 | + * |
| 17 | + *=========================================================================*/ |
| 18 | +#ifndef __elxEulerStackTransform_h |
| 19 | +#define __elxEulerStackTransform_h |
| 20 | + |
| 21 | +#include "elxIncludes.h" |
| 22 | +/** Include itk transforms needed. */ |
| 23 | +#include "itkAdvancedCombinationTransform.h" |
| 24 | +#include "itkStackTransform.h" |
| 25 | +#include "itkEulerTransform.h" |
| 26 | + |
| 27 | +namespace elastix |
| 28 | +{ |
| 29 | + |
| 30 | +/** |
| 31 | + * \class EulerStackTransform |
| 32 | + * \brief A stack transform based on the itk EulerTransforms. |
| 33 | + * |
| 34 | + * This transform is a rigid body transformation. Calls to TransformPoint and GetJacobian are |
| 35 | + * redirected to the appropriate sub transform based on the last dimension (time) index. |
| 36 | + * |
| 37 | + * This transform uses the size, spacing and origin of the last dimension of the fixed |
| 38 | + * image to set the number of sub transforms, the origin of the first transform and the |
| 39 | + * spacing between the transforms. |
| 40 | + * |
| 41 | + * |
| 42 | + * The parameters used in this class are: |
| 43 | + * \parameter Transform: Select this transform as follows:\n |
| 44 | + * <tt>(%Transform "EulerStackTransform")</tt> |
| 45 | + * \parameter Scales: the scale factor between the rotations and translations, |
| 46 | + * used in the optimizer. \n |
| 47 | + * example: <tt>(Scales 200000.0)</tt> \n |
| 48 | + * example: <tt>(Scales 100000.0 60000.0 ... 80000.0)</tt> \n |
| 49 | + * If only one argument is given, that factor is used for the rotations. |
| 50 | + * If more than one argument is given, then the number of arguments should be |
| 51 | + * equal to the number of parameters: for each parameter its scale factor. |
| 52 | + * If this parameter option is not used, by default the rotations are scaled |
| 53 | + * by a factor of 100000.0. See also the AutomaticScalesEstimation parameter. |
| 54 | + * \parameter AutomaticScalesEstimation: if this parameter is set to "true" the Scales |
| 55 | + * parameter is ignored and the scales are determined automatically. \n |
| 56 | + * example: <tt>( AutomaticScalesEstimation "true" ) </tt> \n |
| 57 | + * Default: "false" (for backwards compatibility). Recommended: "true". |
| 58 | + * \parameter CenterOfRotation: an index around which the image is rotated. \n |
| 59 | + * example: <tt>(CenterOfRotation 128 128)</tt> \n |
| 60 | + * |
| 61 | + * The transform parameters necessary for transformix, additionally defined by this class, are: |
| 62 | + * \transformparameter CenterOfRotation: stores the center of rotation as an index. \n |
| 63 | + * example: <tt>(CenterOfRotation 128 128)</tt> |
| 64 | + * deprecated! From elastix version 3.402 this is changed to CenterOfRotationPoint! |
| 65 | + * \transformparameter CenterOfRotationPoint: stores the center of rotation, expressed in world coordinates. \n |
| 66 | + * example: <tt>(CenterOfRotationPoint 10.555 6.666)</tt> |
| 67 | + * \transformparameter StackSpacing: stores the spacing between the sub transforms. \n |
| 68 | + * exanoke: <tt>(StackSpacing 1.0)</tt> |
| 69 | + * \transformparameter StackOrigin: stores the origin of the first sub transform. \n |
| 70 | + * exanoke: <tt>(StackOrigin 0.0)</tt> |
| 71 | + * \transformparameter NumberOfSubTransforms: stores the number of sub transforms. \n |
| 72 | + * exanoke: <tt>(NumberOfSubTransforms 10)</tt> |
| 73 | + * |
| 74 | + * \todo It is unsure what happens when one of the image dimensions has length 1. |
| 75 | + * \todo The center of rotation point is not transformed with the initial transform yet. |
| 76 | + * |
| 77 | + * \ingroup Transforms |
| 78 | + */ |
| 79 | + |
| 80 | +template< class TElastix > |
| 81 | +class EulerStackTransform : |
| 82 | + public itk::AdvancedCombinationTransform< |
| 83 | + typename elx::TransformBase< TElastix >::CoordRepType, |
| 84 | + elx::TransformBase< TElastix >::FixedImageDimension >, |
| 85 | + public elx::TransformBase< TElastix > |
| 86 | +{ |
| 87 | +public: |
| 88 | + |
| 89 | + /** Standard ITK-stuff. */ |
| 90 | + typedef EulerStackTransform Self; |
| 91 | + typedef itk::AdvancedCombinationTransform< |
| 92 | + typename elx::TransformBase< TElastix >::CoordRepType, |
| 93 | + elx::TransformBase< TElastix >::FixedImageDimension > Superclass1; |
| 94 | + typedef elx::TransformBase< TElastix > Superclass2; |
| 95 | + typedef itk::SmartPointer< Self > Pointer; |
| 96 | + typedef itk::SmartPointer< const Self > ConstPointer; |
| 97 | + |
| 98 | + /** Method for creation through the object factory. */ |
| 99 | + itkNewMacro( Self ); |
| 100 | + |
| 101 | + /** Run-time type information (and related methods). */ |
| 102 | + itkTypeMacro( EulerStackTransform, itk::AdvancedCombinationTransform ); |
| 103 | + |
| 104 | + /** Name of this class. |
| 105 | + * Use this name in the parameter file to select this specific transform. \n |
| 106 | + * example: <tt>(Transform "EulerStackTransform")</tt>\n |
| 107 | + */ |
| 108 | + elxClassNameMacro( "EulerStackTransform" ); |
| 109 | + |
| 110 | + /** (Reduced) dimension of the fixed image. */ |
| 111 | + itkStaticConstMacro( SpaceDimension, unsigned int, Superclass2::FixedImageDimension ); |
| 112 | + itkStaticConstMacro( ReducedSpaceDimension, unsigned int, Superclass2::FixedImageDimension - 1 ); |
| 113 | + |
| 114 | + /** The ITK-class that provides most of the functionality, and |
| 115 | + * that is set as the "CurrentTransform" in the CombinationTransform. |
| 116 | + */ |
| 117 | + typedef itk::EulerTransform< |
| 118 | + typename elx::TransformBase< TElastix >::CoordRepType, |
| 119 | + itkGetStaticConstMacro( SpaceDimension ) > EulerTransformType; |
| 120 | + typedef typename EulerTransformType::Pointer EulerTransformPointer; |
| 121 | + typedef typename EulerTransformType::InputPointType InputPointType; |
| 122 | + |
| 123 | + /** The ITK-class for the sub transforms, which have a reduced dimension. */ |
| 124 | + typedef itk::EulerTransform< |
| 125 | + typename elx::TransformBase< TElastix >::CoordRepType, |
| 126 | + itkGetStaticConstMacro( ReducedSpaceDimension ) > ReducedDimensionEulerTransformType; |
| 127 | + typedef typename ReducedDimensionEulerTransformType::Pointer ReducedDimensionEulerTransformPointer; |
| 128 | + |
| 129 | + typedef typename ReducedDimensionEulerTransformType::OutputVectorType ReducedDimensionOutputVectorType; |
| 130 | + typedef typename ReducedDimensionEulerTransformType::InputPointType ReducedDimensionInputPointType; |
| 131 | + |
| 132 | + /** Typedef for stack transform. */ |
| 133 | + typedef itk::StackTransform< |
| 134 | + typename elx::TransformBase< TElastix >::CoordRepType, |
| 135 | + itkGetStaticConstMacro( SpaceDimension ), |
| 136 | + itkGetStaticConstMacro( SpaceDimension ) > EulerStackTransformType; |
| 137 | + typedef typename EulerStackTransformType::Pointer EulerStackTransformPointer; |
| 138 | + |
| 139 | + /** Typedefs inherited from the superclass. */ |
| 140 | + typedef typename Superclass1::ParametersType ParametersType; |
| 141 | + typedef typename Superclass1::NumberOfParametersType NumberOfParametersType; |
| 142 | + |
| 143 | + /** Typedef's from TransformBase. */ |
| 144 | + typedef typename Superclass2::ElastixType ElastixType; |
| 145 | + typedef typename Superclass2::ElastixPointer ElastixPointer; |
| 146 | + typedef typename Superclass2::ConfigurationType ConfigurationType; |
| 147 | + typedef typename Superclass2::ConfigurationPointer ConfigurationPointer; |
| 148 | + typedef typename Superclass2::RegistrationType RegistrationType; |
| 149 | + typedef typename Superclass2::RegistrationPointer RegistrationPointer; |
| 150 | + typedef typename Superclass2::CoordRepType CoordRepType; |
| 151 | + typedef typename Superclass2::FixedImageType FixedImageType; |
| 152 | + typedef typename Superclass2::MovingImageType MovingImageType; |
| 153 | + typedef typename Superclass2::ITKBaseType ITKBaseType; |
| 154 | + typedef typename Superclass2::CombinationTransformType CombinationTransformType; |
| 155 | + |
| 156 | + /** Reduced Dimension typedef's. */ |
| 157 | + typedef float PixelType; |
| 158 | + typedef itk::Image< PixelType, |
| 159 | + itkGetStaticConstMacro( ReducedSpaceDimension ) > ReducedDimensionImageType; |
| 160 | + typedef itk::ImageRegion< |
| 161 | + itkGetStaticConstMacro( ReducedSpaceDimension ) > ReducedDimensionRegionType; |
| 162 | + typedef typename ReducedDimensionImageType::PointType ReducedDimensionPointType; |
| 163 | + typedef typename ReducedDimensionImageType::SizeType ReducedDimensionSizeType; |
| 164 | + typedef typename ReducedDimensionRegionType::IndexType ReducedDimensionIndexType; |
| 165 | + typedef typename ReducedDimensionImageType::SpacingType ReducedDimensionSpacingType; |
| 166 | + typedef typename ReducedDimensionImageType::DirectionType ReducedDimensionDirectionType; |
| 167 | + typedef typename ReducedDimensionImageType::PointType ReducedDimensionOriginType; |
| 168 | + |
| 169 | + /** For scales setting in the optimizer */ |
| 170 | + typedef typename Superclass2::ScalesType ScalesType; |
| 171 | + |
| 172 | + /** Other typedef's. */ |
| 173 | + typedef typename FixedImageType::IndexType IndexType; |
| 174 | + typedef typename FixedImageType::SizeType SizeType; |
| 175 | + typedef typename FixedImageType::PointType PointType; |
| 176 | + typedef typename FixedImageType::SpacingType SpacingType; |
| 177 | + typedef typename FixedImageType::RegionType RegionType; |
| 178 | + typedef typename FixedImageType::DirectionType DirectionType; |
| 179 | + typedef typename itk::ContinuousIndex< CoordRepType, ReducedSpaceDimension > ReducedDimensionContinuousIndexType; |
| 180 | + typedef typename itk::ContinuousIndex< CoordRepType, SpaceDimension > ContinuousIndexType; |
| 181 | + |
| 182 | + /** Execute stuff before anything else is done:*/ |
| 183 | + |
| 184 | + virtual int BeforeAll( void ); |
| 185 | + |
| 186 | + /** Execute stuff before the actual registration: |
| 187 | + * \li Set the stack transform parameters. |
| 188 | + * \li Set initial sub transforms. |
| 189 | + * \li Create initial registration parameters. |
| 190 | + */ |
| 191 | + virtual void BeforeRegistration( void ); |
| 192 | + |
| 193 | + /** Method initialize the parameters (to 0). */ |
| 194 | + virtual void InitializeTransform( void ); |
| 195 | + |
| 196 | + /** Set the scales |
| 197 | + * \li If AutomaticScalesEstimation is "true" estimate scales |
| 198 | + * \li If scales are provided by the user use those, |
| 199 | + * \li Otherwise use some default value |
| 200 | + * This function is called by BeforeRegistration, after |
| 201 | + * the InitializeTransform function is called |
| 202 | + */ |
| 203 | + virtual void SetScales( void ); |
| 204 | + |
| 205 | + /** Function to read transform-parameters from a file. */ |
| 206 | + virtual void ReadFromFile( void ); |
| 207 | + |
| 208 | + /** Function to write transform-parameters to a file. */ |
| 209 | + virtual void WriteToFile( const ParametersType & param ) const; |
| 210 | + |
| 211 | + /** Function to rotate center of rotation point using initial transformation. */ |
| 212 | + virtual void InitialTransformCenter( ReducedDimensionInputPointType & point ); |
| 213 | + |
| 214 | +protected: |
| 215 | + |
| 216 | + /** The constructor. */ |
| 217 | + EulerStackTransform(); |
| 218 | + |
| 219 | + /** The destructor. */ |
| 220 | + virtual ~EulerStackTransform() {} |
| 221 | + |
| 222 | + /** Try to read the CenterOfRotation from the transform parameter file |
| 223 | + * This is an index value, and, thus, converted to world coordinates. |
| 224 | + * Transform parameter files generated by elastix version < 3.402 |
| 225 | + * saved the center of rotation in this way. |
| 226 | + */ |
| 227 | + virtual bool ReadCenterOfRotationIndex( ReducedDimensionInputPointType & rotationPoint ) const; |
| 228 | + |
| 229 | + /** Try to read the CenterOfRotationPoint from the transform parameter file |
| 230 | + * The CenterOfRotationPoint is already in world coordinates. |
| 231 | + * Transform parameter files generated by elastix version > 3.402 |
| 232 | + * save the center of rotation in this way. |
| 233 | + */ |
| 234 | + virtual bool ReadCenterOfRotationPoint( ReducedDimensionInputPointType & rotationPoint ) const; |
| 235 | + |
| 236 | +private: |
| 237 | + |
| 238 | + /** The private constructor and copy constructor. */ |
| 239 | + EulerStackTransform( const Self & ); // purposely not implemented |
| 240 | + void operator=( const Self & ); // purposely not implemented |
| 241 | + |
| 242 | + /** The Affine stack transform. */ |
| 243 | + EulerStackTransformPointer m_EulerStackTransform; |
| 244 | + |
| 245 | + /** Dummy sub transform to be used to set sub transforms of stack transform. */ |
| 246 | + ReducedDimensionEulerTransformPointer m_EulerDummySubTransform; |
| 247 | + |
| 248 | + /** Stack variables. */ |
| 249 | + unsigned int m_NumberOfSubTransforms; |
| 250 | + double m_StackOrigin, m_StackSpacing; |
| 251 | + |
| 252 | + /** Initialize the affine transform. */ |
| 253 | + unsigned int InitializeEulerTransform(); |
| 254 | + |
| 255 | +}; |
| 256 | + |
| 257 | + |
| 258 | +} // end namespace elastix |
| 259 | + |
| 260 | +#ifndef ITK_MANUAL_INSTANTIATION |
| 261 | +#include "elxEulerStackTransform.hxx" |
| 262 | +#endif |
| 263 | + |
| 264 | +#endif // end #ifndef __elxEulerStackTransform_h |
0 commit comments