Orfeo Toolbox  3.16
itkBSplineScatteredDataPointSetToImageFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Insight Segmentation & Registration Toolkit
4  Module: $RCSfile: itkBSplineScatteredDataPointSetToImageFilter.txx,v $
5  Language: C++
6  Date: $Date: 2009-10-02 12:36:37 $
7  Version: $Revision: 1.20 $
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 =========================================================================*/
17 
18 #ifndef __itkBSplineScatteredDataPointSetToImageFilter_txx
19 #define __itkBSplineScatteredDataPointSetToImageFilter_txx
20 
23 #include "itkImageRegionIterator.h"
25 #include "itkImageDuplicator.h"
26 #include "itkCastImageFilter.h"
27 #include "itkNumericTraits.h"
28 
29 #include "vnl/vnl_math.h"
30 #include "vnl/algo/vnl_matrix_inverse.h"
31 #include "vnl/vnl_vector.h"
32 #include "vcl_limits.h"
33 
34 namespace itk
35 {
44 template <class TInputPointSet, class TOutputImage>
47 {
48  this->m_SplineOrder.Fill( 3 );
49  for( unsigned int i = 0; i < ImageDimension; i++ )
50  {
51  this->m_NumberOfControlPoints[i] = ( this->m_SplineOrder[i] + 1 );
52  this->m_Kernel[i] = KernelType::New();
53  this->m_Kernel[i]->SetSplineOrder( this->m_SplineOrder[i] );
54  }
55  this->m_KernelOrder0 = KernelOrder0Type::New();
56  this->m_KernelOrder1 = KernelOrder1Type::New();
57  this->m_KernelOrder2 = KernelOrder2Type::New();
58  this->m_KernelOrder3 = KernelOrder3Type::New();
59 
60  this->m_CloseDimension.Fill( 0 );
61  this->m_DoMultilevel = false;
62  this->m_GenerateOutputImage = true;
63  this->m_NumberOfLevels.Fill( 1 );
64  this->m_MaximumNumberOfLevels = 1;
65 
66  this->m_PhiLattice = NULL;
67  this->m_PsiLattice = PointDataImageType::New();
68  this->m_InputPointData = PointDataContainerType::New();
69  this->m_OutputPointData = PointDataContainerType::New();
70 
71  this->m_PointWeights = WeightsContainerType::New();
72  this->m_UsePointWeights = false;
73 
74  this->m_BSplineEpsilon = vcl_numeric_limits<RealType>::epsilon();
75 }
76 
77 template <class TInputPointSet, class TOutputImage>
80 {
81 }
82 
83 template <class TInputPointSet, class TOutputImage>
84 void
86 ::SetSplineOrder( unsigned int order )
87 {
88  this->m_SplineOrder.Fill( order );
89  this->SetSplineOrder( this->m_SplineOrder );
90 }
91 
92 template <class TInputPointSet, class TOutputImage>
93 void
96 {
97  itkDebugMacro( "Setting m_SplineOrder to " << order );
98 
99  this->m_SplineOrder = order;
100  for( int i = 0; i < ImageDimension; i++ )
101  {
102  if( this->m_SplineOrder[i] == 0 )
103  {
104  itkExceptionMacro(
105  "The spline order in each dimension must be greater than 0" );
106  }
107 
108  this->m_Kernel[i] = KernelType::New();
109  this->m_Kernel[i]->SetSplineOrder( this->m_SplineOrder[i] );
110 
111  if( this->m_DoMultilevel )
112  {
113  typename KernelType::MatrixType C;
114  C = this->m_Kernel[i]->GetShapeFunctionsInZeroToOneInterval();
115 
116  vnl_matrix<RealType> R;
117  vnl_matrix<RealType> S;
118  R.set_size( C.rows(), C.cols() );
119  S.set_size( C.rows(), C.cols() );
120  for( unsigned int j = 0; j < C.rows(); j++ )
121  {
122  for( unsigned int k = 0; k < C.cols(); k++ )
123  {
124  R(j, k) = S(j, k) = static_cast<RealType>( C(j, k) );
125  }
126  }
127  for( unsigned int j = 0; j < C.cols(); j++ )
128  {
129  RealType c = vcl_pow( static_cast<RealType>( 2.0 ),
130  static_cast<RealType>( C.cols() )-j-1 );
131  for( unsigned int k = 0; k < C.rows(); k++)
132  {
133  R(k, j) *= c;
134  }
135  }
136  R = R.transpose();
137  R.flipud();
138  S = S.transpose();
139  S.flipud();
140 
141  this->m_RefinedLatticeCoefficients[i]
142  = ( vnl_svd<RealType>( R ).solve( S ) ).extract( 2, S.cols() );
143  }
144  }
145  this->Modified();
146 }
147 
148 template <class TInputPointSet, class TOutputImage>
149 void
151 ::SetNumberOfLevels( unsigned int levels )
152 {
153  this->m_NumberOfLevels.Fill( levels );
154  this->SetNumberOfLevels( this->m_NumberOfLevels );
155 }
156 
157 template <class TInputPointSet, class TOutputImage>
158 void
161 {
162  this->m_NumberOfLevels = levels;
163  this->m_MaximumNumberOfLevels = 1;
164  for( unsigned int i = 0; i < ImageDimension; i++ )
165  {
166  if( this->m_NumberOfLevels[i] == 0 )
167  {
168  itkExceptionMacro(
169  "The number of levels in each dimension must be greater than 0" );
170  }
171  if( this->m_NumberOfLevels[i] > this->m_MaximumNumberOfLevels )
172  {
173  this->m_MaximumNumberOfLevels = this->m_NumberOfLevels[i];
174  }
175  }
176 
177  itkDebugMacro( "Setting m_NumberOfLevels to " <<
178  this->m_NumberOfLevels );
179  itkDebugMacro( "Setting m_MaximumNumberOfLevels to " <<
180  this->m_MaximumNumberOfLevels );
181 
182  if( this->m_MaximumNumberOfLevels > 1 )
183  {
184  this->m_DoMultilevel = true;
185  }
186  else
187  {
188  this->m_DoMultilevel = false;
189  }
190  this->SetSplineOrder( this->m_SplineOrder );
191  this->Modified();
192 }
193 
194 template <class TInputPointSet, class TOutputImage>
195 void
198 {
199  this->m_UsePointWeights = true;
200  this->m_PointWeights = weights;
201  this->Modified();
202 }
203 
204 template <class TInputPointSet, class TOutputImage>
205 void
208 {
212  itkDebugMacro( "Size: " << this->m_Size );
213  itkDebugMacro( "Origin: " << this->m_Origin );
214  itkDebugMacro( "Spacing: " << this->m_Spacing );
215  itkDebugMacro( "Direction: " << this->m_Direction );
216  for( unsigned int i = 0; i < ImageDimension; i++)
217  {
218  if( this->m_Size[i] == 0 )
219  {
220  itkExceptionMacro( "Size must be specified." );
221  }
222  }
223 
224  this->GetOutput()->SetOrigin( this->m_Origin );
225  this->GetOutput()->SetSpacing( this->m_Spacing );
226  this->GetOutput()->SetDirection( this->m_Direction );
227  this->GetOutput()->SetRegions( this->m_Size );
228  this->GetOutput()->Allocate();
229 
233  if( this->m_UsePointWeights &&
234  ( this->m_PointWeights->Size() != this->GetInput()->GetNumberOfPoints() ) )
235  {
236  itkExceptionMacro(
237  "The number of weight points and input points must be equal." );
238  }
239 
240  for( unsigned int i = 0; i < ImageDimension; i++ )
241  {
242  if( this->m_NumberOfControlPoints[i] < this->m_SplineOrder[i] + 1 )
243  {
244  itkExceptionMacro(
245  "The number of control points must be greater than the spline order." );
246  }
247  }
248 
252  unsigned int maximumNumberOfSpans = 0;
253  for( unsigned int d = 0; d < ImageDimension; d++ )
254  {
255  unsigned int numberOfSpans = this->m_NumberOfControlPoints[d]
256  - this->m_SplineOrder[d];
257  numberOfSpans <<= ( this->m_NumberOfLevels[d] - 1 );
258  if( numberOfSpans > maximumNumberOfSpans )
259  {
260  maximumNumberOfSpans = numberOfSpans;
261  }
262  }
263  this->m_BSplineEpsilon = 10.0 * vcl_numeric_limits<RealType>::epsilon();
264  while( static_cast<RealType>( maximumNumberOfSpans ) ==
265  static_cast<RealType>( maximumNumberOfSpans ) - this->m_BSplineEpsilon )
266  {
267  this->m_BSplineEpsilon *= 10.0;
268  }
269 
270  this->m_InputPointData->Initialize();
271  this->m_OutputPointData->Initialize();
272  if( this->GetInput()->GetNumberOfPoints() > 0 )
273  {
274  typename PointSetType::PointDataContainer::ConstIterator It;
275  It = this->GetInput()->GetPointData()->Begin();
276  while( It != this->GetInput()->GetPointData()->End() )
277  {
278  if( !this->m_UsePointWeights )
279  {
280  this->m_PointWeights->InsertElement( It.Index(), 1.0 );
281  }
282  this->m_InputPointData->InsertElement( It.Index(), It.Value() );
283  this->m_OutputPointData->InsertElement( It.Index(), It.Value() );
284  ++It;
285  }
286  }
287 
288  this->m_CurrentLevel = 0;
289  this->m_CurrentNumberOfControlPoints = this->m_NumberOfControlPoints;
290 
296  str1.Filter = this;
297 
298  this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfThreads() );
299  this->GetMultiThreader()->SetSingleMethod( this->ThreaderCallback, &str1 );
300 
304  this->BeforeThreadedGenerateData();
305  this->GetMultiThreader()->SingleMethodExecute();
306  this->AfterThreadedGenerateData();
307 
308  this->UpdatePointSet();
309 
310  if( this->m_DoMultilevel )
311  {
312  this->m_PsiLattice->SetRegions(
313  this->m_PhiLattice->GetLargestPossibleRegion() );
314  this->m_PsiLattice->Allocate();
315  PointDataType P( 0.0 );
316  this->m_PsiLattice->FillBuffer( P );
317  }
318 
319  for( this->m_CurrentLevel = 1;
320  this->m_CurrentLevel < this->m_MaximumNumberOfLevels;
321  this->m_CurrentLevel++ )
322  {
323 
324  ImageRegionIterator<PointDataImageType> ItPsi( this->m_PsiLattice,
325  this->m_PsiLattice->GetLargestPossibleRegion() );
326  ImageRegionIterator<PointDataImageType> ItPhi( this->m_PhiLattice,
327  this->m_PhiLattice->GetLargestPossibleRegion() );
328  for( ItPsi.GoToBegin(), ItPhi.GoToBegin();
329  !ItPsi.IsAtEnd(); ++ItPsi, ++ItPhi )
330  {
331  ItPsi.Set( ItPhi.Get() + ItPsi.Get() );
332  }
333  this->RefineControlPointLattice();
334 
335  for( unsigned int i = 0; i < ImageDimension; i++ )
336  {
337  if( this->m_CurrentLevel < this->m_NumberOfLevels[i] )
338  {
339  this->m_CurrentNumberOfControlPoints[i] =
340  2*this->m_CurrentNumberOfControlPoints[i]-this->m_SplineOrder[i];
341  }
342  }
343 
344  itkDebugMacro( "Current Level = " << this->m_CurrentLevel );
345  itkDebugMacro( " Current number of control points = "
346  << this->m_CurrentNumberOfControlPoints );
347 
348  RealType avg_p = 0.0;
349  RealType totalWeight = 0.0;
350 
351  typename PointDataContainerType::Iterator ItIn
352  = this->m_InputPointData->Begin();
353  typename PointDataContainerType::Iterator ItOut
354  = this->m_OutputPointData->Begin();
355  while( ItIn != this->m_InputPointData->End() )
356  {
357  this->m_InputPointData->InsertElement(
358  ItIn.Index(), ItIn.Value() - ItOut.Value() );
359 
360  if( this->GetDebug() )
361  {
362  RealType weight = this->m_PointWeights->GetElement( ItIn.Index() );
363  avg_p += ( ItIn.Value() - ItOut.Value() ).GetNorm() * weight;
364  totalWeight += weight;
365  }
366 
367  ++ItIn;
368  ++ItOut;
369  }
370  if( totalWeight > 0 )
371  {
372  itkDebugMacro(
373  "The average weighted difference norm of the point set is "
374  << avg_p / totalWeight );
375  }
381  str2.Filter = this;
382 
383  this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfThreads() );
384  this->GetMultiThreader()->SetSingleMethod( this->ThreaderCallback, &str2 );
385 
389  this->BeforeThreadedGenerateData();
390  this->GetMultiThreader()->SingleMethodExecute();
391  this->AfterThreadedGenerateData();
392 
393  this->UpdatePointSet();
394  }
395 
396  if( this->m_DoMultilevel )
397  {
398  ImageRegionIterator<PointDataImageType> ItPsi( this->m_PsiLattice,
399  this->m_PsiLattice->GetLargestPossibleRegion() );
400  ImageRegionIterator<PointDataImageType> ItPhi( this->m_PhiLattice,
401  this->m_PhiLattice->GetLargestPossibleRegion() );
402  for( ItPsi.GoToBegin(), ItPhi.GoToBegin();
403  !ItPsi.IsAtEnd(); ++ItPsi, ++ItPhi )
404  {
405  ItPsi.Set( ItPhi.Get() + ItPsi.Get() );
406  }
407 
408  typedef ImageDuplicator<PointDataImageType> ImageDuplicatorType;
409  typename ImageDuplicatorType::Pointer Duplicator
410  = ImageDuplicatorType::New();
411  Duplicator->SetInputImage( this->m_PsiLattice );
412  Duplicator->Update();
413  this->m_PhiLattice = Duplicator->GetOutput();
414  this->UpdatePointSet();
415  }
416 
417  if( this->m_GenerateOutputImage )
418  {
419  //this->GenerateOutputImage();
420  this->GenerateOutputImageFast();
421  }
422 }
423 
424 template <class TInputPointSet, class TOutputImage>
425 void
428 {
429  this->m_DeltaLatticePerThread.resize( this->GetNumberOfThreads() );
430  this->m_OmegaLatticePerThread.resize( this->GetNumberOfThreads() );
431 }
432 
433 template <class TInputPointSet, class TOutputImage>
434 void
436 ::ThreadedGenerateData( const RegionType &itkNotUsed(region), int threadId )
437 {
443  for( unsigned int i = 0; i < ImageDimension; i++ )
444  {
445  if( this->m_CloseDimension[i] )
446  {
447  size[i] = this->m_CurrentNumberOfControlPoints[i]
448  - this->m_SplineOrder[i];
449  }
450  else
451  {
452  size[i] = this->m_CurrentNumberOfControlPoints[i];
453  }
454  }
455 
456  this->m_OmegaLatticePerThread[threadId] = RealImageType::New();
457  this->m_OmegaLatticePerThread[threadId]->SetRegions( size );
458  this->m_OmegaLatticePerThread[threadId]->Allocate();
459  this->m_OmegaLatticePerThread[threadId]->FillBuffer( 0.0 );
460 
461  this->m_DeltaLatticePerThread[threadId] = PointDataImageType::New();
462  this->m_DeltaLatticePerThread[threadId]->SetRegions( size );
463  this->m_DeltaLatticePerThread[threadId]->Allocate();
464  this->m_DeltaLatticePerThread[threadId]->FillBuffer( 0.0 );
465 
466  for( unsigned int i = 0; i < ImageDimension; i++ )
467  {
468  size[i] = this->m_SplineOrder[i] + 1;
469  }
470 
471  typename RealImageType::Pointer w = RealImageType::New();
472  w->SetRegions( size );
473  w->Allocate();
474 
475  typename PointDataImageType::Pointer phi = PointDataImageType::New();
476  phi->SetRegions( size );
477  phi->Allocate();
478 
480  Itw( w, w->GetLargestPossibleRegion() );
482  Itp( phi, phi->GetLargestPossibleRegion() );
483 
484  vnl_vector<RealType> p( ImageDimension );
485  vnl_vector<RealType> r( ImageDimension );
486  for( unsigned int i = 0; i < ImageDimension; i++ )
487  {
488  r[i] = static_cast<RealType>( this->m_CurrentNumberOfControlPoints[i] -
489  this->m_SplineOrder[i] ) / ( static_cast<RealType>( this->m_Size[i] - 1 )
490  * this->m_Spacing[i] );
491  }
492 
496  int numberOfThreads = this->GetNumberOfThreads();
497  unsigned long numberOfPointsPerThread = static_cast<unsigned long>(
498  this->GetInput()->GetNumberOfPoints() / numberOfThreads );
499 
500  unsigned int start = threadId * numberOfPointsPerThread;
501  unsigned int end = start + numberOfPointsPerThread;
502  if( threadId == this->GetNumberOfThreads() - 1 )
503  {
504  end = this->GetInput()->GetNumberOfPoints();
505  }
506 
507  for( unsigned int n = start; n < end; n++ )
508  {
509  PointType point;
510  point.Fill( 0.0 );
511 
512  this->GetInput()->GetPoint( n, &point );
513 
514  for( unsigned int i = 0; i < ImageDimension; i++ )
515  {
516  unsigned int totalNumberOfSpans
517  = this->m_CurrentNumberOfControlPoints[i] - this->m_SplineOrder[i];
518 
519  p[i] = ( point[i] - this->m_Origin[i] ) * r[i];
520  if( vnl_math_abs( p[i] - static_cast<RealType>( totalNumberOfSpans ) )
521  <= this->m_BSplineEpsilon )
522  {
523  p[i] = static_cast<RealType>( totalNumberOfSpans )
524  - this->m_BSplineEpsilon;
525  }
526  if( p[i] >= static_cast<RealType>( totalNumberOfSpans ) )
527  {
528  itkExceptionMacro( "The reparameterized point component " << p[i]
529  << " is outside the corresponding parametric domain of [0, "
530  << totalNumberOfSpans << "]." );
531  }
532  }
533 
534  RealType w2_sum = 0.0;
535  for( Itw.GoToBegin(); !Itw.IsAtEnd(); ++Itw )
536  {
537  RealType B = 1.0;
538  typename RealImageType::IndexType idx = Itw.GetIndex();
539  for( unsigned int i = 0; i < ImageDimension; i++ )
540  {
541  RealType u = static_cast<RealType>( p[i] -
542  static_cast<unsigned>( p[i] ) - idx[i] )
543  + 0.5*static_cast<RealType>( this->m_SplineOrder[i] - 1 );
544  switch( this->m_SplineOrder[i] )
545  {
546  case 0:
547  {
548  B *= this->m_KernelOrder0->Evaluate( u );
549  break;
550  }
551  case 1:
552  {
553  B *= this->m_KernelOrder1->Evaluate( u );
554  break;
555  }
556  case 2:
557  {
558  B *= this->m_KernelOrder2->Evaluate( u );
559  break;
560  }
561  case 3:
562  {
563  B *= this->m_KernelOrder3->Evaluate( u );
564  break;
565  }
566  default:
567  {
568  B *= this->m_Kernel[i]->Evaluate( u );
569  break;
570  }
571  }
572  }
573  Itw.Set( B );
574  w2_sum += B*B;
575  }
576 
577  for( Itp.GoToBegin(), Itw.GoToBegin(); !Itp.IsAtEnd(); ++Itp, ++Itw )
578  {
579  typename RealImageType::IndexType idx = Itw.GetIndex();
580  for( unsigned int i = 0; i < ImageDimension; i++ )
581  {
582  idx[i] += static_cast<unsigned>( p[i] );
583  if( this->m_CloseDimension[i] )
584  {
585  idx[i] %= this->m_DeltaLatticePerThread[threadId]
586  ->GetLargestPossibleRegion().GetSize()[i];
587  }
588  }
589  RealType wc = this->m_PointWeights->GetElement( n );
590  RealType t = Itw.Get();
591  this->m_OmegaLatticePerThread[threadId]->SetPixel( idx,
592  this->m_OmegaLatticePerThread[threadId]->GetPixel( idx ) + wc*t*t );
593 
594  PointDataType data = this->m_InputPointData->GetElement( n );
595  data *= ( t / w2_sum );
596  Itp.Set( data );
597  data *= ( t * t * wc );
598  this->m_DeltaLatticePerThread[threadId]->SetPixel(
599  idx, this->m_DeltaLatticePerThread[threadId]->GetPixel( idx ) + data );
600  }
601  }
602 }
603 
604 template <class TInputPointSet, class TOutputImage>
605 void
608 {
614  this->m_DeltaLatticePerThread[0],
615  this->m_DeltaLatticePerThread[0]->GetLargestPossibleRegion() );
617  this->m_OmegaLatticePerThread[0],
618  this->m_OmegaLatticePerThread[0]->GetLargestPossibleRegion() );
619 
620  for( int n = 1; n < this->GetNumberOfThreads(); n++ )
621  {
623  this->m_DeltaLatticePerThread[n],
624  this->m_DeltaLatticePerThread[n]->GetLargestPossibleRegion() );
626  this->m_OmegaLatticePerThread[n],
627  this->m_OmegaLatticePerThread[n]->GetLargestPossibleRegion() );
628 
629  ItD.GoToBegin();
630  ItO.GoToBegin();
631  Itd.GoToBegin();
632  Ito.GoToBegin();
633  while( !ItD.IsAtEnd() )
634  {
635  ItD.Set( ItD.Get() + Itd.Get() );
636  ItO.Set( ItO.Get() + Ito.Get() );
637 
638  ++ItD;
639  ++ItO;
640  ++Itd;
641  ++Ito;
642  }
643  }
644 
649  for( unsigned int i = 0; i < ImageDimension; i++ )
650  {
651  if( this->m_CloseDimension[i] )
652  {
653  size[i] = this->m_CurrentNumberOfControlPoints[i]-this->m_SplineOrder[i];
654  }
655  else
656  {
657  size[i] = this->m_CurrentNumberOfControlPoints[i];
658  }
659  }
660  this->m_PhiLattice = PointDataImageType::New();
661  this->m_PhiLattice->SetRegions( size );
662  this->m_PhiLattice->Allocate();
663  this->m_PhiLattice->FillBuffer( 0.0 );
664 
666  this->m_PhiLattice, this->m_PhiLattice->GetLargestPossibleRegion() );
667 
668  for( ItP.GoToBegin(), ItO.GoToBegin(), ItD.GoToBegin();
669  !ItP.IsAtEnd(); ++ItP, ++ItO, ++ItD )
670  {
671  PointDataType P;
672  P.Fill( 0 );
673  if( ItO.Get() != 0 )
674  {
675  P = ItD.Get() / ItO.Get();
676  for( unsigned int i = 0; i < P.Size(); i++ )
677  {
678  if( vnl_math_isnan( P[i] ) || vnl_math_isinf( P[i] ) )
679  {
680  P[i] = 0;
681  }
682  }
683  ItP.Set( P );
684  }
685  }
686 }
687 
688 template <class TInputPointSet, class TOutputImage>
689 void
692 {
693  ArrayType NumberOfNewControlPoints = this->m_CurrentNumberOfControlPoints;
694  for( unsigned int i = 0; i < ImageDimension; i++ )
695  {
696  if( this->m_CurrentLevel < this->m_NumberOfLevels[i] )
697  {
698  NumberOfNewControlPoints[i]
699  = 2*NumberOfNewControlPoints[i]-this->m_SplineOrder[i];
700  }
701  }
703  for( unsigned int i = 0; i < ImageDimension; i++ )
704  {
705  if( this->m_CloseDimension[i] )
706  {
707  size[i] = NumberOfNewControlPoints[i] - this->m_SplineOrder[i];
708  }
709  else
710  {
711  size[i] = NumberOfNewControlPoints[i];
712  }
713  }
714 
715  typename PointDataImageType::Pointer RefinedLattice
716  = PointDataImageType::New();
717  RefinedLattice->SetRegions( size );
718  RefinedLattice->Allocate();
719  PointDataType data;
720  data.Fill( 0.0 );
721  RefinedLattice->FillBuffer( data );
722 
723  typename PointDataImageType::IndexType idx;
724  typename PointDataImageType::IndexType idx_Psi;
725  typename PointDataImageType::IndexType tmp;
726  typename PointDataImageType::IndexType tmp_Psi;
727  typename PointDataImageType::IndexType off;
728  typename PointDataImageType::IndexType off_Psi;
730 
731  size.Fill( 2 );
732  unsigned int N = 1;
733  for( unsigned int i = 0; i < ImageDimension; i++ )
734  {
735  N *= ( this->m_SplineOrder[i] + 1 );
736  size_Psi[i] = this->m_SplineOrder[i] + 1;
737  }
738 
740  It( RefinedLattice, RefinedLattice->GetLargestPossibleRegion() );
741 
742  It.GoToBegin();
743  while( !It.IsAtEnd() )
744  {
745  idx = It.GetIndex();
746  for( unsigned int i = 0; i < ImageDimension; i++ )
747  {
748  if( this->m_CurrentLevel < this->m_NumberOfLevels[i] )
749  {
750  idx_Psi[i] = static_cast<unsigned int>( 0.5*idx[i] );
751  }
752  else
753  {
754  idx_Psi[i] = static_cast<unsigned int>( idx[i] );
755  }
756  }
757 
758  for( unsigned int i = 0; i < ( 2 << (ImageDimension-1) ); i++ )
759  {
760  PointDataType sum( 0.0 );
761  PointDataType val( 0.0 );
762  off = this->NumberToIndex( i, size );
763 
764  bool OutOfBoundary = false;
765  for( unsigned int j = 0; j < ImageDimension; j++ )
766  {
767  tmp[j] = idx[j] + off[j];
768  if( tmp[j] >= static_cast<int>( NumberOfNewControlPoints[j] )
769  && !this->m_CloseDimension[j] )
770  {
771  OutOfBoundary = true;
772  break;
773  }
774  if( this->m_CloseDimension[j] )
775  {
776  tmp[j] %= RefinedLattice->GetLargestPossibleRegion().GetSize()[j];
777  }
778  }
779  if( OutOfBoundary )
780  {
781  continue;
782  }
783 
784  for( unsigned int j = 0; j < N; j++ )
785  {
786  off_Psi = this->NumberToIndex( j, size_Psi );
787 
788  bool IsOutOfBoundary = false;
789  for( unsigned int k = 0; k < ImageDimension; k++ )
790  {
791  tmp_Psi[k] = idx_Psi[k] + off_Psi[k];
792  if( tmp_Psi[k] >=
793  static_cast<int>( this->m_CurrentNumberOfControlPoints[k] )
794  && !this->m_CloseDimension[k] )
795  {
796  IsOutOfBoundary = true;
797  break;
798  }
799  if( this->m_CloseDimension[k] )
800  {
801  tmp_Psi[k] %=
802  this->m_PsiLattice->GetLargestPossibleRegion().GetSize()[k];
803  }
804  }
805  if( IsOutOfBoundary )
806  {
807  continue;
808  }
809  RealType coeff = 1.0;
810  for( unsigned int k = 0; k < ImageDimension; k++ )
811  {
812  coeff *= this->m_RefinedLatticeCoefficients[k]( off[k], off_Psi[k] );
813  }
814  val = this->m_PsiLattice->GetPixel( tmp_Psi );
815  val *= coeff;
816  sum += val;
817  }
818  RefinedLattice->SetPixel( tmp, sum );
819  }
820 
821  bool IsEvenIndex = false;
822  while( !IsEvenIndex && !It.IsAtEnd() )
823  {
824  ++It;
825  idx = It.GetIndex();
826  IsEvenIndex = true;
827  for( unsigned int i = 0; i < ImageDimension; i++ )
828  {
829  if( idx[i] % 2 )
830  {
831  IsEvenIndex = false;
832  }
833  }
834  }
835  }
836 
837  typedef ImageDuplicator<PointDataImageType> ImageDuplicatorType;
838  typename ImageDuplicatorType::Pointer Duplicator = ImageDuplicatorType::New();
839  Duplicator->SetInputImage( RefinedLattice );
840  Duplicator->Update();
841  this->m_PsiLattice = Duplicator->GetOutput();
842 }
843 
844 template <class TInputPointSet, class TOutputImage>
845 void
848 {
849  typename PointDataImageType::Pointer collapsedPhiLattices[ImageDimension+1];
850  for( unsigned int i = 0; i < ImageDimension; i++ )
851  {
852  collapsedPhiLattices[i] = PointDataImageType::New();
853  collapsedPhiLattices[i]->SetOrigin( this->m_PhiLattice->GetOrigin() );
854  collapsedPhiLattices[i]->SetSpacing( this->m_PhiLattice->GetSpacing() );
855  collapsedPhiLattices[i]->SetDirection( this->m_PhiLattice->GetDirection() );
856  typename PointDataImageType::SizeType size;
857  size.Fill( 1 );
858  for( unsigned int j = 0; j < i; j++ )
859  {
860  size[j] = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[j];
861  }
862  collapsedPhiLattices[i]->SetRegions( size );
863  collapsedPhiLattices[i]->Allocate();
864  }
865  collapsedPhiLattices[ImageDimension] = this->m_PhiLattice;
866  ArrayType totalNumberOfSpans;
867  for( unsigned int i = 0; i < ImageDimension; i++ )
868  {
869  if( this->m_CloseDimension[i] )
870  {
871  totalNumberOfSpans[i]
872  = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i];
873  }
874  else
875  {
876  totalNumberOfSpans[i]
877  = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i]
878  - this->m_SplineOrder[i];
879  }
880  }
883  currentU.Fill( -1 );
884  typename PointDataImageType::IndexType startPhiIndex
885  = this->m_PhiLattice->GetLargestPossibleRegion().GetIndex();
886 
887  typename PointDataContainerType::ConstIterator ItIn;
888 
889  ItIn = this->m_InputPointData->Begin();
890  while( ItIn != this->m_InputPointData->End() )
891  {
892  PointType point;
893  point.Fill( 0.0 );
894 
895  this->GetInput()->GetPoint( ItIn.Index(), &point );
896 
897  for( unsigned int i = 0; i < ImageDimension; i++ )
898  {
899  U[i] = static_cast<RealType>( totalNumberOfSpans[i] ) *
900  static_cast<RealType>( point[i] - this->m_Origin[i] ) /
901  ( static_cast<RealType>( this->m_Size[i] - 1 ) * this->m_Spacing[i] );
902  if( vnl_math_abs( U[i] - static_cast<RealType>( totalNumberOfSpans[i] ) )
903  <= this->m_BSplineEpsilon )
904  {
905  U[i] = static_cast<RealType>( totalNumberOfSpans[i] )
906  - this->m_BSplineEpsilon;
907  }
908  if( U[i] >= static_cast<RealType>( totalNumberOfSpans[i] ) )
909  {
910  itkExceptionMacro( "The collapse point component " << U[i]
911  << " is outside the corresponding parametric domain of [0, "
912  << totalNumberOfSpans[i] << "]." );
913  }
914  }
915  for( int i = ImageDimension-1; i >= 0; i-- )
916  {
917  if( U[i] != currentU[i] )
918  {
919  for( int j = i; j >= 0; j-- )
920  {
921  this->CollapsePhiLattice( collapsedPhiLattices[j+1],
922  collapsedPhiLattices[j], U[j], j );
923  currentU[j] = U[j];
924  }
925  break;
926  }
927  }
928  this->m_OutputPointData->InsertElement( ItIn.Index(),
929  collapsedPhiLattices[0]->GetPixel( startPhiIndex ) );
930  ++ItIn;
931  }
932 }
933 
934 template <class TInputPointSet, class TOutputImage>
935 void
938 {
940  It( this->GetOutput(), this->GetOutput()->GetBufferedRegion() );
941 
942  for( It.GoToBegin(); !It.IsAtEnd(); ++It )
943  {
944  PointDataType data;
945  this->EvaluateAtIndex( It.GetIndex(), data );
946  It.Set( data );
947  }
948 }
949 
950 template <class TInputPointSet, class TOutputImage>
951 void
954 {
955  typename PointDataImageType::Pointer collapsedPhiLattices[ImageDimension+1];
956  for( unsigned int i = 0; i < ImageDimension; i++ )
957  {
958  collapsedPhiLattices[i] = PointDataImageType::New();
959  collapsedPhiLattices[i]->SetOrigin( this->m_PhiLattice->GetOrigin() );
960  collapsedPhiLattices[i]->SetSpacing( this->m_PhiLattice->GetSpacing() );
961  collapsedPhiLattices[i]->SetDirection( this->m_PhiLattice->GetDirection() );
962  typename PointDataImageType::SizeType size;
963  size.Fill( 1 );
964  for( unsigned int j = 0; j < i; j++ )
965  {
966  size[j] = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[j];
967  }
968  collapsedPhiLattices[i]->SetRegions( size );
969  collapsedPhiLattices[i]->Allocate();
970  }
971  collapsedPhiLattices[ImageDimension] = this->m_PhiLattice;
972  ArrayType totalNumberOfSpans;
973  for( unsigned int i = 0; i < ImageDimension; i++ )
974  {
975  if( this->m_CloseDimension[i] )
976  {
977  totalNumberOfSpans[i]
978  = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i];
979  }
980  else
981  {
982  totalNumberOfSpans[i]
983  = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i]
984  - this->m_SplineOrder[i];
985  }
986  }
989  currentU.Fill( -1 );
990  typename ImageType::IndexType startIndex
991  = this->GetOutput()->GetRequestedRegion().GetIndex();
992  typename PointDataImageType::IndexType startPhiIndex
993  = this->m_PhiLattice->GetLargestPossibleRegion().GetIndex();
994 
996  It( this->GetOutput(), this->GetOutput()->GetRequestedRegion() );
997  for( It.GoToBegin(); !It.IsAtEnd(); ++It )
998  {
999  typename ImageType::IndexType idx = It.GetIndex();
1000  for( unsigned int i = 0; i < ImageDimension; i++ )
1001  {
1002  U[i] = static_cast<RealType>( totalNumberOfSpans[i] ) *
1003  static_cast<RealType>( idx[i] - startIndex[i] ) /
1004  static_cast<RealType>( this->m_Size[i] - 1 );
1005  if( vnl_math_abs( U[i] - static_cast<RealType>( totalNumberOfSpans[i] ) )
1006  <= this->m_BSplineEpsilon )
1007  {
1008  U[i] = static_cast<RealType>( totalNumberOfSpans[i] )
1009  - this->m_BSplineEpsilon;
1010  }
1011  if( U[i] >= static_cast<RealType>( totalNumberOfSpans[i] ) )
1012  {
1013  itkExceptionMacro( "The collapse point component " << U[i]
1014  << " is outside the corresponding parametric domain of [0, "
1015  << totalNumberOfSpans[i] << "]." );
1016  }
1017  }
1018  for( int i = ImageDimension-1; i >= 0; i-- )
1019  {
1020  if( U[i] != currentU[i] )
1021  {
1022  for( int j = i; j >= 0; j-- )
1023  {
1024  this->CollapsePhiLattice( collapsedPhiLattices[j+1],
1025  collapsedPhiLattices[j], U[j], j );
1026  currentU[j] = U[j];
1027  }
1028  break;
1029  }
1030  }
1031  It.Set( collapsedPhiLattices[0]->GetPixel( startPhiIndex ) );
1032  }
1033 }
1034 
1035 template <class TInputPointSet, class TOutputImage>
1036 void
1039  PointDataImageType *collapsedLattice, RealType u, unsigned int dimension )
1040 {
1042  ( collapsedLattice, collapsedLattice->GetLargestPossibleRegion() );
1043 
1044  for( It.GoToBegin(); !It.IsAtEnd(); ++It )
1045  {
1046  PointDataType data;
1047  data.Fill( 0.0 );
1048  typename PointDataImageType::IndexType idx = It.GetIndex();
1049  for( unsigned int i = 0; i < this->m_SplineOrder[dimension] + 1; i++ )
1050  {
1051  idx[dimension] = static_cast<unsigned int>( u ) + i;
1052  RealType v = u - idx[dimension]
1053  + 0.5*static_cast<RealType>( this->m_SplineOrder[dimension] - 1 );
1054  RealType B;
1055  switch( this->m_SplineOrder[dimension] )
1056  {
1057  case 0:
1058  {
1059  B = this->m_KernelOrder0->Evaluate( v );
1060  break;
1061  }
1062  case 1:
1063  {
1064  B = this->m_KernelOrder1->Evaluate( v );
1065  break;
1066  }
1067  case 2:
1068  {
1069  B = this->m_KernelOrder2->Evaluate( v );
1070  break;
1071  }
1072  case 3:
1073  {
1074  B = this->m_KernelOrder3->Evaluate( v );
1075  break;
1076  }
1077  default:
1078  {
1079  B = this->m_Kernel[dimension]->Evaluate( v );
1080  break;
1081  }
1082  }
1083  if( this->m_CloseDimension[dimension] )
1084  {
1085  idx[dimension] %=
1086  lattice->GetLargestPossibleRegion().GetSize()[dimension];
1087  }
1088 
1089  if(idx[dimension]>=0 && static_cast<typename PointDataImageType::RegionType::SizeValueType>(idx[dimension])<lattice->GetLargestPossibleRegion().GetSize()[dimension])
1090  data += ( lattice->GetPixel( idx ) * B );
1091  }
1092  It.Set( data );
1093  }
1094 }
1095 
1096 template <class TInputPointSet, class TOutputImage>
1097 void
1100 {
1101  for( unsigned int i = 0; i < ImageDimension; i++)
1102  {
1103  point[i] -= this->m_Origin[i];
1104  point[i] /=
1105  ( static_cast<RealType>( this->m_Size[i] - 1 ) * this->m_Spacing[i] );
1106  }
1107  this->Evaluate( point, data );
1108 }
1109 
1110 template <class TInputPointSet, class TOutputImage>
1111 void
1114 {
1115  PointType point;
1116  this->GetOutput()->TransformIndexToPhysicalPoint( idx, point );
1117  this->EvaluateAtPoint( point, data );
1118 }
1119 
1120 template <class TInputPointSet, class TOutputImage>
1121 void
1124 {
1125  PointType point;
1126  this->GetOutput()->TransformContinuousIndexToPhysicalPoint( idx, point );
1127  this->EvaluateAtPoint( point, data );
1128 }
1129 
1130 template <class TInputPointSet, class TOutputImage>
1131 void
1134 {
1135  vnl_vector<RealType> p( ImageDimension );
1136  for( unsigned int i = 0; i < ImageDimension; i++ )
1137  {
1138  if( params[i] == NumericTraits<RealType>::One )
1139  {
1140  params[i] = NumericTraits<RealType>::One - this->m_BSplineEpsilon;
1141  }
1142  if( params[i] < 0.0 || params[i] >= 1.0 )
1143  {
1144  itkExceptionMacro( "The specified point " << params
1145  << " is outside the reparameterized domain [0, 1]." );
1146  }
1147  p[i] = static_cast<RealType>( params[i] )
1148  * static_cast<RealType>( this->m_CurrentNumberOfControlPoints[i]
1149  - this->m_SplineOrder[i] );
1150  }
1151 
1153  for( unsigned int i = 0; i < ImageDimension; i++ )
1154  {
1155  size[i] = this->m_SplineOrder[i] + 1;
1156  }
1157  typename RealImageType::Pointer w;
1158  w = RealImageType::New();
1159  w->SetRegions( size );
1160  w->Allocate();
1161 
1162  PointDataType val;
1163  data.Fill( 0.0 );
1164 
1166  Itw( w, w->GetLargestPossibleRegion() );
1167 
1168  for( Itw.GoToBegin(); !Itw.IsAtEnd(); ++Itw )
1169  {
1170  RealType B = 1.0;
1171  typename RealImageType::IndexType idx = Itw.GetIndex();
1172  for( unsigned int i = 0; i < ImageDimension; i++ )
1173  {
1174  RealType u = p[i] - static_cast<RealType>( static_cast<unsigned>( p[i] )
1175  + idx[i] ) + 0.5*static_cast<RealType>( this->m_SplineOrder[i] - 1 );
1176  switch( this->m_SplineOrder[i] )
1177  {
1178  case 0:
1179  {
1180  B *= this->m_KernelOrder0->Evaluate( u );
1181  break;
1182  }
1183  case 1:
1184  {
1185  B *= this->m_KernelOrder1->Evaluate( u );
1186  break;
1187  }
1188  case 2:
1189  {
1190  B *= this->m_KernelOrder2->Evaluate( u );
1191  break;
1192  }
1193  case 3:
1194  {
1195  B *= this->m_KernelOrder3->Evaluate( u );
1196  break;
1197  }
1198  default:
1199  {
1200  B *= this->m_Kernel[i]->Evaluate( u );
1201  break;
1202  }
1203  }
1204  }
1205  for( unsigned int i = 0; i < ImageDimension; i++ )
1206  {
1207  idx[i] += static_cast<unsigned int>( p[i] );
1208  if( this->m_CloseDimension[i] )
1209  {
1210  idx[i] %= this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i];
1211  }
1212  }
1213  if( this->m_PhiLattice->GetLargestPossibleRegion().IsInside( idx ) )
1214  {
1215  val = this->m_PhiLattice->GetPixel( idx );
1216  val *= B;
1217  data += val;
1218  }
1219  }
1220 }
1221 
1222 template <class TInputPointSet, class TOutputImage>
1223 void
1226 {
1227  for( unsigned int i = 0; i < ImageDimension; i++)
1228  {
1229  point[i] -= this->m_Origin[i];
1230  point[i] /=
1231  ( static_cast<RealType>( this->m_Size[i] - 1 ) * this->m_Spacing[i] );
1232  }
1233  this->EvaluateGradient( point, gradient );
1234 }
1235 
1236 template <class TInputPointSet, class TOutputImage>
1237 void
1240 {
1241  PointType point;
1242  this->GetOutput()->TransformIndexToPhysicalPoint( idx, point );
1243  this->EvaluateGradientAtPoint( point, gradient );
1244 }
1245 
1246 template <class TInputPointSet, class TOutputImage>
1247 void
1250  ContinuousIndexType idx, GradientType &gradient )
1251 {
1252  PointType point;
1253  this->GetOutput()->TransformContinuousIndexToPhysicalPoint( idx, gradient );
1254  this->EvaluateGradientAtPoint( point, gradient );
1255 }
1256 
1257 template <class TInputPointSet, class TOutputImage>
1258 void
1261 {
1262  vnl_vector<RealType> p( ImageDimension );
1263  for( unsigned int i = 0; i < ImageDimension; i++ )
1264  {
1265  if( params[i] == NumericTraits<RealType>::One )
1266  {
1267  params[i] = NumericTraits<RealType>::One - this->m_BSplineEpsilon;
1268  }
1269  if( params[i] < 0.0 || params[i] >= 1.0 )
1270  {
1271  itkExceptionMacro( "The specified point " << params
1272  << " is outside the reparameterized domain [0, 1]." );
1273  }
1274  p[i] = static_cast<RealType>( params[i] )
1275  * static_cast<RealType>( this->m_CurrentNumberOfControlPoints[i]
1276  - this->m_SplineOrder[i] );
1277  }
1278 
1280  for( unsigned int i = 0; i < ImageDimension; i++ )
1281  {
1282  size[i] = this->m_SplineOrder[i] + 1;
1283  }
1284  typename RealImageType::Pointer w;
1285  w = RealImageType::New();
1286  w->SetRegions( size );
1287  w->Allocate();
1288 
1289  PointDataType val;
1290  gradient.SetSize( val.Size(), ImageDimension );
1291  gradient.Fill( 0.0 );
1292 
1294  Itw( w, w->GetLargestPossibleRegion() );
1295 
1296  for( unsigned int j = 0; j < gradient.Cols(); j++ )
1297  {
1298  for( Itw.GoToBegin(); !Itw.IsAtEnd(); ++Itw )
1299  {
1300  RealType B = 1.0;
1301  typename RealImageType::IndexType idx = Itw.GetIndex();
1302  for( unsigned int i = 0; i < ImageDimension; i++ )
1303  {
1304  RealType u = p[i] - static_cast<RealType>( static_cast<unsigned>( p[i] )
1305  + idx[i] ) + 0.5*static_cast<RealType>( this->m_SplineOrder[i] - 1 );
1306  if( j == i )
1307  {
1308  B *= this->m_Kernel[i]->EvaluateDerivative( u );
1309  }
1310  else
1311  {
1312  B *= this->m_Kernel[i]->Evaluate( u );
1313  }
1314  }
1315  for( unsigned int i = 0; i < ImageDimension; i++ )
1316  {
1317  idx[i] += static_cast<unsigned int>( p[i] );
1318  if( this->m_CloseDimension[i] )
1319  {
1320  idx[i] %= this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i];
1321  }
1322  }
1323  if( this->m_PhiLattice->GetLargestPossibleRegion().IsInside( idx ) )
1324  {
1325  val = this->m_PhiLattice->GetPixel( idx );
1326  val *= B;
1327  for( unsigned int i = 0; i < val.Size(); i++ )
1328  {
1329  gradient( i, j ) += val[i];
1330  }
1331  }
1332  }
1333  }
1334 }
1335 
1339 template <class TInputPointSet, class TOutputImage>
1340 void
1343  std::ostream& os,
1344  Indent indent) const
1345 {
1346  Superclass::PrintSelf( os, indent );
1347  for( unsigned int i = 0; i < ImageDimension; i++ )
1348  {
1349  this->m_Kernel[i]->Print( os, indent );
1350  }
1351  os << indent << "B-spline order: "
1352  << this->m_SplineOrder << std::endl;
1353  os << indent << "Number Of control points: "
1354  << this->m_NumberOfControlPoints << std::endl;
1355  os << indent << "Close dimension: "
1356  << this->m_CloseDimension << std::endl;
1357  os << indent << "Number of levels "
1358  << this->m_NumberOfLevels << std::endl;
1359 }
1360 
1361 } // end namespace itk
1362 
1363 #endif

Generated at Sat May 18 2013 23:32:25 for Orfeo Toolbox with doxygen 1.8.3.1