go home Home | Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Data Structures | File List | Namespace Members | Data Fields | Globals | Related Pages
itkStackTransform.h
Go to the documentation of this file.
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 itkStackTransform_h
19#define itkStackTransform_h
20
22#include "itkIndex.h"
23
24#include <cassert>
25
26namespace itk
27{
28
39template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
40class ITK_TEMPLATE_EXPORT StackTransform : public AdvancedTransform<TScalarType, NInputDimensions, NOutputDimensions>
41{
42public:
44
48 using Pointer = SmartPointer<Self>;
49 using ConstPointer = SmartPointer<const Self>;
50
53
55 itkStaticConstMacro(InputSpaceDimension, unsigned int, NInputDimensions);
56 itkStaticConstMacro(OutputSpaceDimension, unsigned int, NOutputDimensions);
57 itkStaticConstMacro(ReducedInputSpaceDimension, unsigned int, NInputDimensions - 1);
58 itkStaticConstMacro(ReducedOutputSpaceDimension, unsigned int, NOutputDimensions - 1);
59
61 using typename Superclass::ScalarType;
62 using typename Superclass::ParametersType;
63 using typename Superclass::FixedParametersType;
64 using typename Superclass::NumberOfParametersType;
65 using typename Superclass::ParametersValueType;
66 using typename Superclass::JacobianType;
69 using typename Superclass::SpatialHessianType;
72 using typename Superclass::InputPointType;
73 using typename Superclass::InputVectorType;
74 using typename Superclass::OutputVectorType;
75 using typename Superclass::InputVnlVectorType;
76 using typename Superclass::OutputVnlVectorType;
77 using typename Superclass::OutputCovariantVectorType;
78 using typename Superclass::InputCovariantVectorType;
79 using typename Superclass::OutputPointType;
80 using typename Superclass::OutputVectorPixelType;
81 using typename Superclass::InputVectorPixelType;
82
87 using SubTransformJacobianType = typename SubTransformType::JacobianType;
88
90 using SubTransformInputPointType = typename SubTransformType::InputPointType;
91 using SubTransformOutputPointType = typename SubTransformType::OutputPointType;
92
94 using ParametersArrayType = typename ParametersType::ArrayType;
95
97 OutputPointType
98 TransformPoint(const InputPointType & inputPoint) const override;
99
105 void
106 GetJacobian(const InputPointType & inputPoint, JacobianType & jac, NonZeroJacobianIndicesType & nzji) const override;
107
110 void
111 SetParameters(const ParametersType & param) override;
112
115 const ParametersType &
116 GetParameters() const override;
117
119 void
120 SetFixedParameters(const FixedParametersType & fixedParameters) override
121 {
122 const auto numberOfFixedParameters = fixedParameters.size();
123 if (numberOfFixedParameters < NumberOfGeneralFixedParametersOfStack)
124 {
125 itkExceptionMacro("The number of FixedParameters (" << numberOfFixedParameters << ") should be at least "
126 << NumberOfGeneralFixedParametersOfStack);
127 }
128
129 if (Superclass::m_FixedParameters != fixedParameters)
130 {
131 Superclass::m_FixedParameters = fixedParameters;
132
133 CreateSubTransforms(FixedParametersType(fixedParameters.data_block() + NumberOfGeneralFixedParametersOfStack,
134 numberOfFixedParameters - NumberOfGeneralFixedParametersOfStack));
135 UpdateStackSpacingAndOrigin();
136 this->Modified();
137 }
138 }
139
140
142 NumberOfParametersType
143 GetNumberOfParameters() const override
144 {
145 if (this->m_SubTransformContainer.empty())
146 {
147 return 0;
148 }
149 else
150 {
151 return this->m_SubTransformContainer.size() * m_SubTransformContainer[0]->GetNumberOfParameters();
152 }
153 }
154
155
157 void
158 SetNumberOfSubTransforms(const unsigned int num)
159 {
160 if (this->m_SubTransformContainer.size() != num)
161 {
162 this->m_SubTransformContainer.clear();
163 this->m_SubTransformContainer.resize(num);
164 this->Modified();
165 }
166 }
167
168
169 auto
171 {
172 return static_cast<unsigned>(m_SubTransformContainer.size());
173 }
174
175
177 itkSetMacro(StackSpacing, TScalarType);
178 itkGetConstMacro(StackSpacing, TScalarType);
179 itkSetMacro(StackOrigin, TScalarType);
180 itkGetConstMacro(StackOrigin, TScalarType);
181
183 void
184 SetSubTransform(unsigned int i, SubTransformType * transform)
185 {
186 this->m_SubTransformContainer[i] = transform;
187 this->Modified();
188 }
189
190
193 void
195 {
196 const SubTransformType * const subTransform =
197 m_SubTransformContainer.empty() ? nullptr : m_SubTransformContainer.front();
198 this->UpdateFixedParametersInternally((subTransform == nullptr) ? FixedParametersType()
199 : subTransform->GetFixedParameters());
200 }
201
202
204 void
206 {
207 const auto & fixedParametersOfSubTransform = transform.GetFixedParameters();
208 const auto & parametersOfSubTransform = transform.GetParameters();
209
210 UpdateFixedParametersInternally(fixedParametersOfSubTransform);
211
212 for (auto & subTransform : m_SubTransformContainer)
213 {
214 // Copy transform
215 SubTransformPointer transformcopy = dynamic_cast<SubTransformType *>(transform.CreateAnother().GetPointer());
216 transformcopy->SetFixedParameters(fixedParametersOfSubTransform);
217 transformcopy->SetParameters(parametersOfSubTransform);
218 // Set sub transform
219 subTransform = transformcopy;
220 }
221 }
222
223
225 SubTransformPointer
226 GetSubTransform(unsigned int i)
227 {
228 return this->m_SubTransformContainer[i];
229 }
230
231
233 NumberOfParametersType
235
236protected:
237 StackTransform() = default;
238 ~StackTransform() override = default;
239
240 // Indices of the general fixed parameters into the FixedParameters array, and the number of those parameters.
241 enum
242 {
246 NumberOfGeneralFixedParametersOfStack
247 };
248
249 void
250 CreateSubTransforms(const FixedParametersType & fixedParametersOfSubTransform)
251 {
252 assert(Superclass::m_FixedParameters.size() >= NumberOfGeneralFixedParametersOfStack);
253 const auto numberOfSubTransforms = Superclass::m_FixedParameters[IndexOfNumberOfSubTransforms];
254
255 if (numberOfSubTransforms >= 0.0 && numberOfSubTransforms <= UINT_MAX &&
256 static_cast<double>(static_cast<unsigned>(numberOfSubTransforms)) == numberOfSubTransforms)
257 {
258 m_SubTransformContainer.resize(static_cast<unsigned>(numberOfSubTransforms));
259 }
260 else
261 {
262 itkExceptionMacro("The FixedParameters element (" << numberOfSubTransforms
263 << ") should be a valid number (the number of subtransforms).");
264 }
265
266 for (auto & subTransform : m_SubTransformContainer)
267 {
268 subTransform = this->CreateSubTransform();
269 subTransform->SetFixedParameters(fixedParametersOfSubTransform);
270 }
271 }
272
273 void
275 {
276 assert(Superclass::m_FixedParameters.size() >= NumberOfGeneralFixedParametersOfStack);
277 m_StackSpacing = Superclass::m_FixedParameters[IndexOfStackSpacing];
278 m_StackOrigin = Superclass::m_FixedParameters[IndexOfStackOrigin];
279 }
280
281
284 virtual void
285 UpdateFixedParametersInternally(const FixedParametersType & fixedParametersOfSubTransform)
286 {
287 const auto numberOfFixedParametersOfSubTransform = fixedParametersOfSubTransform.size();
288
289 FixedParametersType & fixedParametersOfStack = this->Superclass::m_FixedParameters;
290
291 const auto minimumNumberOfFixedParametersOfStack =
292 NumberOfGeneralFixedParametersOfStack + numberOfFixedParametersOfSubTransform;
293
294 if (fixedParametersOfStack.size() < minimumNumberOfFixedParametersOfStack)
295 {
296 fixedParametersOfStack.set_size(minimumNumberOfFixedParametersOfStack);
297 }
298 fixedParametersOfStack[IndexOfNumberOfSubTransforms] = m_SubTransformContainer.size();
299 fixedParametersOfStack[IndexOfStackOrigin] = m_StackOrigin;
300 fixedParametersOfStack[IndexOfStackSpacing] = m_StackSpacing;
301 std::copy_n(fixedParametersOfSubTransform.begin(),
302 numberOfFixedParametersOfSubTransform,
303 fixedParametersOfStack.begin() + NumberOfGeneralFixedParametersOfStack);
304 }
305
306private:
307 // Private using-declarations, to avoid `-Woverloaded-virtual` warnings from GCC (GCC 11.4).
308 using Superclass::TransformCovariantVector;
309 using Superclass::TransformVector;
310
314 virtual SubTransformPointer
316
317
318 static constexpr const char * unimplementedOverrideMessage = "Not implemented for StackTransform";
319
321 OutputVectorType
322 TransformVector(const InputVectorType &) const override
323 {
324 itkExceptionMacro(<< unimplementedOverrideMessage);
325 }
326
327 OutputVnlVectorType
328 TransformVector(const InputVnlVectorType &) const override
329 {
330 itkExceptionMacro(<< unimplementedOverrideMessage);
331 }
332
333 OutputCovariantVectorType
334 TransformCovariantVector(const InputCovariantVectorType &) const override
335 {
336 itkExceptionMacro(<< unimplementedOverrideMessage);
337 }
338
339
341 void
342 GetSpatialJacobian(const InputPointType &, SpatialJacobianType &) const override
343 {
344 itkExceptionMacro(<< unimplementedOverrideMessage);
345 }
346
347 void
348 GetSpatialHessian(const InputPointType &, SpatialHessianType &) const override
349 {
350 itkExceptionMacro(<< unimplementedOverrideMessage);
351 }
352
353 void
354 GetJacobianOfSpatialJacobian(const InputPointType &,
356 NonZeroJacobianIndicesType &) const override
357 {
358 itkExceptionMacro(<< unimplementedOverrideMessage);
359 }
360
361 void
362 GetJacobianOfSpatialJacobian(const InputPointType &,
365 NonZeroJacobianIndicesType &) const override
366 {
367 itkExceptionMacro(<< unimplementedOverrideMessage);
368 }
369
370 void
371 GetJacobianOfSpatialHessian(const InputPointType &,
373 NonZeroJacobianIndicesType &) const override
374 {
375 itkExceptionMacro(<< unimplementedOverrideMessage);
376 }
377
378
379 void
380 GetJacobianOfSpatialHessian(const InputPointType &,
383 NonZeroJacobianIndicesType &) const override
384 {
385 itkExceptionMacro(<< unimplementedOverrideMessage);
386 }
387
388
389 // Transform container
390 std::vector<SubTransformPointer> m_SubTransformContainer{};
391
392 // Stack spacing and origin of last dimension
393 TScalarType m_StackSpacing{ 1.0 };
394 TScalarType m_StackOrigin{ 0.0 };
395};
396
397} // end namespace itk
398
399#ifndef ITK_MANUAL_INSTANTIATION
400# include "itkStackTransform.hxx"
401#endif
402
403#endif
Transform maps points, vectors and covariant vectors from an input space to an output space.
FixedArray< Matrix< ScalarType, InputSpaceDimension, InputSpaceDimension >, OutputSpaceDimension > SpatialHessianType
Matrix< ScalarType, OutputSpaceDimension, InputSpaceDimension > SpatialJacobianType
Implements stack of transforms: one for every last dimension index.
itkStaticConstMacro(ReducedOutputSpaceDimension, unsigned int, NOutputDimensions - 1)
itkStaticConstMacro(InputSpaceDimension, unsigned int, NInputDimensions)
itkStaticConstMacro(ReducedInputSpaceDimension, unsigned int, NInputDimensions - 1)
typename SubTransformType::Pointer SubTransformPointer
NumberOfParametersType GetNumberOfParameters() const override
void CreateSubTransforms(const FixedParametersType &fixedParametersOfSubTransform)
StackTransform()=default
void GetSpatialJacobian(const InputPointType &, SpatialJacobianType &) const override
void SetFixedParameters(const FixedParametersType &fixedParameters) override
typename SubTransformType::JacobianType SubTransformJacobianType
NumberOfParametersType GetNumberOfNonZeroJacobianIndices() const override
void SetSubTransform(unsigned int i, SubTransformType *transform)
typename SubTransformType::InputPointType SubTransformInputPointType
void GetJacobianOfSpatialHessian(const InputPointType &, SpatialHessianType &, JacobianOfSpatialHessianType &, NonZeroJacobianIndicesType &) const override
OutputPointType TransformPoint(const InputPointType &inputPoint) const override
SmartPointer< const Self > ConstPointer
void GetJacobianOfSpatialJacobian(const InputPointType &, SpatialJacobianType &, JacobianOfSpatialJacobianType &, NonZeroJacobianIndicesType &) const override
void GetJacobianOfSpatialHessian(const InputPointType &, JacobianOfSpatialHessianType &, NonZeroJacobianIndicesType &) const override
~StackTransform() override=default
const ParametersType & GetParameters() const override
typename ParametersType::ArrayType ParametersArrayType
void SetAllSubTransforms(const SubTransformType &transform)
void SetNumberOfSubTransforms(const unsigned int num)
OutputVectorType TransformVector(const InputVectorType &) const override
ITK_DISALLOW_COPY_AND_MOVE(StackTransform)
auto GetNumberOfSubTransforms() const
void GetJacobianOfSpatialJacobian(const InputPointType &, JacobianOfSpatialJacobianType &, NonZeroJacobianIndicesType &) const override
typename SubTransformType::OutputPointType SubTransformOutputPointType
virtual void UpdateFixedParametersInternally(const FixedParametersType &fixedParametersOfSubTransform)
void GetJacobian(const InputPointType &inputPoint, JacobianType &jac, NonZeroJacobianIndicesType &nzji) const override
void GetSpatialHessian(const InputPointType &, SpatialHessianType &) const override
OutputCovariantVectorType TransformCovariantVector(const InputCovariantVectorType &) const override
itkStaticConstMacro(OutputSpaceDimension, unsigned int, NOutputDimensions)
virtual SubTransformPointer CreateSubTransform() const =0
SubTransformPointer GetSubTransform(unsigned int i)
void SetParameters(const ParametersType &param) override
OutputVnlVectorType TransformVector(const InputVnlVectorType &) const override


Generated on 2024-07-17 for elastix by doxygen 1.11.0 (9b424b03c9833626cd435af22a444888fbbb192d) elastix logo