18 #ifndef __itkBSplineScatteredDataPointSetToImageFilter_txx
19 #define __itkBSplineScatteredDataPointSetToImageFilter_txx
27 #include "itkNumericTraits.h"
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"
44 template <
class TInputPo
intSet,
class TOutputImage>
48 this->m_SplineOrder.Fill( 3 );
49 for(
unsigned int i = 0; i < ImageDimension; i++ )
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] );
55 this->m_KernelOrder0 = KernelOrder0Type::New();
56 this->m_KernelOrder1 = KernelOrder1Type::New();
57 this->m_KernelOrder2 = KernelOrder2Type::New();
58 this->m_KernelOrder3 = KernelOrder3Type::New();
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;
66 this->m_PhiLattice =
NULL;
67 this->m_PsiLattice = PointDataImageType::New();
68 this->m_InputPointData = PointDataContainerType::New();
69 this->m_OutputPointData = PointDataContainerType::New();
71 this->m_PointWeights = WeightsContainerType::New();
72 this->m_UsePointWeights =
false;
74 this->m_BSplineEpsilon = vcl_numeric_limits<RealType>::epsilon();
77 template <
class TInputPo
intSet,
class TOutputImage>
83 template <
class TInputPo
intSet,
class TOutputImage>
88 this->m_SplineOrder.Fill( order );
89 this->SetSplineOrder( this->m_SplineOrder );
92 template <
class TInputPo
intSet,
class TOutputImage>
97 itkDebugMacro(
"Setting m_SplineOrder to " << order );
99 this->m_SplineOrder = order;
100 for(
int i = 0; i < ImageDimension; i++ )
102 if( this->m_SplineOrder[i] == 0 )
105 "The spline order in each dimension must be greater than 0" );
108 this->m_Kernel[i] = KernelType::New();
109 this->m_Kernel[i]->SetSplineOrder( this->m_SplineOrder[i] );
111 if( this->m_DoMultilevel )
114 C = this->m_Kernel[i]->GetShapeFunctionsInZeroToOneInterval();
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++ )
122 for(
unsigned int k = 0; k < C.cols(); k++ )
124 R(j, k) = S(j, k) =
static_cast<RealType>( C(j, k) );
127 for(
unsigned int j = 0; j < C.cols(); j++ )
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++)
141 this->m_RefinedLatticeCoefficients[i]
142 = ( vnl_svd<RealType>( R ).solve( S ) ).extract( 2, S.cols() );
148 template <
class TInputPo
intSet,
class TOutputImage>
153 this->m_NumberOfLevels.Fill( levels );
154 this->SetNumberOfLevels( this->m_NumberOfLevels );
157 template <
class TInputPo
intSet,
class TOutputImage>
162 this->m_NumberOfLevels = levels;
163 this->m_MaximumNumberOfLevels = 1;
164 for(
unsigned int i = 0; i < ImageDimension; i++ )
166 if( this->m_NumberOfLevels[i] == 0 )
169 "The number of levels in each dimension must be greater than 0" );
171 if( this->m_NumberOfLevels[i] > this->m_MaximumNumberOfLevels )
173 this->m_MaximumNumberOfLevels = this->m_NumberOfLevels[i];
177 itkDebugMacro(
"Setting m_NumberOfLevels to " <<
178 this->m_NumberOfLevels );
179 itkDebugMacro(
"Setting m_MaximumNumberOfLevels to " <<
180 this->m_MaximumNumberOfLevels );
182 if( this->m_MaximumNumberOfLevels > 1 )
184 this->m_DoMultilevel =
true;
188 this->m_DoMultilevel =
false;
190 this->SetSplineOrder( this->m_SplineOrder );
194 template <
class TInputPo
intSet,
class TOutputImage>
199 this->m_UsePointWeights =
true;
200 this->m_PointWeights = weights;
204 template <
class TInputPo
intSet,
class TOutputImage>
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++)
218 if( this->m_Size[i] == 0 )
220 itkExceptionMacro(
"Size must be specified." );
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();
233 if( this->m_UsePointWeights &&
234 ( this->m_PointWeights->Size() != this->GetInput()->GetNumberOfPoints() ) )
237 "The number of weight points and input points must be equal." );
240 for(
unsigned int i = 0; i < ImageDimension; i++ )
242 if( this->m_NumberOfControlPoints[i] < this->m_SplineOrder[i] + 1 )
245 "The number of control points must be greater than the spline order." );
252 unsigned int maximumNumberOfSpans = 0;
253 for(
unsigned int d = 0; d < ImageDimension; d++ )
255 unsigned int numberOfSpans = this->m_NumberOfControlPoints[d]
256 - this->m_SplineOrder[d];
257 numberOfSpans <<= ( this->m_NumberOfLevels[d] - 1 );
258 if( numberOfSpans > maximumNumberOfSpans )
260 maximumNumberOfSpans = numberOfSpans;
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 )
267 this->m_BSplineEpsilon *= 10.0;
270 this->m_InputPointData->Initialize();
271 this->m_OutputPointData->Initialize();
272 if( this->GetInput()->GetNumberOfPoints() > 0 )
274 typename PointSetType::PointDataContainer::ConstIterator It;
275 It = this->GetInput()->GetPointData()->Begin();
276 while( It != this->GetInput()->GetPointData()->End() )
278 if( !this->m_UsePointWeights )
280 this->m_PointWeights->InsertElement( It.Index(), 1.0 );
282 this->m_InputPointData->InsertElement( It.Index(), It.Value() );
283 this->m_OutputPointData->InsertElement( It.Index(), It.Value() );
288 this->m_CurrentLevel = 0;
289 this->m_CurrentNumberOfControlPoints = this->m_NumberOfControlPoints;
298 this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfThreads() );
299 this->GetMultiThreader()->SetSingleMethod( this->ThreaderCallback, &str1 );
304 this->BeforeThreadedGenerateData();
305 this->GetMultiThreader()->SingleMethodExecute();
306 this->AfterThreadedGenerateData();
308 this->UpdatePointSet();
310 if( this->m_DoMultilevel )
312 this->m_PsiLattice->SetRegions(
313 this->m_PhiLattice->GetLargestPossibleRegion() );
314 this->m_PsiLattice->Allocate();
316 this->m_PsiLattice->FillBuffer( P );
319 for( this->m_CurrentLevel = 1;
320 this->m_CurrentLevel < this->m_MaximumNumberOfLevels;
321 this->m_CurrentLevel++ )
325 this->m_PsiLattice->GetLargestPossibleRegion() );
327 this->m_PhiLattice->GetLargestPossibleRegion() );
328 for( ItPsi.GoToBegin(), ItPhi.GoToBegin();
329 !ItPsi.IsAtEnd(); ++ItPsi, ++ItPhi )
331 ItPsi.
Set( ItPhi.Get() + ItPsi.Get() );
333 this->RefineControlPointLattice();
335 for(
unsigned int i = 0; i < ImageDimension; i++ )
337 if( this->m_CurrentLevel < this->m_NumberOfLevels[i] )
339 this->m_CurrentNumberOfControlPoints[i] =
340 2*this->m_CurrentNumberOfControlPoints[i]-this->m_SplineOrder[i];
344 itkDebugMacro(
"Current Level = " << this->m_CurrentLevel );
345 itkDebugMacro(
" Current number of control points = "
346 << this->m_CurrentNumberOfControlPoints );
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() )
357 this->m_InputPointData->InsertElement(
358 ItIn.Index(), ItIn.Value() - ItOut.Value() );
360 if( this->GetDebug() )
362 RealType weight = this->m_PointWeights->GetElement( ItIn.Index() );
363 avg_p += ( ItIn.Value() - ItOut.Value() ).GetNorm() * weight;
364 totalWeight += weight;
370 if( totalWeight > 0 )
373 "The average weighted difference norm of the point set is "
374 << avg_p / totalWeight );
383 this->GetMultiThreader()->SetNumberOfThreads( this->GetNumberOfThreads() );
384 this->GetMultiThreader()->SetSingleMethod( this->ThreaderCallback, &str2 );
389 this->BeforeThreadedGenerateData();
390 this->GetMultiThreader()->SingleMethodExecute();
391 this->AfterThreadedGenerateData();
393 this->UpdatePointSet();
396 if( this->m_DoMultilevel )
399 this->m_PsiLattice->GetLargestPossibleRegion() );
401 this->m_PhiLattice->GetLargestPossibleRegion() );
402 for( ItPsi.GoToBegin(), ItPhi.GoToBegin();
403 !ItPsi.IsAtEnd(); ++ItPsi, ++ItPhi )
405 ItPsi.
Set( ItPhi.Get() + ItPsi.Get() );
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();
417 if( this->m_GenerateOutputImage )
420 this->GenerateOutputImageFast();
424 template <
class TInputPo
intSet,
class TOutputImage>
429 this->m_DeltaLatticePerThread.resize( this->GetNumberOfThreads() );
430 this->m_OmegaLatticePerThread.resize( this->GetNumberOfThreads() );
433 template <
class TInputPo
intSet,
class TOutputImage>
443 for(
unsigned int i = 0; i < ImageDimension; i++ )
445 if( this->m_CloseDimension[i] )
447 size[i] = this->m_CurrentNumberOfControlPoints[i]
448 - this->m_SplineOrder[i];
452 size[i] = this->m_CurrentNumberOfControlPoints[i];
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 );
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 );
466 for(
unsigned int i = 0; i < ImageDimension; i++ )
468 size[i] = this->m_SplineOrder[i] + 1;
472 w->SetRegions( size );
476 phi->SetRegions( size );
480 Itw( w, w->GetLargestPossibleRegion() );
482 Itp( phi, phi->GetLargestPossibleRegion() );
484 vnl_vector<RealType> p( ImageDimension );
485 vnl_vector<RealType> r( ImageDimension );
486 for(
unsigned int i = 0; i < ImageDimension; i++ )
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] );
496 int numberOfThreads = this->GetNumberOfThreads();
497 unsigned long numberOfPointsPerThread =
static_cast<unsigned long>(
498 this->GetInput()->GetNumberOfPoints() / numberOfThreads );
500 unsigned int start = threadId * numberOfPointsPerThread;
501 unsigned int end = start + numberOfPointsPerThread;
502 if( threadId == this->GetNumberOfThreads() - 1 )
504 end = this->GetInput()->GetNumberOfPoints();
507 for(
unsigned int n = start; n < end; n++ )
512 this->GetInput()->GetPoint( n, &point );
514 for(
unsigned int i = 0; i < ImageDimension; i++ )
516 unsigned int totalNumberOfSpans
517 = this->m_CurrentNumberOfControlPoints[i] - this->m_SplineOrder[i];
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 )
523 p[i] =
static_cast<RealType>( totalNumberOfSpans )
524 - this->m_BSplineEpsilon;
526 if( p[i] >= static_cast<RealType>( totalNumberOfSpans ) )
528 itkExceptionMacro(
"The reparameterized point component " << p[i]
529 <<
" is outside the corresponding parametric domain of [0, "
530 << totalNumberOfSpans <<
"]." );
535 for( Itw.GoToBegin(); !Itw.IsAtEnd(); ++Itw )
539 for(
unsigned int i = 0; i < ImageDimension; 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] )
548 B *= this->m_KernelOrder0->Evaluate( u );
553 B *= this->m_KernelOrder1->Evaluate( u );
558 B *= this->m_KernelOrder2->Evaluate( u );
563 B *= this->m_KernelOrder3->Evaluate( u );
568 B *= this->m_Kernel[i]->Evaluate( u );
577 for( Itp.GoToBegin(), Itw.GoToBegin(); !Itp.IsAtEnd(); ++Itp, ++Itw )
580 for(
unsigned int i = 0; i < ImageDimension; i++ )
582 idx[i] +=
static_cast<unsigned>( p[i] );
583 if( this->m_CloseDimension[i] )
585 idx[i] %= this->m_DeltaLatticePerThread[threadId]
586 ->GetLargestPossibleRegion().GetSize()[i];
591 this->m_OmegaLatticePerThread[threadId]->SetPixel( idx,
592 this->m_OmegaLatticePerThread[threadId]->GetPixel( idx ) + wc*t*t );
594 PointDataType data = this->m_InputPointData->GetElement( n );
595 data *= ( t / w2_sum );
597 data *= ( t * t * wc );
598 this->m_DeltaLatticePerThread[threadId]->SetPixel(
599 idx, this->m_DeltaLatticePerThread[threadId]->GetPixel( idx ) + data );
604 template <
class TInputPo
intSet,
class TOutputImage>
614 this->m_DeltaLatticePerThread[0],
615 this->m_DeltaLatticePerThread[0]->GetLargestPossibleRegion() );
617 this->m_OmegaLatticePerThread[0],
618 this->m_OmegaLatticePerThread[0]->GetLargestPossibleRegion() );
620 for(
int n = 1; n < this->GetNumberOfThreads(); n++ )
623 this->m_DeltaLatticePerThread[n],
624 this->m_DeltaLatticePerThread[n]->GetLargestPossibleRegion() );
626 this->m_OmegaLatticePerThread[n],
627 this->m_OmegaLatticePerThread[n]->GetLargestPossibleRegion() );
649 for(
unsigned int i = 0; i < ImageDimension; i++ )
651 if( this->m_CloseDimension[i] )
653 size[i] = this->m_CurrentNumberOfControlPoints[i]-this->m_SplineOrder[i];
657 size[i] = this->m_CurrentNumberOfControlPoints[i];
660 this->m_PhiLattice = PointDataImageType::New();
661 this->m_PhiLattice->SetRegions( size );
662 this->m_PhiLattice->Allocate();
663 this->m_PhiLattice->FillBuffer( 0.0 );
666 this->m_PhiLattice, this->m_PhiLattice->GetLargestPossibleRegion() );
669 !ItP.IsAtEnd(); ++ItP, ++ItO, ++ItD )
675 P = ItD.
Get() / ItO.Get();
676 for(
unsigned int i = 0; i < P.Size(); i++ )
678 if( vnl_math_isnan( P[i] ) || vnl_math_isinf( P[i] ) )
688 template <
class TInputPo
intSet,
class TOutputImage>
693 ArrayType NumberOfNewControlPoints = this->m_CurrentNumberOfControlPoints;
694 for(
unsigned int i = 0; i < ImageDimension; i++ )
696 if( this->m_CurrentLevel < this->m_NumberOfLevels[i] )
698 NumberOfNewControlPoints[i]
699 = 2*NumberOfNewControlPoints[i]-this->m_SplineOrder[i];
703 for(
unsigned int i = 0; i < ImageDimension; i++ )
705 if( this->m_CloseDimension[i] )
707 size[i] = NumberOfNewControlPoints[i] - this->m_SplineOrder[i];
711 size[i] = NumberOfNewControlPoints[i];
716 = PointDataImageType::New();
717 RefinedLattice->SetRegions( size );
718 RefinedLattice->Allocate();
721 RefinedLattice->FillBuffer( data );
733 for(
unsigned int i = 0; i < ImageDimension; i++ )
735 N *= ( this->m_SplineOrder[i] + 1 );
736 size_Psi[i] = this->m_SplineOrder[i] + 1;
740 It( RefinedLattice, RefinedLattice->GetLargestPossibleRegion() );
743 while( !It.IsAtEnd() )
746 for(
unsigned int i = 0; i < ImageDimension; i++ )
748 if( this->m_CurrentLevel < this->m_NumberOfLevels[i] )
750 idx_Psi[i] =
static_cast<unsigned int>( 0.5*idx[i] );
754 idx_Psi[i] =
static_cast<unsigned int>( idx[i] );
758 for(
unsigned int i = 0; i < ( 2 << (ImageDimension-1) ); i++ )
762 off = this->NumberToIndex( i, size );
764 bool OutOfBoundary =
false;
765 for(
unsigned int j = 0; j < ImageDimension; j++ )
767 tmp[j] = idx[j] + off[j];
768 if( tmp[j] >= static_cast<int>( NumberOfNewControlPoints[j] )
769 && !this->m_CloseDimension[j] )
771 OutOfBoundary =
true;
774 if( this->m_CloseDimension[j] )
776 tmp[j] %= RefinedLattice->GetLargestPossibleRegion().GetSize()[j];
784 for(
unsigned int j = 0; j < N; j++ )
786 off_Psi = this->NumberToIndex( j, size_Psi );
788 bool IsOutOfBoundary =
false;
789 for(
unsigned int k = 0; k < ImageDimension; k++ )
791 tmp_Psi[k] = idx_Psi[k] + off_Psi[k];
793 static_cast<int>( this->m_CurrentNumberOfControlPoints[k] )
794 && !this->m_CloseDimension[k] )
796 IsOutOfBoundary =
true;
799 if( this->m_CloseDimension[k] )
802 this->m_PsiLattice->GetLargestPossibleRegion().GetSize()[k];
805 if( IsOutOfBoundary )
810 for(
unsigned int k = 0; k < ImageDimension; k++ )
812 coeff *= this->m_RefinedLatticeCoefficients[k]( off[k], off_Psi[k] );
814 val = this->m_PsiLattice->GetPixel( tmp_Psi );
818 RefinedLattice->SetPixel( tmp, sum );
821 bool IsEvenIndex =
false;
822 while( !IsEvenIndex && !It.IsAtEnd() )
827 for(
unsigned int i = 0; i < ImageDimension; i++ )
838 typename ImageDuplicatorType::Pointer Duplicator = ImageDuplicatorType::New();
839 Duplicator->SetInputImage( RefinedLattice );
840 Duplicator->Update();
841 this->m_PsiLattice = Duplicator->GetOutput();
844 template <
class TInputPo
intSet,
class TOutputImage>
850 for(
unsigned int i = 0; i < ImageDimension; i++ )
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() );
858 for(
unsigned int j = 0; j < i; j++ )
860 size[j] = this->m_PhiLattice->GetLargestPossibleRegion().
GetSize()[j];
862 collapsedPhiLattices[i]->SetRegions( size );
863 collapsedPhiLattices[i]->Allocate();
865 collapsedPhiLattices[ImageDimension] = this->m_PhiLattice;
867 for(
unsigned int i = 0; i < ImageDimension; i++ )
869 if( this->m_CloseDimension[i] )
871 totalNumberOfSpans[i]
872 = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i];
876 totalNumberOfSpans[i]
877 = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i]
878 - this->m_SplineOrder[i];
885 = this->m_PhiLattice->GetLargestPossibleRegion().
GetIndex();
887 typename PointDataContainerType::ConstIterator ItIn;
889 ItIn = this->m_InputPointData->Begin();
890 while( ItIn != this->m_InputPointData->End() )
895 this->GetInput()->GetPoint( ItIn.Index(), &point );
897 for(
unsigned int i = 0; i < ImageDimension; i++ )
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 )
905 U[i] =
static_cast<RealType>( totalNumberOfSpans[i] )
906 - this->m_BSplineEpsilon;
908 if( U[i] >= static_cast<RealType>( totalNumberOfSpans[i] ) )
910 itkExceptionMacro(
"The collapse point component " << U[i]
911 <<
" is outside the corresponding parametric domain of [0, "
912 << totalNumberOfSpans[i] <<
"]." );
915 for(
int i = ImageDimension-1; i >= 0; i-- )
917 if( U[i] != currentU[i] )
919 for(
int j = i; j >= 0; j-- )
921 this->CollapsePhiLattice( collapsedPhiLattices[j+1],
922 collapsedPhiLattices[j], U[j], j );
928 this->m_OutputPointData->InsertElement( ItIn.Index(),
929 collapsedPhiLattices[0]->GetPixel( startPhiIndex ) );
934 template <
class TInputPo
intSet,
class TOutputImage>
940 It( this->GetOutput(), this->GetOutput()->GetBufferedRegion() );
945 this->EvaluateAtIndex( It.
GetIndex(), data );
950 template <
class TInputPo
intSet,
class TOutputImage>
956 for(
unsigned int i = 0; i < ImageDimension; i++ )
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() );
964 for(
unsigned int j = 0; j < i; j++ )
966 size[j] = this->m_PhiLattice->GetLargestPossibleRegion().
GetSize()[j];
968 collapsedPhiLattices[i]->SetRegions( size );
969 collapsedPhiLattices[i]->Allocate();
971 collapsedPhiLattices[ImageDimension] = this->m_PhiLattice;
973 for(
unsigned int i = 0; i < ImageDimension; i++ )
975 if( this->m_CloseDimension[i] )
977 totalNumberOfSpans[i]
978 = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i];
982 totalNumberOfSpans[i]
983 = this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i]
984 - this->m_SplineOrder[i];
990 typename ImageType::IndexType startIndex
991 = this->GetOutput()->GetRequestedRegion().GetIndex();
993 = this->m_PhiLattice->GetLargestPossibleRegion().
GetIndex();
996 It( this->GetOutput(), this->GetOutput()->GetRequestedRegion() );
999 typename ImageType::IndexType idx = It.
GetIndex();
1000 for(
unsigned int i = 0; i < ImageDimension; i++ )
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 )
1008 U[i] =
static_cast<RealType>( totalNumberOfSpans[i] )
1009 - this->m_BSplineEpsilon;
1011 if( U[i] >= static_cast<RealType>( totalNumberOfSpans[i] ) )
1013 itkExceptionMacro(
"The collapse point component " << U[i]
1014 <<
" is outside the corresponding parametric domain of [0, "
1015 << totalNumberOfSpans[i] <<
"]." );
1018 for(
int i = ImageDimension-1; i >= 0; i-- )
1020 if( U[i] != currentU[i] )
1022 for(
int j = i; j >= 0; j-- )
1024 this->CollapsePhiLattice( collapsedPhiLattices[j+1],
1025 collapsedPhiLattices[j], U[j], j );
1031 It.
Set( collapsedPhiLattices[0]->GetPixel( startPhiIndex ) );
1035 template <
class TInputPo
intSet,
class TOutputImage>
1044 for( It.GoToBegin(); !It.IsAtEnd(); ++It )
1049 for(
unsigned int i = 0; i < this->m_SplineOrder[dimension] + 1; i++ )
1051 idx[dimension] =
static_cast<unsigned int>( u ) + i;
1053 + 0.5*
static_cast<RealType>( this->m_SplineOrder[dimension] - 1 );
1055 switch( this->m_SplineOrder[dimension] )
1059 B = this->m_KernelOrder0->Evaluate( v );
1064 B = this->m_KernelOrder1->Evaluate( v );
1069 B = this->m_KernelOrder2->Evaluate( v );
1074 B = this->m_KernelOrder3->Evaluate( v );
1079 B = this->m_Kernel[dimension]->Evaluate( v );
1083 if( this->m_CloseDimension[dimension] )
1089 if(idx[dimension]>=0 && static_cast<typename PointDataImageType::RegionType::SizeValueType>(idx[dimension])<lattice->
GetLargestPossibleRegion().
GetSize()[dimension])
1090 data += ( lattice->
GetPixel( idx ) * B );
1096 template <
class TInputPo
intSet,
class TOutputImage>
1101 for(
unsigned int i = 0; i < ImageDimension; i++)
1103 point[i] -= this->m_Origin[i];
1105 (
static_cast<RealType>( this->m_Size[i] - 1 ) * this->m_Spacing[i] );
1107 this->Evaluate( point, data );
1110 template <
class TInputPo
intSet,
class TOutputImage>
1116 this->GetOutput()->TransformIndexToPhysicalPoint( idx, point );
1117 this->EvaluateAtPoint( point, data );
1120 template <
class TInputPo
intSet,
class TOutputImage>
1126 this->GetOutput()->TransformContinuousIndexToPhysicalPoint( idx, point );
1127 this->EvaluateAtPoint( point, data );
1130 template <
class TInputPo
intSet,
class TOutputImage>
1135 vnl_vector<RealType> p( ImageDimension );
1136 for(
unsigned int i = 0; i < ImageDimension; i++ )
1142 if( params[i] < 0.0 || params[i] >= 1.0 )
1144 itkExceptionMacro(
"The specified point " << params
1145 <<
" is outside the reparameterized domain [0, 1]." );
1147 p[i] =
static_cast<RealType>( params[i] )
1148 * static_cast<RealType>( this->m_CurrentNumberOfControlPoints[i]
1149 - this->m_SplineOrder[i] );
1153 for(
unsigned int i = 0; i < ImageDimension; i++ )
1155 size[i] = this->m_SplineOrder[i] + 1;
1158 w = RealImageType::New();
1159 w->SetRegions( size );
1166 Itw( w, w->GetLargestPossibleRegion() );
1168 for( Itw.GoToBegin(); !Itw.IsAtEnd(); ++Itw )
1172 for(
unsigned int i = 0; i < ImageDimension; i++ )
1175 + idx[i] ) + 0.5*
static_cast<RealType>( this->m_SplineOrder[i] - 1 );
1176 switch( this->m_SplineOrder[i] )
1180 B *= this->m_KernelOrder0->Evaluate( u );
1185 B *= this->m_KernelOrder1->Evaluate( u );
1190 B *= this->m_KernelOrder2->Evaluate( u );
1195 B *= this->m_KernelOrder3->Evaluate( u );
1200 B *= this->m_Kernel[i]->Evaluate( u );
1205 for(
unsigned int i = 0; i < ImageDimension; i++ )
1207 idx[i] +=
static_cast<unsigned int>( p[i] );
1208 if( this->m_CloseDimension[i] )
1210 idx[i] %= this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i];
1213 if( this->m_PhiLattice->GetLargestPossibleRegion().IsInside( idx ) )
1215 val = this->m_PhiLattice->GetPixel( idx );
1222 template <
class TInputPo
intSet,
class TOutputImage>
1227 for(
unsigned int i = 0; i < ImageDimension; i++)
1229 point[i] -= this->m_Origin[i];
1231 (
static_cast<RealType>( this->m_Size[i] - 1 ) * this->m_Spacing[i] );
1233 this->EvaluateGradient( point, gradient );
1236 template <
class TInputPo
intSet,
class TOutputImage>
1242 this->GetOutput()->TransformIndexToPhysicalPoint( idx, point );
1243 this->EvaluateGradientAtPoint( point, gradient );
1246 template <
class TInputPo
intSet,
class TOutputImage>
1253 this->GetOutput()->TransformContinuousIndexToPhysicalPoint( idx, gradient );
1254 this->EvaluateGradientAtPoint( point, gradient );
1257 template <
class TInputPo
intSet,
class TOutputImage>
1262 vnl_vector<RealType> p( ImageDimension );
1263 for(
unsigned int i = 0; i < ImageDimension; i++ )
1269 if( params[i] < 0.0 || params[i] >= 1.0 )
1271 itkExceptionMacro(
"The specified point " << params
1272 <<
" is outside the reparameterized domain [0, 1]." );
1274 p[i] =
static_cast<RealType>( params[i] )
1275 * static_cast<RealType>( this->m_CurrentNumberOfControlPoints[i]
1276 - this->m_SplineOrder[i] );
1280 for(
unsigned int i = 0; i < ImageDimension; i++ )
1282 size[i] = this->m_SplineOrder[i] + 1;
1285 w = RealImageType::New();
1286 w->SetRegions( size );
1290 gradient.
SetSize( val.Size(), ImageDimension );
1291 gradient.
Fill( 0.0 );
1294 Itw( w, w->GetLargestPossibleRegion() );
1296 for(
unsigned int j = 0; j < gradient.
Cols(); j++ )
1298 for( Itw.GoToBegin(); !Itw.IsAtEnd(); ++Itw )
1302 for(
unsigned int i = 0; i < ImageDimension; i++ )
1305 + idx[i] ) + 0.5*
static_cast<RealType>( this->m_SplineOrder[i] - 1 );
1308 B *= this->m_Kernel[i]->EvaluateDerivative( u );
1312 B *= this->m_Kernel[i]->Evaluate( u );
1315 for(
unsigned int i = 0; i < ImageDimension; i++ )
1317 idx[i] +=
static_cast<unsigned int>( p[i] );
1318 if( this->m_CloseDimension[i] )
1320 idx[i] %= this->m_PhiLattice->GetLargestPossibleRegion().GetSize()[i];
1323 if( this->m_PhiLattice->GetLargestPossibleRegion().IsInside( idx ) )
1325 val = this->m_PhiLattice->GetPixel( idx );
1327 for(
unsigned int i = 0; i < val.Size(); i++ )
1329 gradient( i, j ) += val[i];
1339 template <
class TInputPo
intSet,
class TOutputImage>
1346 Superclass::PrintSelf( os, indent );
1347 for(
unsigned int i = 0; i < ImageDimension; i++ )
1349 this->m_Kernel[i]->Print( os, indent );
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;