Seg3D  2.4
Seg3D is a free volume segmentation and processing tool developed by the NIH Center for Integrative Biomedical Computing at the University of Utah Scientific Computing and Imaging (SCI) Institute.
itkCascadedTransform.h
1 /*
2  For more information, please see: http://software.sci.utah.edu
3 
4  The MIT License
5 
6  Copyright (c) 2016 Scientific Computing and Imaging Institute,
7  University of Utah.
8 
9 
10  Permission is hereby granted, free of charge, to any person obtaining a
11  copy of this software and associated documentation files (the "Software"),
12  to deal in the Software without restriction, including without limitation
13  the rights to use, copy, modify, merge, publish, distribute, sublicense,
14  and/or sell copies of the Software, and to permit persons to whom the
15  Software is furnished to do so, subject to the following conditions:
16 
17  The above copyright notice and this permission notice shall be included
18  in all copies or substantial portions of the Software.
19 
20  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
21  OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22  FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
23  THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24  LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
26  DEALINGS IN THE SOFTWARE.
27 */
28 
29 // File : itkCascadedTransform.h
30 // Author : Pavel A. Koshevoy
31 // Created : 2005/06/03 10:16
32 // Copyright : (C) 2004-2008 University of Utah
33 // Description : A composite transform used to chain several conventional
34 // ITK transforms together.
35 
36 #ifndef __itkCascadedTransform_h
37 #define __itkCascadedTransform_h
38 
39 // system includes:
40 #include <iostream>
41 #include <cassert>
42 #include <vector>
43 #include <sstream>
44 
45 // ITK includes:
46 #include <itkTransform.h>
47 #include <itkMacro.h>
48 
49 #include <Core/Utils/Log.h>
50 
51 
52 //----------------------------------------------------------------
53 // itk::CascadedTransform
54 //
55 namespace itk
56 {
57 
58 template <class TScalar, unsigned int Dimension>
60 public ITK_EXPORT Transform<TScalar, Dimension, Dimension>
61 {
62 public:
63  // standard typedefs:
64  typedef CascadedTransform Self;
65  typedef Transform<TScalar, Dimension, Dimension> Superclass;
66  typedef SmartPointer<Self> Pointer;
67  typedef SmartPointer<const Self> ConstPointer;
68 
69 
72  typedef typename Superclass::InverseTransformBaseType InverseTransformBaseType;
73  typedef typename InverseTransformBaseType::Pointer InverseTransformBasePointer;
74 
75  typedef SmartPointer<Superclass> TransformPointer;
76  typedef SmartPointer<const Superclass> ConstTransformPointer;
77 
78  // RTTI:
79  itkTypeMacro(CascadedTransform, Transform);
80 
81  // macro for instantiation through the object factory:
82  itkNewMacro(Self);
83 
85  typedef typename Superclass::ScalarType ScalarType;
86 
88  itkStaticConstMacro(InputSpaceDimension, unsigned int, Dimension);
89  itkStaticConstMacro(OutputSpaceDimension, unsigned int, Dimension);
90 
91  // shortcuts:
92  typedef typename Superclass::ParametersType ParametersType;
93  typedef typename Superclass::JacobianType JacobianType;
94 
95  typedef typename Superclass::InputPointType PointType;
96  typedef PointType InputPointType;
97  typedef PointType OutputPointType;
98 
99  typedef typename Superclass::InputVectorType VectorType;
100  typedef VectorType InputVectorType;
101  typedef VectorType OutputVectorType;
102 
103  typedef typename Superclass::InputVnlVectorType VnlVectorType;
104  typedef VnlVectorType InputVnlVectorType;
105  typedef VnlVectorType OutputVnlVectorType;
106 
107  typedef typename Superclass::InputCovariantVectorType CovariantVectorType;
108  typedef CovariantVectorType InputCovariantVectorType;
109  typedef CovariantVectorType OutputCovariantVectorType;
110 
112  typedef typename Superclass::NumberOfParametersType NumberOfParametersType;
113 
114  // virtual:
115  virtual PointType TransformPoint(const PointType & x) const
116  {
117  PointType y = x;
118 
119  // apply the transforms:
120  for (unsigned int i = active_start_; i <= active_finish_; i++)
121  {
122  PointType tx = transform_[i]->TransformPoint(y);
123  if (tx[0] == std::numeric_limits<double>::max())
124  {
125  return tx;
126  }
127 
128  y = tx;
129  }
130 
131  return y;
132  }
133 
134  // virtual:
135  virtual VectorType TransformVector(const VectorType & x) const
136  {
137  VectorType y(x);
138 
139  // apply the transforms:
140  for (unsigned int i = active_start_; i <= active_finish_; i++)
141  {
142  y = transform_[i]->TransformVector(y);
143  }
144 
145  return y;
146  }
147 
148  // virtual:
149  virtual VnlVectorType TransformVector(const VnlVectorType & x) const
150  {
151  VnlVectorType y(x);
152 
153  // apply the transforms:
154  for (unsigned int i = active_start_; i <= active_finish_; i++)
155  {
156  y = transform_[i]->TransformVector(y);
157  }
158 
159  return y;
160  }
161 
162  // virtual:
163  virtual CovariantVectorType
164  TransformCovariantVector(const CovariantVectorType & x) const
165  {
166  CovariantVectorType y(x);
167 
168  // apply the transforms:
169  for (unsigned int i = active_start_; i < active_finish_; i++)
170  {
171  y = transform_[i]->TransformCovariantVector(y);
172  }
173 
174  return y;
175  }
176 
177  // Inverse transformations:
178  // If y = Transform(x), then x = BackTransform(y);
179  // if no mapping from y to x exists, then an exception is thrown
180  bool GetInverse(Self* inverse) const
181  {
182  if (! inverse) return false;
183 
184  const unsigned int cascade_length = transform_.size();
185 
186 // Pointer inv = Self::New();
187  inverse->transform_.resize(cascade_length);
188 
189  for (unsigned int i = 0; i < cascade_length; i++)
190  {
191  unsigned int idx = (cascade_length - 1) - i;
192 // inverse->transform_[i] = transform_[idx]->GetInverseTransform();
193  TransformPointer inverseTransform =
194  dynamic_cast<Superclass*>( transform_[idx]->GetInverseTransform().GetPointer() );
195  if (inverseTransform)
196  {
197  inverse->transform_[i] = inverseTransform;
198  }
199  else
200  {
201  std::ostringstream oss;
202  oss << "Could not convert inverse tranform obtained from transform "
203  << i << " from itkTransformBase to itkTransform. Skipping transform.";
204  CORE_LOG_DEBUG(oss.str());
205  }
206  }
207 
208  inverse->active_start_ = active_start_;
209  inverse->active_finish_ = active_finish_;
210  inverse->active_params_ = (cascade_length - 1) - active_params_;
211 
212 // InverseTransformPointer tmp = inverse.GetPointer();
213 // return tmp;
214  return true;
215  }
216 
217  virtual InverseTransformBasePointer GetInverseTransform() const
218  {
219  Pointer inv = Self::New();
220  return this->GetInverse(inv) ? inv.GetPointer() : 0;
221  }
222 
223  // virtual:
224  virtual void SetParameters(const ParametersType & params)
225  { transform_[active_params_]->SetParameters(params); }
226 
227  virtual void SetFixedParameters(const ParametersType &)
228  {
229  itkExceptionMacro(<< "SetFixedParameters is not implemented for CascadedTransform");
230  }
231 
232  // virtual:
233  virtual const ParametersType & GetParameters() const
234  { return transform_[active_params_]->GetParameters(); }
235 
236  // virtual:
237  virtual NumberOfParametersType GetNumberOfParameters() const
238  { return transform_[active_params_]->GetNumberOfParameters(); }
239 
240  // virtual:
241  virtual const JacobianType & GetJacobian(const PointType & pt) const
242  { return transform_[active_params_]->GetJacobian(pt); }
243 
244  // add a transform to the stack:
245  void append(TransformPointer transform)
246  {
247  const unsigned int old_sz = transform_.size();
248  std::vector<TransformPointer> new_array(old_sz + 1);
249 
250  for (unsigned int i = 0; i < old_sz; i++)
251  {
252  new_array[i] = transform_[i];
253  }
254 
255  new_array[old_sz] = transform;
256  transform_ = new_array;
257  active_params_ = transform_.size() - 1;
258  active_finish_ = transform_.size() - 1;
259  }
260 
261  // setup a cascaded transform:
262  template <typename container_t>
263  void setup(const container_t & transforms,
264  const unsigned int & cascade_length)
265  {
266  transform_.resize(cascade_length);
267 
268  for (unsigned int i = 0; i < cascade_length; i++)
269  {
270  transform_[i] = transforms[i];
271  }
272 
273  active_start_ = 0;
274  active_finish_ = cascade_length - 1;
275  active_params_ = active_finish_;
276  }
277 
278  // accessor to the individual transforms on the stack:
279  template <class transform_t> transform_t *
280  GetTransform(const unsigned int & index) const
281  { return dynamic_cast<transform_t *>(transform_[index].GetPointer()); }
282 
283  // accessor:
284  inline const std::vector<TransformPointer> & GetTransforms() const
285  { return transform_; }
286 
287  // accessors:
288  inline unsigned int GetParamsIndex() const
289  { return active_params_; }
290 
291  inline void SetParamsIndex(const unsigned int & index)
292  {
293 // assert(index < transform_.size());
294  if (index >= transform_.size())
295  {
296  itkExceptionMacro(<< "parameter index out of bounds");
297  }
298  active_params_ = index;
299 // assert(active_params_ <= active_finish_);
300  if (active_params_ > active_finish_)
301  {
302  itkExceptionMacro(<< "active parameter index out of bounds");
303  }
304  }
305 
306  inline unsigned int GetActiveIndex() const
307  { return active_finish_; }
308 
309  inline void SetActiveIndex(const unsigned int & index)
310  {
311 // assert(index < transform_.size());
312  if (index >= transform_.size())
313  {
314  itkExceptionMacro(<< "parameter index out of bounds");
315  }
316  active_finish_ = index;
317  active_params_ = index;
318  }
319 
320 protected:
321  CascadedTransform():
322  Superclass(/*Dimension,*/0),
323  transform_(0),
324  active_params_(~0),
325  active_start_(0),
326  active_finish_(~0)
327  {}
328 
329  // virtual:
330  virtual void PrintSelf(std::ostream & os, Indent indent) const
331  {
332  Superclass::PrintSelf(os, indent);
333 
334  const unsigned int sz = transform_.size();
335  for (unsigned int i = 0; i < sz; i++)
336  {
337  os << indent << "transform_[" << i << "] = "
338  << transform_[i] << std::endl;
339  }
340 
341  os << indent << "active_params_ = " << active_params_ << std::endl
342  << indent << "active_start_ = " << active_start_ << std::endl
343  << indent << "active_finish_ = " << active_finish_ << std::endl;
344  }
345 
346 private:
347  // disable default copy constructor and assignment operator:
348  CascadedTransform(const Self & other);
349  const Self & operator = (const Self & t);
350 
351  // Cascaded transforms - input is first transformed by the first
352  // transform, followed by the other transforms sequentially.
353  // Only the top-most (last) transform in the array is accessible
354  // for modification, all preciding transforms are fixed.
355  std::vector<TransformPointer> transform_;
356 
357  // This index controls which transform on the stack can be manipulated
358  // via GetParameters/SetParameters function. By default this is
359  // the top transform on the stack, but it may be adjusted to suit
360  // anyones needs:
361  unsigned int active_params_;
362 
363  // Transforms which are outside of the [start, finish] range are
364  // completely ignored. This feature is useful whenever it is necessary
365  // to temporarily remove some of the transforms from the cascade:
366  unsigned int active_start_;
367  unsigned int active_finish_;
368 
369 }; // class CascadedTransform
370 
371 } // namespace itk
372 
373 #endif // __itkCascadedTransform_h
Definition: itkNormalizeImageFilterWithMask.h:48
Superclass::ScalarType ScalarType
Definition: itkCascadedTransform.h:85
Superclass::NumberOfParametersType NumberOfParametersType
Definition: itkCascadedTransform.h:112
Superclass::InverseTransformBaseType InverseTransformBaseType
Definition: itkCascadedTransform.h:72
Definition: itkCascadedTransform.h:59
itkStaticConstMacro(InputSpaceDimension, unsigned int, Dimension)