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