1 /*=========================================================================
2  *
3  *  Copyright Insight Software Consortium
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 itkCenteredTransformInitializer_h
19 #define itkCenteredTransformInitializer_h
20 
21 #include "itkObject.h"
22 #include "itkObjectFactory.h"
23 #include "itkImageMomentsCalculator.h"
24 
25 #include <iostream>
26 
27 namespace itk
28 {
29 /** \class CenteredTransformInitializer
30  * \brief CenteredTransformInitializer is a helper class intended to
31  * initialize the center of rotation and the translation of Transforms having
32  * the center of rotation among their parameters.
33  *
34  * This class is connected to the fixed image, moving image and transform
35  * involved in the registration. Two modes of operation are possible:
36  *
37  * - Geometrical,
38  * - Center of mass
39  *
40  * In the first mode, the geometrical center of the moving image is passed as
41  * initial center of rotation to the transform and the vector from the center
42  * of the  fixed image to the center of the moving image is passed as the
43  * initial translation. This mode basically assumes that the anatomical objects
44  * to be registered are centered in their respective images. Hence the best
45  * initial guess for the registration is the one that superimposes those two
46  * centers.
47  *
48  * In the second mode, the moments of gray level values are computed
49  * for both images. The center of mass of the moving image is then
50  * used as center of rotation. The vector between the two centers of
51  * mass is passes as the initial translation to the transform. This
52  * second approach assumes that the moments of the anatomical objects
53  * are similar for both images and hence the best initial guess for
54  * registration is to superimpose both mass centers.  Note that this
55  * assumption will probably not hold in multi-modality registration.
56  *
57  * \ingroup ITKRegistrationCommon
58  * \ingroup ITKTransform
59  */
60 template< typename TTransform,
61           typename TFixedImage,
62           typename TMovingImage >
63 class ITK_TEMPLATE_EXPORT CenteredTransformInitializer:public Object
64 {
65 public:
66   ITK_DISALLOW_COPY_AND_ASSIGN(CenteredTransformInitializer);
67 
68   /** Standard class type aliases. */
69   using Self = CenteredTransformInitializer;
70   using Superclass = Object;
71   using Pointer = SmartPointer< Self >;
72   using ConstPointer = SmartPointer< const Self >;
73 
74   /** New macro for creation of through a Smart Pointer. */
75   itkNewMacro(Self);
76 
77   /** Run-time type information (and related methods). */
78   itkTypeMacro(CenteredTransformInitializer, Object);
79 
80   /** Type of the transform to initialize */
81   using TransformType = TTransform;
82   using TransformPointer = typename TransformType::Pointer;
83 
84   /** Dimension of parameters. */
85   static constexpr unsigned int InputSpaceDimension = TransformType::InputSpaceDimension;
86   static constexpr unsigned int OutputSpaceDimension = TransformType::OutputSpaceDimension;
87 
88   /** Image Types to use in the initialization of the transform */
89   using FixedImageType = TFixedImage;
90   using MovingImageType = TMovingImage;
91 
92   using FixedImagePointer = typename FixedImageType::ConstPointer;
93   using MovingImagePointer = typename MovingImageType::ConstPointer;
94 
95   /** Moment calculators */
96   using FixedImageCalculatorType = ImageMomentsCalculator< FixedImageType >;
97   using MovingImageCalculatorType = ImageMomentsCalculator< MovingImageType >;
98 
99   using FixedImageCalculatorPointer = typename FixedImageCalculatorType::Pointer;
100   using MovingImageCalculatorPointer = typename MovingImageCalculatorType::Pointer;
101 
102   /** Offset type. */
103   using OffsetType = typename TransformType::OffsetType;
104 
105   /** Point type. */
106   using InputPointType = typename TransformType::InputPointType;
107 
108   /** Vector type. */
109   using OutputVectorType = typename TransformType::OutputVectorType;
110 
111   /** Set the transform to be initialized */
112   itkSetObjectMacro(Transform,   TransformType);
113 
114   /** Set the fixed image used in the registration process */
115   itkSetConstObjectMacro(FixedImage,  FixedImageType);
116 
117   /** Set the moving image used in the registration process */
118   itkSetConstObjectMacro(MovingImage, MovingImageType);
119 
120   /** Initialize the transform using data from the images */
121   virtual void InitializeTransform();
122 
123   /** Select between using the geometrical center of the images or
124       using the center of mass given by the image intensities. */
GeometryOn()125   void GeometryOn() { m_UseMoments = false; }
MomentsOn()126   void MomentsOn()  { m_UseMoments = true; }
127 
128   /** Get() access to the moments calculators */
129   itkGetModifiableObjectMacro(FixedCalculator, FixedImageCalculatorType);
130   itkGetModifiableObjectMacro(MovingCalculator, MovingImageCalculatorType);
131 
132 protected:
133   CenteredTransformInitializer();
134   ~CenteredTransformInitializer() override = default;
135 
136   void PrintSelf(std::ostream & os, Indent indent) const override;
137 
138   itkGetModifiableObjectMacro(Transform, TransformType);
139 
140 private:
141   TransformPointer m_Transform;
142 
143   FixedImagePointer m_FixedImage;
144 
145   MovingImagePointer m_MovingImage;
146 
147   bool m_UseMoments;
148 
149   FixedImageCalculatorPointer  m_FixedCalculator;
150   MovingImageCalculatorPointer m_MovingCalculator;
151 }; //class CenteredTransformInitializer
152 }  // namespace itk
153 
154 #ifndef ITK_MANUAL_INSTANTIATION
155 #include "itkCenteredTransformInitializer.hxx"
156 #endif
157 
158 #endif /* itkCenteredTransformInitializer_h */
159