1 /*
2  * Medical Image Registration ToolKit (MIRTK)
3  *
4  * Copyright 2013-2015 Imperial College London
5  * Copyright 2013-2015 Andreas Schuh
6  *
7  * Licensed under the Apache License, Version 2.0 (the "License");
8  * you may not use this file except in compliance with the License.
9  * You may obtain a copy of the License at
10  *
11  *     http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing, software
14  * distributed under the License is distributed on an "AS IS" BASIS,
15  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16  * See the License for the specific language governing permissions and
17  * limitations under the License.
18  */
19 
20 #ifndef MIRTK_LieBracketImageFilter_H
21 #define MIRTK_LieBracketImageFilter_H
22 
23 #include "mirtk/ImageToImage.h"
24 
25 #include "mirtk/ImageAttributes.h"
26 #include "mirtk/BaseImage.h"
27 #include "mirtk/GenericImage.h"
28 
29 
30 namespace mirtk {
31 
32 
33 /**
34  * Base class for image filters which compute the Lie bracket of two vector fields.
35  */
36 template <class TVoxel>
37 class LieBracketImageFilter : public ImageToImage<TVoxel>
38 {
39   mirtkAbstractImageFilterMacro(LieBracketImageFilter, TVoxel);
40 
41 protected:
42 
43   using Baseclass::Input;
44 
45   /// Second input vector field
46   const ImageType *_Input2;
47 
48   /// Constructor
49   LieBracketImageFilter();
50 
51   /// Initialize filter
52   virtual void Initialize();
53 
54 public:
55 
56   /// Construct Lie bracket filter for given image domain
57   static LieBracketImageFilter *New(const ImageAttributes &, bool = true);
58 
59   /// Construct Lie bracket filter for given input vector field
60   static LieBracketImageFilter *New(const BaseImage *, bool = true);
61 
62   /// Destructor
63   virtual ~LieBracketImageFilter();
64 
65   /// Set n-th input
66   virtual void Input(int, const ImageType *);
67 
68   /// Get n-th input
69   virtual const ImageType *Input(int) const;
70 
71   /// Get n-th input
72   ///
73   /// This overload can be used to disambiguate the getter Input(0) from
74   /// the setter Input(NULL). Alternatively, use Input(int(0)).
75   virtual const ImageType *GetInput(int) const;
76 
77 };
78 
79 ///////////////////////////////////////////////////////////////////////////////
80 // Inline definitions
81 ///////////////////////////////////////////////////////////////////////////////
82 
83 // ----------------------------------------------------------------------------
84 template <class VoxelType>
LieBracketImageFilter()85 LieBracketImageFilter<VoxelType>::LieBracketImageFilter()
86 :
87   _Input2(NULL)
88 {
89 }
90 
91 // ----------------------------------------------------------------------------
92 template <class VoxelType>
~LieBracketImageFilter()93 LieBracketImageFilter<VoxelType>::~LieBracketImageFilter()
94 {
95 }
96 
97 // --------------------------------------------------------------------------
98 template <class VoxelType>
Input(int i,const ImageType * image)99 void LieBracketImageFilter<VoxelType>::Input(int i, const ImageType *image)
100 {
101   if      (i == 0) Baseclass::Input(image);
102   else if (i == 1) _Input2 = image;
103   else {
104     cerr << this->NameOfClass() << "::Input: Input index out of range: " << i << endl;
105     exit(1);
106   }
107 }
108 
109 // --------------------------------------------------------------------------
110 template <class VoxelType>
111 const typename LieBracketImageFilter<VoxelType>::ImageType *
Input(int i)112 LieBracketImageFilter<VoxelType>::Input(int i) const
113 {
114   if      (i == 0) return Baseclass::Input();
115   else if (i == 1) return _Input2;
116   else {
117     cerr << this->NameOfClass() << "::Input: Input index out of range: " << i << endl;
118     exit(1);
119   }
120 }
121 
122 // --------------------------------------------------------------------------
123 template <class VoxelType>
124 const typename LieBracketImageFilter<VoxelType>::ImageType *
GetInput(int i)125 LieBracketImageFilter<VoxelType>::GetInput(int i) const
126 {
127   return Input(i); // with explicit "int" type
128 }
129 
130 // --------------------------------------------------------------------------
131 template <class VoxelType>
Initialize()132 void LieBracketImageFilter<VoxelType>::Initialize()
133 {
134   // Initialize base class
135   Baseclass::Initialize();
136 
137   // Check second input
138   if (_Input2 == NULL) {
139     cerr << this->NameOfClass() << "::Initialize: Filter has no second input" << endl;
140     exit(1);
141   }
142   if (!_Input2->HasSpatialAttributesOf(this->_Input) || _Input2->T() != this->_Input->T()) {
143     cerr << this->NameOfClass() << "::Initialize: Attributes of input images do not match" << endl;
144     exit(1);
145   }
146 }
147 
148 
149 } // namespace mirtk
150 
151 #endif // MIRTK_LieBracketImageFilter_H
152 
153 ///////////////////////////////////////////////////////////////////////////////
154 // Instantiation of filter implementation
155 ///////////////////////////////////////////////////////////////////////////////
156 
157 #ifndef MIRTK_LieBracketImageFilterNew_H
158 #define MIRTK_LieBracketImageFilterNew_H
159 
160 #include "mirtk/Memory.h"
161 #include "mirtk/GenericImage.h"
162 #include "mirtk/LieBracketImageFilter2D.h"
163 #include "mirtk/LieBracketImageFilter3D.h"
164 #include "mirtk/DifferenceOfCompositionLieBracketImageFilter3D.h"
165 
166 
167 namespace mirtk {
168 
169 
170 // ----------------------------------------------------------------------------
171 template <class VoxelType>
172 LieBracketImageFilter<VoxelType> *
New(const ImageAttributes & attr,bool usejac)173 LieBracketImageFilter<VoxelType>::New(const ImageAttributes &attr, bool usejac)
174 {
175   if (attr._z > 1) {
176     if (usejac) return new LieBracketImageFilter3D<VoxelType>;
177     else        return new DifferenceOfCompositionLieBracketImageFilter3D<VoxelType>;
178   } else {
179     if (usejac) return new LieBracketImageFilter2D<VoxelType>;
180     else {
181       cerr << NameOfType() << "::New: DifferenceOfCompositionLieBracketImageFilter2D not implemented" << endl;
182       exit(1);
183     }
184   }
185 }
186 
187 // ----------------------------------------------------------------------------
188 template <class VoxelType>
189 LieBracketImageFilter<VoxelType> *
New(const Image * image,bool usejac)190 LieBracketImageFilter<VoxelType>::New(const Image *image, bool usejac)
191 {
192   return LieBracketImageFilter::New(image->Attributes(), usejac);
193 }
194 
195 // ----------------------------------------------------------------------------
196 template <class VoxelType>
197 void liebracket(GenericImage<VoxelType> *ov,
198                 const GenericImage<VoxelType> *lv,
199                 const GenericImage<VoxelType> *rv, bool usejac = true)
200 {
201   typedef LieBracketImageFilter<VoxelType> LieBracketFilter;
202   UniquePtr<LieBracketFilter> filter(LieBracketFilter::New(lv, usejac));
203   filter->Input(0, lv);
204   filter->Input(1, rv);
205   filter->Output(ov);
206   filter->Run();
207 }
208 
209 
210 } // namespace mirtk
211 
212 #endif // MIRTK_LieBracketImageFilterNew_H
213