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
24namespace itk
25{
26
37template <class TScalarType, unsigned int NInputDimensions, unsigned int NOutputDimensions>
38class ITK_TEMPLATE_EXPORT StackTransform : public AdvancedTransform<TScalarType, NInputDimensions, NOutputDimensions>
39{
40public:
42
46 using Pointer = SmartPointer<Self>;
47 using ConstPointer = SmartPointer<const Self>;
48
51
53 itkStaticConstMacro(InputSpaceDimension, unsigned int, NInputDimensions);
54 itkStaticConstMacro(OutputSpaceDimension, unsigned int, NOutputDimensions);
55 itkStaticConstMacro(ReducedInputSpaceDimension, unsigned int, NInputDimensions - 1);
56 itkStaticConstMacro(ReducedOutputSpaceDimension, unsigned int, NOutputDimensions - 1);
57
59 using typename Superclass::ScalarType;
60 using typename Superclass::ParametersType;
61 using typename Superclass::FixedParametersType;
62 using typename Superclass::NumberOfParametersType;
63 using typename Superclass::ParametersValueType;
64 using typename Superclass::JacobianType;
67 using typename Superclass::SpatialHessianType;
70 using typename Superclass::InputPointType;
71 using typename Superclass::InputVectorType;
72 using typename Superclass::OutputVectorType;
73 using typename Superclass::InputVnlVectorType;
74 using typename Superclass::OutputVnlVectorType;
75 using typename Superclass::OutputCovariantVectorType;
76 using typename Superclass::InputCovariantVectorType;
77 using typename Superclass::OutputPointType;
78 using typename Superclass::OutputVectorPixelType;
79 using typename Superclass::InputVectorPixelType;
80
85 using SubTransformJacobianType = typename SubTransformType::JacobianType;
86
88 using SubTransformInputPointType = typename SubTransformType::InputPointType;
89 using SubTransformOutputPointType = typename SubTransformType::OutputPointType;
90
92 using ParametersArrayType = typename ParametersType::ArrayType;
93
95 OutputPointType
96 TransformPoint(const InputPointType & inputPoint) const override;
97
103 void
104 GetJacobian(const InputPointType & inputPoint, JacobianType & jac, NonZeroJacobianIndicesType & nzji) const override;
105
108 void
109 SetParameters(const ParametersType & param) override;
110
113 const ParametersType &
114 GetParameters() const override;
115
117 void
118 SetFixedParameters(const FixedParametersType & fixedParameters) override
119 {
120 const auto numberOfFixedParameters = fixedParameters.size();
121 if (numberOfFixedParameters < NumberOfGeneralFixedParametersOfStack)
122 {
123 itkExceptionMacro(<< "The number of FixedParameters (" << numberOfFixedParameters << ") should be at least "
124 << NumberOfGeneralFixedParametersOfStack);
125 }
126
127 if (Superclass::m_FixedParameters != fixedParameters)
128 {
129 Superclass::m_FixedParameters = fixedParameters;
130
131 CreateSubTransforms(FixedParametersType(fixedParameters.data_block() + NumberOfGeneralFixedParametersOfStack,
132 numberOfFixedParameters - NumberOfGeneralFixedParametersOfStack));
133 UpdateStackSpacingAndOrigin();
134 this->Modified();
135 }
136 }
137
138
140 NumberOfParametersType
141 GetNumberOfParameters() const override
142 {
143 if (this->m_SubTransformContainer.empty())
144 {
145 return 0;
146 }
147 else
148 {
149 return this->m_SubTransformContainer.size() * m_SubTransformContainer[0]->GetNumberOfParameters();
150 }
151 }
152
153
155 void
156 SetNumberOfSubTransforms(const unsigned int num)
157 {
158 if (this->m_SubTransformContainer.size() != num)
159 {
160 this->m_SubTransformContainer.clear();
161 this->m_SubTransformContainer.resize(num);
162 this->Modified();
163 }
164 }
165
166
167 auto
169 {
170 return static_cast<unsigned>(m_SubTransformContainer.size());
171 }
172
173
175 itkSetMacro(StackSpacing, TScalarType);
176 itkGetConstMacro(StackSpacing, TScalarType);
177 itkSetMacro(StackOrigin, TScalarType);
178 itkGetConstMacro(StackOrigin, TScalarType);
179
181 void
182 SetSubTransform(unsigned int i, SubTransformType * transform)
183 {
184 this->m_SubTransformContainer[i] = transform;
185 this->Modified();
186 }
187
188
191 void
193 {
194 const SubTransformType * const subTransform =
195 m_SubTransformContainer.empty() ? nullptr : m_SubTransformContainer.front();
196 this->UpdateFixedParametersInternally((subTransform == nullptr) ? FixedParametersType()
197 : subTransform->GetFixedParameters());
198 }
199
200
202 void
204 {
205 const auto & fixedParametersOfSubTransform = transform.GetFixedParameters();
206 const auto & parametersOfSubTransform = transform.GetParameters();
207
208 UpdateFixedParametersInternally(fixedParametersOfSubTransform);
209
210 for (auto & subTransform : m_SubTransformContainer)
211 {
212 // Copy transform
213 SubTransformPointer transformcopy = dynamic_cast<SubTransformType *>(transform.CreateAnother().GetPointer());
214 transformcopy->SetFixedParameters(fixedParametersOfSubTransform);
215 transformcopy->SetParameters(parametersOfSubTransform);
216 // Set sub transform
217 subTransform = transformcopy;
218 }
219 }
220
221
223 SubTransformPointer
224 GetSubTransform(unsigned int i)
225 {
226 return this->m_SubTransformContainer[i];
227 }
228
229
231 NumberOfParametersType
233
234protected:
235 StackTransform() = default;
236 ~StackTransform() override = default;
237
238 // Indices of the general fixed parameters into the FixedParameters array, and the number of those parameters.
239 enum
240 {
244 NumberOfGeneralFixedParametersOfStack
245 };
246
247 void
248 CreateSubTransforms(const FixedParametersType & fixedParametersOfSubTransform)
249 {
250 assert(Superclass::m_FixedParameters.size() >= NumberOfGeneralFixedParametersOfStack);
251 const auto numberOfSubTransforms = Superclass::m_FixedParameters[IndexOfNumberOfSubTransforms];
252
253 if (numberOfSubTransforms >= 0.0 && numberOfSubTransforms <= UINT_MAX &&
254 static_cast<double>(static_cast<unsigned>(numberOfSubTransforms)) == numberOfSubTransforms)
255 {
256 m_SubTransformContainer.resize(static_cast<unsigned>(numberOfSubTransforms));
257 }
258 else
259 {
260 itkExceptionMacro(<< "The FixedParameters element (" << numberOfSubTransforms
261 << ") should be a valid number (the number of subtransforms).");
262 }
263
264 for (auto & subTransform : m_SubTransformContainer)
265 {
266 subTransform = this->CreateSubTransform();
267 subTransform->SetFixedParameters(fixedParametersOfSubTransform);
268 }
269 }
270
271 void
273 {
274 assert(Superclass::m_FixedParameters.size() >= NumberOfGeneralFixedParametersOfStack);
275 m_StackSpacing = Superclass::m_FixedParameters[IndexOfStackSpacing];
276 m_StackOrigin = Superclass::m_FixedParameters[IndexOfStackOrigin];
277 }
278
279
282 virtual void
283 UpdateFixedParametersInternally(const FixedParametersType & fixedParametersOfSubTransform)
284 {
285 const auto numberOfFixedParametersOfSubTransform = fixedParametersOfSubTransform.size();
286
287 FixedParametersType & fixedParametersOfStack = this->Superclass::m_FixedParameters;
288
289 const auto minimumNumberOfFixedParametersOfStack =
290 NumberOfGeneralFixedParametersOfStack + numberOfFixedParametersOfSubTransform;
291
292 if (fixedParametersOfStack.size() < minimumNumberOfFixedParametersOfStack)
293 {
294 fixedParametersOfStack.set_size(minimumNumberOfFixedParametersOfStack);
295 }
296 fixedParametersOfStack[IndexOfNumberOfSubTransforms] = m_SubTransformContainer.size();
297 fixedParametersOfStack[IndexOfStackOrigin] = m_StackOrigin;
298 fixedParametersOfStack[IndexOfStackSpacing] = m_StackSpacing;
299 std::copy_n(fixedParametersOfSubTransform.begin(),
300 numberOfFixedParametersOfSubTransform,
301 fixedParametersOfStack.begin() + NumberOfGeneralFixedParametersOfStack);
302 }
303
304private:
308 virtual SubTransformPointer
310
311
312 static constexpr const char * unimplementedOverrideMessage = "Not implemented for StackTransform";
313
315 OutputVectorType
316 TransformVector(const InputVectorType &) const override
317 {
318 itkExceptionMacro(<< unimplementedOverrideMessage);
319 }
320
321 OutputVnlVectorType
322 TransformVector(const InputVnlVectorType &) const override
323 {
324 itkExceptionMacro(<< unimplementedOverrideMessage);
325 }
326
327 OutputCovariantVectorType
328 TransformCovariantVector(const InputCovariantVectorType &) const override
329 {
330 itkExceptionMacro(<< unimplementedOverrideMessage);
331 }
332
333
335 void
336 GetSpatialJacobian(const InputPointType &, SpatialJacobianType &) const override
337 {
338 itkExceptionMacro(<< unimplementedOverrideMessage);
339 }
340
341 void
342 GetSpatialHessian(const InputPointType &, SpatialHessianType &) const override
343 {
344 itkExceptionMacro(<< unimplementedOverrideMessage);
345 }
346
347 void
348 GetJacobianOfSpatialJacobian(const InputPointType &,
350 NonZeroJacobianIndicesType &) const override
351 {
352 itkExceptionMacro(<< unimplementedOverrideMessage);
353 }
354
355 void
356 GetJacobianOfSpatialJacobian(const InputPointType &,
359 NonZeroJacobianIndicesType &) const override
360 {
361 itkExceptionMacro(<< unimplementedOverrideMessage);
362 }
363
364 void
365 GetJacobianOfSpatialHessian(const InputPointType &,
367 NonZeroJacobianIndicesType &) const override
368 {
369 itkExceptionMacro(<< unimplementedOverrideMessage);
370 }
371
372
373 void
374 GetJacobianOfSpatialHessian(const InputPointType &,
377 NonZeroJacobianIndicesType &) const override
378 {
379 itkExceptionMacro(<< unimplementedOverrideMessage);
380 }
381
382
383 // Transform container
384 std::vector<SubTransformPointer> m_SubTransformContainer;
385
386 // Stack spacing and origin of last dimension
387 TScalarType m_StackSpacing{ 1.0 };
388 TScalarType m_StackOrigin{ 0.0 };
389};
390
391} // end namespace itk
392
393#ifndef ITK_MANUAL_INSTANTIATION
394# include "itkStackTransform.hxx"
395#endif
396
397#endif
Transform maps points, vectors and covariant vectors from an input space to an output space.
Matrix< ScalarType, OutputSpaceDimension, InputSpaceDimension > SpatialJacobianType
FixedArray< Matrix< ScalarType, InputSpaceDimension, InputSpaceDimension >, OutputSpaceDimension > SpatialHessianType
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
std::vector< SubTransformPointer > m_SubTransformContainer


Generated on Wed 12 Apr 2023 for elastix by doxygen 1.9.6 elastix logo