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
19 #include <iostream>
20
21 #include "itkTransform.h"
22
23 namespace itk
24 {
25 namespace itkTransformTestHelpers
26 {
27
28 template <
29 typename TScalar,
30 unsigned int NInputDimensions,
31 unsigned int NOutputDimensions>
32 class TransformTestHelper :
33 public Transform< TScalar, NInputDimensions, NOutputDimensions >
34 {
35 public:
36 using Self = TransformTestHelper;
37 using Superclass = Transform< TScalar, NInputDimensions, NOutputDimensions >;
38 using Pointer = SmartPointer< Self >;
39 using ConstPointer = SmartPointer< const Self >;
40
41 itkNewMacro( Self );
42 itkTypeMacro( TransformTestHelper, Transform );
43
44 using JacobianType = typename Superclass::JacobianType;
45 using JacobianPositionType = typename Superclass::JacobianPositionType;
46
47 using ParametersType = typename Superclass::ParametersType;
48 using InputPointType = typename Superclass::InputPointType;
49 using OutputPointType = typename Superclass::OutputPointType;
50 using InputVectorType = typename Superclass::InputVectorType;
51 using OutputVectorType = typename Superclass::OutputVectorType;
52 using InputVectorPixelType = typename Superclass::InputVectorPixelType;
53 using OutputVectorPixelType = typename Superclass::OutputVectorPixelType;
54 using InputVnlVectorType = typename Superclass::InputVnlVectorType;
55 using OutputVnlVectorType = typename Superclass::OutputVnlVectorType;
56 using InputCovariantVectorType = typename Superclass::InputCovariantVectorType;
57 using OutputCovariantVectorType = typename Superclass::OutputCovariantVectorType;
58
59 using InputDiffusionTensor3DType = typename Superclass::InputDiffusionTensor3DType;
60 using OutputDiffusionTensor3DType = typename Superclass::OutputDiffusionTensor3DType;
61
62 using InputSymmetricSecondRankTensorType = typename Superclass::InputSymmetricSecondRankTensorType;
63 using OutputSymmetricSecondRankTensorType = typename Superclass::OutputSymmetricSecondRankTensorType;
64
TransformPoint(const InputPointType & itkNotUsed (inputPoint)) const65 OutputPointType TransformPoint(const InputPointType & itkNotUsed(inputPoint) ) const override
66 {
67 OutputPointType outPoint;
68 outPoint.Fill( 22.0 );
69 return outPoint;
70 }
71
72 using Superclass::TransformVector;
TransformVector(const InputVectorType & itkNotUsed (inputVector)) const73 OutputVectorType TransformVector(const InputVectorType & itkNotUsed(inputVector) ) const override
74 {
75 OutputVectorType outVector;
76 outVector.Fill( 12.2 );
77 return outVector;
78 }
79
TransformVector(const InputVnlVectorType & itkNotUsed (inputVector)) const80 OutputVnlVectorType TransformVector(const InputVnlVectorType & itkNotUsed(inputVector) ) const override
81 {
82 OutputVnlVectorType outVector( 15.0 );
83 return outVector;
84 }
85
TransformVector(const InputVectorPixelType & itkNotUsed (inputVector)) const86 OutputVectorPixelType TransformVector(const InputVectorPixelType & itkNotUsed(inputVector) ) const override
87 {
88 OutputVectorPixelType outVector;
89 outVector.Fill( 88.8 );
90 return outVector;
91 }
92
93 using Superclass::TransformCovariantVector;
TransformCovariantVector(const InputCovariantVectorType & itkNotUsed (inputVector)) const94 OutputCovariantVectorType TransformCovariantVector(const InputCovariantVectorType & itkNotUsed(inputVector) ) const override
95 {
96 OutputCovariantVectorType outVector;
97 outVector.Fill( 8.9 );
98 return outVector;
99 }
100
TransformCovariantVector(const InputVectorPixelType & itkNotUsed (inputVector)) const101 OutputVectorPixelType TransformCovariantVector(const InputVectorPixelType & itkNotUsed(inputVector) ) const override
102 {
103 OutputVectorPixelType outVector;
104 outVector.Fill( 6.9 );
105 return outVector;
106 }
107
108 using Superclass::TransformDiffusionTensor3D;
TransformDiffusionTensor3D(const InputDiffusionTensor3DType & itkNotUsed (tensor)) const109 OutputDiffusionTensor3DType TransformDiffusionTensor3D( const InputDiffusionTensor3DType & itkNotUsed( tensor ) ) const override
110 {
111 OutputDiffusionTensor3DType outTensor;
112 outTensor.Fill( 2.1 );
113 return outTensor;
114 }
115
TransformDiffusionTensor3D(const InputVectorPixelType & itkNotUsed (tensor)) const116 OutputVectorPixelType TransformDiffusionTensor3D( const InputVectorPixelType & itkNotUsed( tensor ) ) const override
117 {
118 OutputVectorPixelType outTensor;
119 outTensor.Fill( 29.1 );
120 return outTensor;
121 }
122
123 using Superclass::TransformSymmetricSecondRankTensor;
TransformSymmetricSecondRankTensor(const InputSymmetricSecondRankTensorType & itkNotUsed (tensor)) const124 OutputSymmetricSecondRankTensorType TransformSymmetricSecondRankTensor(
125 const InputSymmetricSecondRankTensorType & itkNotUsed( tensor ) ) const override
126 {
127 OutputSymmetricSecondRankTensorType outTensor;
128 outTensor.Fill( 10.0 );
129 return outTensor;
130 }
131
TransformSymmetricSecondRankTensor(const InputVectorPixelType & itkNotUsed (tensor)) const132 OutputVectorPixelType TransformSymmetricSecondRankTensor(
133 const InputVectorPixelType & itkNotUsed( tensor ) ) const override
134 {
135 OutputVectorPixelType outTensor;
136 outTensor.Fill( 55.9 );
137 return outTensor;
138 }
139
SetParameters(const ParametersType &)140 void SetParameters(const ParametersType &) override
141 {
142 }
143
SetFixedParameters(const ParametersType &)144 void SetFixedParameters(const ParametersType &) override
145 {
146 }
147
ComputeJacobianWithRespectToParameters(const InputPointType &,JacobianType & jacobian) const148 void ComputeJacobianWithRespectToParameters(const InputPointType &,
149 JacobianType & jacobian) const override
150 {
151 jacobian.SetSize(3, 6);
152 jacobian.Fill(1);
153 }
154
155 using Superclass::ComputeJacobianWithRespectToPosition;
ComputeJacobianWithRespectToPosition(const InputPointType &,JacobianPositionType & jacobian) const156 void ComputeJacobianWithRespectToPosition(
157 const InputPointType &,
158 JacobianPositionType & jacobian ) const override
159 {
160 jacobian.fill(1.0);
161 }
162
163 };
164
165 template <
166 typename TScalar,
167 unsigned int NInputDimensions,
168 unsigned int NOutputDimensions>
169 class TransformTester
170 {
171 public:
172 using Self = TransformTester;
173
174 using TransformType = TransformTestHelper<double, NInputDimensions, NOutputDimensions>;
175
176 using JacobianType = typename TransformType::JacobianType;
177 using ParametersType = typename TransformType::ParametersType;
178 using InputPointType = typename TransformType::InputPointType;
179 using OutputPointType = typename TransformType::OutputPointType;
180 using InputVectorType = typename TransformType::InputVectorType;
181 using OutputVectorType = typename TransformType::OutputVectorType;
182 using InputVectorPixelType = typename TransformType::InputVectorPixelType;
183 using OutputVectorPixelType = typename TransformType::OutputVectorPixelType;
184 using InputVnlVectorType = typename TransformType::InputVnlVectorType;
185 using OutputVnlVectorType = typename TransformType::OutputVnlVectorType;
186 using InputCovariantVectorType = typename TransformType::InputCovariantVectorType;
187 using OutputCovariantVectorType = typename TransformType::OutputCovariantVectorType;
188
189 using InputDiffusionTensor3DType = typename TransformType::InputDiffusionTensor3DType;
190 using OutputDiffusionTensor3DType = typename TransformType::OutputDiffusionTensor3DType;
191
192 using InputSymmetricSecondRankTensorType = typename TransformType::InputSymmetricSecondRankTensorType;
193 using OutputSymmetricSecondRankTensorType = typename TransformType::OutputSymmetricSecondRankTensorType;
194
RunTests()195 bool RunTests()
196 {
197 std::cout << "Testing itkTransform<" << NInputDimensions << "," << NOutputDimensions << ">" << std::endl;
198 typename TransformType::Pointer transform = TransformType::New();
199
200 InputPointType pnt;
201 pnt.Fill(2.9);
202
203 transform->TransformPoint(pnt);
204 std::cout << "TransformPoint() OK" << std::endl;
205
206 InputVectorType vec;
207 transform->TransformVector(vec);
208 transform->TransformVector(vec,pnt);
209
210 InputVectorPixelType vecpix;
211 vecpix.SetSize( NInputDimensions );
212 vecpix.Fill(1.7);
213 transform->TransformVector(vecpix);
214 transform->TransformVector(vecpix,pnt);
215
216 InputVnlVectorType vec_vnl;
217 transform->TransformVector(vec_vnl);
218 transform->TransformVector(vec_vnl,pnt);
219 std::cout << "TransformVector() OK" << std::endl;
220
221 InputCovariantVectorType covec;
222 transform->TransformCovariantVector(covec);
223 transform->TransformCovariantVector(vecpix);
224 transform->TransformCovariantVector(covec,pnt);
225 transform->TransformCovariantVector(vecpix,pnt);
226 std::cout << "TransformCovariantVector() OK" << std::endl;
227
228 InputDiffusionTensor3DType difften;
229 vecpix.SetSize( 6 );
230 vecpix.Fill(1.7);
231 transform->TransformDiffusionTensor3D(difften);
232 transform->TransformDiffusionTensor3D(difften,pnt);
233 transform->TransformDiffusionTensor3D(vecpix);
234 transform->TransformDiffusionTensor3D(vecpix,pnt);
235 std::cout << "TransformDiffusionTensor3D() OK" << std::endl;
236
237 InputSymmetricSecondRankTensorType ssrten;
238 vecpix.SetSize(NInputDimensions*NInputDimensions);
239 vecpix.Fill(0);
240 transform->TransformSymmetricSecondRankTensor(ssrten);
241 transform->TransformSymmetricSecondRankTensor(ssrten,pnt);
242 transform->TransformSymmetricSecondRankTensor(vecpix);
243 transform->TransformSymmetricSecondRankTensor(vecpix,pnt);
244 std::cout << "TransformSymmetricSecondRankTensor() OK" << std::endl;
245
246 typename TransformType::ParametersType parameters(6);
247 try
248 {
249 transform->SetParameters(parameters);
250 }
251 catch( itk::ExceptionObject & e )
252 {
253 std::cerr << e << std::endl;
254 }
255
256 try
257 {
258 transform->GetParameters();
259 }
260 catch( itk::ExceptionObject & e )
261 {
262 std::cerr << e << std::endl;
263 }
264
265 typename TransformType::JacobianType jacobian;
266 try
267 {
268 transform->ComputeJacobianWithRespectToParameters(pnt, jacobian);
269 }
270 catch( itk::ExceptionObject & e )
271 {
272 std::cerr << e << std::endl;
273 }
274
275 typename TransformType::JacobianPositionType jacobian_position;
276 try
277 {
278 transform->ComputeJacobianWithRespectToPosition(pnt, jacobian_position);
279 }
280 catch( itk::ExceptionObject & e )
281 {
282 std::cerr << e << std::endl;
283 }
284
285 typename TransformType::InverseJacobianPositionType inv_jacobian_position;
286 try
287 {
288 transform->ComputeInverseJacobianWithRespectToPosition(pnt, inv_jacobian_position);
289 }
290 catch( itk::ExceptionObject & e )
291 {
292 std::cerr << e << std::endl;
293 }
294
295 typename TransformType::DerivativeType update( transform->GetNumberOfParameters() );
296 update.Fill(1);
297 try
298 {
299 transform->UpdateTransformParameters( update );
300 }
301 catch( itk::ExceptionObject & e )
302 {
303 std::cerr << e << std::endl;
304 }
305
306 // Exercise some methods
307 transform->Print( std::cout );
308 std::cout << transform->GetNameOfClass() << std::endl;
309
310 return true;
311 }
312
313 };
314
315
316 }
317 }
318
itkTransformTest(int,char * [])319 int itkTransformTest(int, char * [] )
320 {
321 itk::itkTransformTestHelpers::TransformTester<double,3,3> tester33;
322 tester33.RunTests();
323 std::cout << "passed 3 3" << std::endl;
324
325 itk::itkTransformTestHelpers::TransformTester<double,3,2> tester32;
326 tester32.RunTests();
327 std::cout << "passed 3 2" << std::endl;
328
329 itk::itkTransformTestHelpers::TransformTester<double,2,3> tester23;
330 tester23.RunTests();
331 std::cout << "passed 2 3" << std::endl;
332
333
334 std::cout << "[ PASSED ]" << std::endl;
335 return EXIT_SUCCESS;
336
337 }
338