File: itkBSplineScatteredDataPointSetToImageFilter.h

package info (click to toggle)
insighttoolkit 3.20.1%2Bgit20120521-3
  • links: PTS, VCS
  • area: main
  • in suites: wheezy
  • size: 80,652 kB
  • sloc: cpp: 458,133; ansic: 196,223; fortran: 28,000; python: 3,839; tcl: 1,811; sh: 1,184; java: 583; makefile: 430; csh: 220; perl: 193; xml: 20
file content (289 lines) | stat: -rw-r--r-- 11,923 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
/*=========================================================================

  Program:   Insight Segmentation & Registration Toolkit
  Module:    itkBSplineScatteredDataPointSetToImageFilter.h
  Language:  C++
  Date:      $Date$
  Version:   $Revision$

  Copyright (c) Insight Software Consortium. All rights reserved.
  See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notices for more information.

=========================================================================*/
#ifndef __itkBSplineScatteredDataPointSetToImageFilter_h
#define __itkBSplineScatteredDataPointSetToImageFilter_h

#include "itkPointSetToImageFilter.h"
#include "itkBSplineKernelFunction.h"
#include "itkCoxDeBoorBSplineKernelFunction.h"
#include "itkFixedArray.h"
#include "itkVariableSizeMatrix.h"
#include "itkVector.h"
#include "itkVectorContainer.h"

#include "vnl/vnl_matrix.h"

namespace itk
{

/** \class BSplineScatteredDataPointSetToImageFilter
 * \brief Image filter which provides a B-spline output approximation.
 *
 * Given an n-D image with scattered data, this filter finds
 * a fast approximation to that irregularly spaced data using uniform
 * B-splines.  The traditional method of inverting the observation
 * matrix to find a least-squares fit is made obsolete.  Therefore,
 * memory issues are not a concern and inverting large matrices is
 * not applicable.  In addition, this allows fitting to be multi-threaded.
 * This class generalizes from Lee's original paper to encompass
 * n-D data in m-D parametric space and any *feasible* B-spline order as well
 * as the option of specifying a confidence value for each point.
 *
 * In addition to specifying the input point set, one must specify the number
 * of control points.  The specified number of control points must be
 * > m_SplineOrder.  If one wishes to use the multilevel component of
 * this algorithm, one must also specify the number of levels in the
 * hierarchy.  If this is desired, the number of control points becomes
 * the number of control points for the coarsest level.  The algorithm
 * then increases the number of control points at each level so that
 * the B-spline n-D grid is refined to twice the previous level.
 *
 * \author Nicholas J. Tustison
 *
 * Contributed by Nicholas J. Tustison, James C. Gee
 * in the Insight Journal paper:
 * http://hdl.handle.net/1926/140
 *
 * \par REFERENCE
 * S. Lee, G. Wolberg, and S. Y. Shin, "Scattered Data Interpolation
 * with Multilevel B-Splines", IEEE Transactions on Visualization and
 * Computer Graphics, 3(3):228-244, 1997.
 *
 * \par REFERENCE
 * N.J. Tustison and J.C. Gee, "Generalized n-D C^k Scattered Data Approximation
 * with COnfidence Values", Proceedings of the MIAR conference, August 2006.
 */

template <class TInputPointSet, class TOutputImage>
class BSplineScatteredDataPointSetToImageFilter
: public PointSetToImageFilter<TInputPointSet, TOutputImage>
{
public:
  typedef BSplineScatteredDataPointSetToImageFilter  Self;
  typedef PointSetToImageFilter
    <TInputPointSet, TOutputImage>                   Superclass;
  typedef SmartPointer<Self>                         Pointer;
  typedef SmartPointer<const Self>                   ConstPointer;

  /** Method for creation through the object factory. */
  itkNewMacro(Self);

  /** Extract dimension from input and output image. */
  itkStaticConstMacro( ImageDimension, unsigned int,
    TOutputImage::ImageDimension );

  typedef TOutputImage                               ImageType;
  typedef TInputPointSet                             PointSetType;

  /** Image typedef support. */
  typedef typename ImageType::PixelType              PixelType;
  typedef typename ImageType::RegionType             RegionType;
  typedef typename ImageType::SizeType               SizeType;
  typedef typename ImageType::IndexType              IndexType;
  typedef typename ImageType::PointType              ContinuousIndexType;

  /** PointSet typedef support. */
  typedef typename PointSetType::PointType           PointType;
  typedef typename PointSetType::PixelType           PointDataType;
  typedef typename PointSetType::PointDataContainer  PointDataContainerType;

  /** Other typedef */
  typedef float                                      RealType;
  typedef VectorContainer<unsigned, RealType>        WeightsContainerType;
  typedef Image<PointDataType,
    itkGetStaticConstMacro( ImageDimension )>        PointDataImageType;
  typedef typename PointDataImageType::Pointer       PointDataImagePointer;
  typedef Image<RealType,
    itkGetStaticConstMacro( ImageDimension )>        RealImageType;
  typedef typename RealImageType::Pointer            RealImagePointer;
  typedef FixedArray<unsigned,
    itkGetStaticConstMacro( ImageDimension )>        ArrayType;
  typedef VariableSizeMatrix<RealType>               GradientType;

  /**
   * Interpolation kernel type (default spline order = 3)
   */
  typedef CoxDeBoorBSplineKernelFunction<3>          KernelType;
  typedef BSplineKernelFunction<0>                   KernelOrder0Type;
  typedef BSplineKernelFunction<1>                   KernelOrder1Type;
  typedef BSplineKernelFunction<2>                   KernelOrder2Type;
  typedef BSplineKernelFunction<3>                   KernelOrder3Type;

  /** Helper functions */

  void SetNumberOfLevels( unsigned int );
  void SetNumberOfLevels( ArrayType );
  itkGetConstReferenceMacro( NumberOfLevels, ArrayType );

  void SetSplineOrder( unsigned int );
  void SetSplineOrder( ArrayType );
  itkGetConstReferenceMacro( SplineOrder, ArrayType );

  itkSetMacro( NumberOfControlPoints, ArrayType );
  itkGetConstReferenceMacro( NumberOfControlPoints, ArrayType );
  itkGetConstReferenceMacro( CurrentNumberOfControlPoints, ArrayType );

  /** This array of 0/1 values defines whether a particular dimension of the
   * parametric space is to be considered periodic or not. For example, if you
   * are using interpolating along a 1D closed curve, the array type will have
   * size 1, and you should set the first element of this array to the value
   * "1". In the case that you were interpolating in a planar surface with
   * cylindrical topology, the array type will have two components, and you
   * should set to "1" the component that goes around the cylinder, and set to
   * "0" the component that goes from the top of the cylinder to the bottom.
   * This will indicate the periodity of that parameter to the filter.
   * Internally, in order to make periodic the domain of the parameter, the
   * filter will reuse some of the points at the beginning of the domain as if
   * they were also located at the end of the domain. The number of points to
   * be reused will depend on the spline order. As a user, you don't need to
   * replicate the points, the filter will do this for you. */
  itkSetMacro( CloseDimension, ArrayType );
  itkGetConstReferenceMacro( CloseDimension, ArrayType );

  itkSetMacro( GenerateOutputImage, bool );
  itkGetConstReferenceMacro( GenerateOutputImage, bool );
  itkBooleanMacro( GenerateOutputImage );

  void SetPointWeights( WeightsContainerType * weights );

  /**
   * Get the control point lattice.
   */
  itkSetMacro( PhiLattice, PointDataImagePointer );
  itkGetConstMacro( PhiLattice, PointDataImagePointer );

  /**
   * Evaluate the resulting B-spline object at a specified
   * point or index within the image domain.
   */
  void EvaluateAtPoint( PointType, PointDataType & );
  void EvaluateAtIndex( IndexType, PointDataType & );
  void EvaluateAtContinuousIndex( ContinuousIndexType, PointDataType & );

  /**
   * Evaluate the resulting B-spline object at a specified
   * parametric point.  Note that the parameterization over
   * each dimension of the B-spline object is [0, 1].
   */
  void Evaluate( PointType, PointDataType & );

  /**
   * Evaluate the gradient of the resulting B-spline object at a specified
   * point or index within the image domain.
   */
  void EvaluateGradientAtPoint( PointType, GradientType & );
  void EvaluateGradientAtIndex( IndexType, GradientType & );
  void EvaluateGradientAtContinuousIndex( ContinuousIndexType, GradientType & );

  /**
   * Evaluate the gradient of the resulting B-spline object
   * at a specified parametric point.  Note that the
   * parameterization over each dimension of the B-spline
   * object is [0, 1].
   */
  void EvaluateGradient( PointType, GradientType & );

protected:
  BSplineScatteredDataPointSetToImageFilter();
  virtual ~BSplineScatteredDataPointSetToImageFilter();
  void PrintSelf( std::ostream& os, Indent indent ) const;

  /** Multithreaded function which generates the control point lattice. */
  void ThreadedGenerateData( const RegionType&, int );
  void BeforeThreadedGenerateData();
  void AfterThreadedGenerateData();

  /** Only the points are divided among the threads, so always return
   * a valid number */
  int SplitRequestedRegion(int, int, RegionType&)
    {
    return this->GetNumberOfThreads();
    }

  void GenerateData();

private:

  //purposely not implemented
  BSplineScatteredDataPointSetToImageFilter(const Self&);
  void operator=(const Self&);

  void RefineControlPointLattice();
  void UpdatePointSet();
  void GenerateOutputImage();
  void GenerateOutputImageFast();
  void CollapsePhiLattice( PointDataImageType *, PointDataImageType *,
    RealType, unsigned int );

  bool                                           m_DoMultilevel;
  bool                                           m_GenerateOutputImage;
  bool                                           m_UsePointWeights;
  unsigned int                                   m_MaximumNumberOfLevels;
  unsigned int                                   m_CurrentLevel;
  ArrayType                                      m_NumberOfControlPoints;
  ArrayType                                      m_CurrentNumberOfControlPoints;
  ArrayType                                      m_CloseDimension;
  ArrayType                                      m_SplineOrder;
  ArrayType                                      m_NumberOfLevels;
  typename WeightsContainerType::Pointer         m_PointWeights;
  typename PointDataImageType::Pointer           m_PhiLattice;
  typename PointDataImageType::Pointer           m_PsiLattice;
  typename PointDataContainerType::Pointer       m_InputPointData;
  typename PointDataContainerType::Pointer       m_OutputPointData;

  typename KernelType::Pointer                   m_Kernel[ImageDimension];
  typename KernelOrder0Type::Pointer             m_KernelOrder0;
  typename KernelOrder1Type::Pointer             m_KernelOrder1;
  typename KernelOrder2Type::Pointer             m_KernelOrder2;
  typename KernelOrder3Type::Pointer             m_KernelOrder3;

  std::vector<RealImagePointer>                  m_OmegaLatticePerThread;
  std::vector<PointDataImagePointer>             m_DeltaLatticePerThread;

  RealType                                       m_BSplineEpsilon;

  vnl_matrix<RealType>
    m_RefinedLatticeCoefficients[ImageDimension];

  inline typename RealImageType::IndexType
  NumberToIndex( unsigned int number, typename RealImageType::SizeType size )
    {
    typename RealImageType::IndexType k;
    k[0] = 1;

    for ( unsigned int i = 1; i < ImageDimension; i++ )
      {
      k[i] = size[ImageDimension-i-1]*k[i-1];
      }
    typename RealImageType::IndexType index;
    for ( unsigned int i = 0; i < ImageDimension; i++ )
      {
      index[ImageDimension-i-1]
        = static_cast<unsigned int>( number/k[ImageDimension-i-1] );
      number %= k[ImageDimension-i-1];
      }
    return index;
    }
};

} // end namespace itk

#ifndef ITK_MANUAL_INSTANTIATION
#include "itkBSplineScatteredDataPointSetToImageFilter.txx"
#endif

#endif