KWStyle - itkNonUniformBSpline.txx
 
Matrix View
Description

1 /*=========================================================================
2
3   Program:   Insight Segmentation & Registration Toolkit
4   Module:    $RCSfile: itkNonUniformBSpline.txx.html,v $
5   Language:  C++
6   Date:      $Date: 2006/01/17 19:15:42 $
7   Version:   $Revision: 1.4 $
8
9   Copyright (c) Insight Software Consortium. All rights reserved.
10   See ITKCopyright.txt or http://www.itk.org/HTML/Copyright.htm for details.
11
12      This software is distributed WITHOUT ANY WARRANTY; without even 
13      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR 
14      PURPOSE.  See the above copyright notices for more information.
15
16 DEF =========================================================================*/
17
18
19 #if defined(_MSC_VER)
20 #pragma warning ( disable : 4786 )
21 #endif
22
23 #ifndef __itkNonUniformBSpline_txx
24 #define __itkNonUniformBSpline_txx
25
26 #include "itkNonUniformBSpline.h" 
27
28 #include "vnl/vnl_vector.h"
29 #include "vnl/vnl_matrix.h"
30 #include "vnl/algo/vnl_matrix_inverse.h"
31
32
33 // #define DEBUG_SPLINE
34
35 namespace itk  
36
37
38
39 /** Constructor */
40 template< unsigned int TDimension >
41 NonUniformBSpline< TDimension > 
42 ::NonUniformBSpline()  
43
44   // Cubic bspline => 4th order
45   m_SplineOrder = 3;
46   m_SpatialDimension = TDimension;
47
48  
49 /** Destructor */
50 template< unsigned int TDimension >
51 NonUniformBSpline< TDimension >  
52 ::~NonUniformBSpline()
53
54 }  
55
56 /** Print the object */ 
57 template< unsigned int TDimension >
58 void  
59 NonUniformBSpline< TDimension >  
60 ::PrintSelf( std::ostream& os, Indent indent ) const 
61
62   Superclass::PrintSelf( os, indent ); 
63   os << indent << "NonUniformBSpline(" << this << ")" << std::endl; 
64
65   os << indent << "Chord lengths : " << std::endl;
66 LEN   for (ChordLengthListType::const_iterator iter = m_CumulativeChordLength.begin();
67         iter != m_CumulativeChordLength.end();
68         iter++)
69       {
70       os << indent << indent << *iter << std::endl;
71       }
72   os << indent << "Knots : " << std::endl;
73   for (KnotListType::const_iterator kiter = m_Knots.begin();
74         kiter != m_Knots.end();
75         kiter++)
76         {
77         os << indent << indent << *kiter << std::endl;
78         }
79   os << indent << "Control Points : " << std::endl;
80 LEN   for (typename ControlPointListType::const_iterator cpiter = m_ControlPoints.begin();
81         cpiter != m_ControlPoints.end();
82         cpiter++)
83        {
84        os << indent << indent << *cpiter << std::endl;
85        }
86
87
88
89 /** Set the list of points composing the tube */
90 template< unsigned int TDimension >
91 void  
92 NonUniformBSpline< TDimension >  
93 ::SetPoints( PointListType & points )  
94 {
95   m_Points.clear();
96          
97   typename PointListType::iterator it,end;
98   it = points.begin();    
99   end = points.end();
100   while(it != end)
101     {
102     m_Points.push_back(*it);
103     it++;
104     }
105       
106   this->Modified();
107 }
108
109 /** Set the list of points composing the tube */
110 template< unsigned int TDimension >
111 void  
112 NonUniformBSpline< TDimension >  
113 ::SetKnots( KnotListType & knots )  
114 {
115   m_Knots.clear();
116   
117   int len = knots.size();
118   double max_knot = knots[len - 1];
119          
120   typename KnotListType::iterator it;
121   typename KnotListType::iterator end;
122
123   it = knots.begin();    
124   end = knots.end();
125
126   while(it != end)
127     {
128     m_Knots.push_back(*it/max_knot);
129     it++;
130     }
131       
132   this->Modified();
133 }
134
135 template< unsigned int TDimension >
136 double  
137 NonUniformBSpline< TDimension > 
138 LEN ::NonUniformBSplineFunctionRecursive(unsigned int order, unsigned int i, double t) const
139 {
140   if (order == 1)
141     {
142     if (m_Knots[i] <= t && t < m_Knots[i+1])
143       {
144       return 1;
145       }
146     else
147       {
148       return 0;
149       }
150     }
151
152   //
153   // Be careful, we must use the passed in parameter for the order since this
154   // function is recursive.
155   //
156 LEN   double numer1 = (t - m_Knots[i]) * NonUniformBSplineFunctionRecursive(order-1, i, t);
157   double denom1 = (m_Knots[i+order-1] - m_Knots[i]);
158   double val1 = numer1 / denom1;
159   if (denom1 == 0 && numer1 == 0)
160     val1 = 0;
161   else if (denom1 == 0)
162     std::cout << "Error : " << denom1 << ", " << numer1 << std::endl;
163
164 LEN   double numer2 = (m_Knots[i+order] - t) * NonUniformBSplineFunctionRecursive(order-1, i+1, t);
165   double denom2 = (m_Knots[i + order] - m_Knots[i+1]);
166   double val2 = numer2 / denom2;
167   if (denom2 == 0 && numer2 == 0)
168     val2 = 0;
169   else if (denom2 == 0)
170     std::cout << "Error : " << denom2 << ", " << numer2 << std::endl;
171
172   return val1 + val2;
173 }
174
175 template< unsigned int TDimension >
176 void  
177 NonUniformBSpline< TDimension > 
178 ::ComputeChordLengths()
179 {
180   m_ChordLength.clear();
181   m_CumulativeChordLength.clear();
182
183   m_ChordLength.push_back(0);
184   m_CumulativeChordLength.push_back(0);
185
186   double total_chord_length = 0.0;
187   ChordLengthListType temp;
188
189   for (::size_t i = 0; i < m_Points.size()-1; i++)
190       {
191       PointType pt = m_Points[i];
192       PointType pt2 = m_Points[i+1];
193
194       double chord = pt.EuclideanDistanceTo(pt2);
195       m_ChordLength.push_back(chord);
196       total_chord_length = total_chord_length + chord;
197       temp.push_back(total_chord_length);
198       }
199
200   for (ChordLengthListType::iterator aiter = temp.begin();
201         aiter != temp.end();
202         aiter++)
203       {
204       m_CumulativeChordLength.push_back(*aiter/total_chord_length);
205       }
206
207   //
208   // Debug printouts
209   //
210 #ifdef DEBUG_SPLINE
211   std::cout << "Total chord length : " << total_chord_length << std::endl;
212
213   std::cout << "Chord length : " << std::endl;
214   for (ChordLengthListType::iterator aiter2 = m_ChordLength.begin();
215         aiter2 != m_ChordLength.end();
216         aiter2++)
217       {
218       std::cout << *aiter2 << std::endl;
219       }
220
221   std::cout << "Cumulative chord length : " << std::endl;
222   for (ChordLengthListType::iterator aiter3 = m_CumulativeChordLength.begin();
223         aiter3 != m_CumulativeChordLength.end();
224         aiter3++)
225       {
226       std::cout << *aiter3 << std::endl;
227       }
228   std::cout << std::endl;
229 #endif
230 }
231
232 template< unsigned int TDimension >
233 void  
234 NonUniformBSpline< TDimension > 
235 ::SetControlPoints( ControlPointListType& ctrlpts )
236 {
237 IND *m_ControlPoints.clear();
238 IND *for (typename ControlPointListType::iterator iter = ctrlpts.begin();
239 IND ********iter != ctrlpts.end();
240 IND ********iter++)
241 IND *****{
242 IND *****m_ControlPoints.push_back(*iter);   
243 IND *****} 
244 IND *this->Modified();
245 }
246
247 template< unsigned int TDimension >
248 void
249 NonUniformBSpline< TDimension >::ComputeControlPoints() 
250 {
251   unsigned int dim = m_Points[0].GetPointDimension();
252
253 #ifdef DEBUG_SPLINE
254   std::cout << "Points have dimension : " << dim  << std::endl;
255 #endif  
256
257   //
258   // +1 in cols for radius
259   // 
260   vnl_matrix<double> data_matrix(m_Points.size(), dim);
261
262   //
263   // Form data point matrix
264   //
265   int rr = 0;
266   for (typename PointListType::iterator iter = m_Points.begin();
267 IND ********iter != m_Points.end();
268 IND ********iter++)
269 IND ******{
270 IND ******PointType pt = (*iter);
271 IND ******for (int i = 0; i < dim; i++)
272         {
273         data_matrix(rr, i) = pt.GetVnlVector()[i];
274         }
275       rr++;
276       }
277
278 #ifdef DEBUG_SPLINE
279   std::cout << std::endl << "Data matrix" << std::endl;
280   std::cout << data_matrix << std::endl;
281 #endif
282
283   //
284   // Form basis function matrix
285   //
286   //int num_basis_functions = 2 * m_SplineOrder - 1;
287   //int num_basis_functions = m_Points.size();
288   int num_rows = m_Points.size();
289
290   //
291   // Assumes multiplicity k (m_SplineOrder at the ends).
292   //
293   int num_cols = m_Knots.size() - m_SplineOrder;
294
295   vnl_matrix<double> N_matrix(num_rows, num_cols);
296
297   //N_matrix(0, 0) = 1.0;
298
299   for (int r = 0; r < num_rows; r++)
300     {
301     for (int c = 0; c < num_cols; c++)
302       {
303       double t = m_CumulativeChordLength[r];
304       N_matrix(r, c) = NonUniformBSplineFunctionRecursive(m_SplineOrder, c, t);
305       }
306     }
307
308   N_matrix(num_rows-1, num_cols-1) = 1.0;
309
310 #ifdef DEBUG_SPLINE
311   std::cout << "Basis function matrix : " << std::endl;
312   std::cout << N_matrix << std::endl;
313 #endif
314
315 LEN   vnl_matrix<double> B = vnl_matrix_inverse<double>(N_matrix.transpose() * N_matrix) * N_matrix.transpose() * data_matrix;
316
317 IND //#ifdef DEBUG_SPLINE
318   std::cout << "Control point matrix : " << std::endl;
319   std::cout << B << std::endl;
320 //#endif
321
322   m_ControlPoints.clear();
323
324   int j = 0;
325   for (j = 0; j < B.rows(); j++)
326     {
327     vnl_vector<double> v = B.get_row(j);
328     itk::Vector<double> iv;
329     iv.SetVnlVector(v);
330     itk::Point<double, TDimension> pt;
331     for (int d = 0; d < dim; d++)
332       {
333       pt[d] = v(d);
334       }
335     m_ControlPoints.push_back(pt);
336     }
337   return;
338 }
339
340 template< unsigned int TDimension >
341 typename NonUniformBSpline<TDimension>::PointType
342 NonUniformBSpline< TDimension >
343 ::EvaluateSpline(const itk::Array<double> & p) const
344 {
345   double t = p[0];
346
347   return EvaluateSpline(t);
348 }
349
350 template< unsigned int TDimension >
351 typename NonUniformBSpline<TDimension>::PointType
352 NonUniformBSpline< TDimension >
353 ::EvaluateSpline(double t) const
354 {
355   double N = 0.0;
356
357   int i = 0;
358
359   vnl_vector<double> result(TDimension);
360   result.fill(0);
361
362 LEN   for (typename ControlPointListType::const_iterator cpiter = m_ControlPoints.begin();
363 IND ********cpiter != m_ControlPoints.end();
364 IND ********cpiter++)
365     {
366     ControlPointType pt = *cpiter;
367     vnl_vector<double> v = pt.GetVnlVector();
368
369     N =  this->NonUniformBSplineFunctionRecursive(m_SplineOrder, i, t);
370     result = result + N * v;
371
372     i++;
373     }
374
375   double array[TDimension];
376 SEM   for (int d = 0; d < TDimension ; d++)
377     {
378     array[d] = result[d];
379     }
380
381   ControlPointType sum(array);
382 #ifdef DEBUG_SPLINE
383   std::cout << "Result : " << result << std::endl;
384   std::cout << "Sum : " << sum << std::endl;
385 #endif
386   
387   return sum;
388 }
389
390 // end namespace itk 
391
392 #endif
393
394 EOF

Generated by KWStyle 1.0b on Tuesday January,17 at 02:14:27PM
© Kitware Inc.