17 #ifndef __itkBSplineDeformableTransform_txx
18 #define __itkBSplineDeformableTransform_txx
31 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
37 m_WeightsFunction = WeightsFunctionType::New();
38 m_SupportSize = m_WeightsFunction->GetSupportSize();
42 typename IdentityTransformType::Pointer
id = IdentityTransformType::New();
47 typename RegionType::IndexType index;
50 m_GridRegion.SetSize( size );
51 m_GridRegion.SetIndex( index );
53 m_GridOrigin.Fill( 0.0 );
54 m_GridSpacing.Fill( 1.0 );
55 m_GridDirection.SetIdentity();
59 m_InputParametersPointer = &m_InternalParametersBuffer;
62 for (
unsigned int j = 0; j < SpaceDimension; j++ )
64 m_WrappedImage[j] = ImageType::New();
65 m_WrappedImage[j]->SetRegions( m_GridRegion );
66 m_WrappedImage[j]->SetOrigin( m_GridOrigin.GetDataPointer() );
67 m_WrappedImage[j]->SetSpacing( m_GridSpacing.GetDataPointer() );
68 m_WrappedImage[j]->SetDirection( m_GridDirection );
69 m_CoefficientImage[j] =
NULL;
73 m_Offset = SplineOrder / 2;
74 if ( SplineOrder % 2 )
76 m_SplineOrderOdd =
true;
80 m_SplineOrderOdd =
false;
82 m_ValidRegion = m_GridRegion;
85 for (
unsigned int j = 0; j < SpaceDimension; j++ )
87 m_JacobianImage[j] = ImageType::New();
88 m_JacobianImage[j]->SetRegions( m_GridRegion );
89 m_JacobianImage[j]->SetOrigin( m_GridOrigin.GetDataPointer() );
90 m_JacobianImage[j]->SetSpacing( m_GridSpacing.GetDataPointer() );
91 m_JacobianImage[j]->SetDirection( m_GridDirection );
101 this->m_FixedParameters.SetSize ( NDimensions * (NDimensions + 3) );
102 this->m_FixedParameters.Fill ( 0.0 );
103 for (
unsigned int i=0; i<NDimensions; i++)
105 this->m_FixedParameters[2*NDimensions+i] = m_GridSpacing[i];
107 for (
unsigned int di=0; di<NDimensions; di++)
109 for (
unsigned int dj=0; dj<NDimensions; dj++)
111 this->m_FixedParameters[3*NDimensions+(di*NDimensions+dj)] = m_GridDirection[di][dj];
116 for(
unsigned int i=0; i<SpaceDimension; i++)
118 scale[i][i] = m_GridSpacing[i];
121 m_IndexToPoint = m_GridDirection * scale;
122 m_PointToIndex = m_IndexToPoint.GetInverse();
125 m_LastJacobianIndex = m_ValidRegion.GetIndex();
131 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
141 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
158 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
166 copyPtr->m_BulkTransform = this->GetBulkTransform();
168 smartPtr =
static_cast<Pointer>(copyPtr);
174 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
182 return ( static_cast<unsigned int>( SpaceDimension ) *
183 static_cast<unsigned int>( m_GridRegion.GetNumberOfPixels() ) );
189 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
196 return ( static_cast<unsigned int>( m_GridRegion.GetNumberOfPixels() ) );
202 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
207 if ( m_GridRegion != region )
210 m_GridRegion = region;
213 for (
unsigned int j = 0; j < SpaceDimension; j++ )
215 m_WrappedImage[j]->SetRegions( m_GridRegion );
216 m_JacobianImage[j]->SetRegions( m_GridRegion );
229 typename RegionType::IndexType index = m_GridRegion.GetIndex();
230 for (
unsigned int j = 0; j < SpaceDimension; j++ )
234 m_ValidRegionFirst[j] = index[j];
238 m_ValidRegion.SetIndex( index );
245 if (m_InputParametersPointer == &m_InternalParametersBuffer)
248 if ( m_InternalParametersBuffer.GetSize() != this->GetNumberOfParameters() )
250 m_InternalParametersBuffer.SetSize( this->GetNumberOfParameters() );
252 m_InternalParametersBuffer.Fill( 0 );
262 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
267 if ( m_GridSpacing != spacing )
269 m_GridSpacing = spacing;
272 for (
unsigned int j = 0; j < SpaceDimension; j++ )
274 m_WrappedImage[j]->SetSpacing( m_GridSpacing.GetDataPointer() );
275 m_JacobianImage[j]->SetSpacing( m_GridSpacing.GetDataPointer() );
279 for(
unsigned int i=0; i<SpaceDimension; i++)
281 scale[i][i] = m_GridSpacing[i];
284 m_IndexToPoint = m_GridDirection * scale;
285 m_PointToIndex = m_IndexToPoint.GetInverse();
293 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
298 if ( m_GridDirection != direction )
300 m_GridDirection = direction;
303 for (
unsigned int j = 0; j < SpaceDimension; j++ )
305 m_WrappedImage[j]->SetDirection( m_GridDirection );
306 m_JacobianImage[j]->SetDirection( m_GridDirection );
310 for(
unsigned int i=0; i<SpaceDimension; i++)
312 scale[i][i] = m_GridSpacing[i];
315 m_IndexToPoint = m_GridDirection * scale;
316 m_PointToIndex = m_IndexToPoint.GetInverse();
325 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
330 if ( m_GridOrigin != origin )
332 m_GridOrigin = origin;
335 for (
unsigned int j = 0; j < SpaceDimension; j++ )
337 m_WrappedImage[j]->SetOrigin( m_GridOrigin.GetDataPointer() );
338 m_JacobianImage[j]->SetOrigin( m_GridOrigin.GetDataPointer() );
348 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
353 if( m_InputParametersPointer )
357 parameters->Fill( 0.0 );
362 itkExceptionMacro( <<
"Input parameters for the spline haven't been set ! "
363 <<
"Set them using the SetParameters or SetCoefficientImage method first." );
368 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
376 if ( parameters.Size() != this->GetNumberOfParameters() )
378 itkExceptionMacro(<<
"Mismatch between parameters size "
380 <<
" and expected number of parameters "
381 << this->GetNumberOfParameters()
382 << (m_GridRegion.GetNumberOfPixels() == 0 ?
383 ". \nSince the size of the grid region is 0, perhaps you forgot to SetGridRegion or SetFixedParameters before setting the Parameters." :
""));
390 m_InputParametersPointer = ¶meters;
393 this->WrapAsImages();
401 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
411 if ( passedParameters.Size() == NDimensions * 3 )
413 parameters.Fill( 0.0 );
414 for(
unsigned int i=0; i<3 * NDimensions; i++)
416 parameters[i] = passedParameters[i];
418 for (
unsigned int di=0; di<NDimensions; di++)
420 parameters[3*NDimensions+(di*NDimensions+di)] = 1;
423 else if ( passedParameters.Size() != NDimensions * (3 + NDimensions) )
425 itkExceptionMacro(<<
"Mismatched between parameters size "
426 << passedParameters.size()
427 <<
" and number of fixed parameters "
428 << NDimensions * (3 + NDimensions) );
432 for(
unsigned int i=0; i<NDimensions * (3 + NDimensions); i++)
434 parameters[i] = passedParameters[i];
449 for (
unsigned int i=0; i<NDimensions; i++)
451 gridSize[i] =
static_cast<int> (parameters[i]);
454 bsplineRegion.
SetSize( gridSize );
458 for (
unsigned int i=0; i<NDimensions; i++)
460 origin[i] = parameters[NDimensions+i];
465 for (
unsigned int i=0; i<NDimensions; i++)
467 spacing[i] = parameters[2*NDimensions+i];
472 for (
unsigned int di=0; di<NDimensions; di++)
474 for (
unsigned int dj=0; dj<NDimensions; dj++)
476 direction[di][dj] = parameters[3*NDimensions+(di*NDimensions+dj)];
481 this->SetGridSpacing( spacing );
482 this->SetGridDirection( direction );
483 this->SetGridOrigin( origin );
484 this->SetGridRegion( bsplineRegion );
491 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
503 const_cast<PixelType *
>(( m_InputParametersPointer->data_block() ));
504 unsigned int numberOfPixels = m_GridRegion.GetNumberOfPixels();
506 for (
unsigned int j = 0; j < SpaceDimension; j++ )
508 m_WrappedImage[j]->GetPixelContainer()->
509 SetImportPointer( dataPointer, numberOfPixels );
510 dataPointer += numberOfPixels;
511 m_CoefficientImage[j] = m_WrappedImage[j];
518 this->m_Jacobian.set_size( SpaceDimension, this->GetNumberOfParameters() );
519 this->m_Jacobian.Fill( NumericTraits<JacobianPixelType>::Zero );
520 m_LastJacobianIndex = m_ValidRegion.GetIndex();
523 for (
unsigned int j = 0; j < SpaceDimension; j++ )
525 m_JacobianImage[j]->GetPixelContainer()->
526 SetImportPointer( jacobianDataPointer, numberOfPixels );
527 jacobianDataPointer += this->GetNumberOfParameters() + numberOfPixels;
533 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
541 if ( parameters.Size() != this->GetNumberOfParameters() )
543 itkExceptionMacro(<<
"Mismatched between parameters size "
545 <<
" and region size "
546 << m_GridRegion.GetNumberOfPixels() );
550 m_InternalParametersBuffer = parameters;
551 m_InputParametersPointer = &m_InternalParametersBuffer;
554 this->WrapAsImages();
563 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
573 if (
NULL == m_InputParametersPointer)
575 itkExceptionMacro( <<
"Cannot GetParameters() because m_InputParametersPointer is NULL. Perhaps SetCoefficientImage() has been called causing the NULL pointer." );
578 return (*m_InputParametersPointer);
583 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
590 RegionType resRegion = this->GetGridRegion( );
592 for (
unsigned int i=0; i<NDimensions; i++)
594 this->m_FixedParameters[i] = (resRegion.
GetSize())[i];
596 for (
unsigned int i=0; i<NDimensions; i++)
598 this->m_FixedParameters[NDimensions+i] = (this->GetGridOrigin())[i];
600 for (
unsigned int i=0; i<NDimensions; i++)
602 this->m_FixedParameters[2*NDimensions+i] = (this->GetGridSpacing())[i];
604 for (
unsigned int di=0; di<NDimensions; di++)
606 for (
unsigned int dj=0; dj<NDimensions; dj++)
608 this->m_FixedParameters[3*NDimensions+(di*NDimensions+dj)] = (this->GetGridDirection())[di][dj];
612 return (this->m_FixedParameters);
617 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
624 this->SetGridRegion( images[0]->GetBufferedRegion() );
625 this->SetGridOrigin( images[0]->GetOrigin() );
626 this->SetGridSpacing( images[0]->GetSpacing() );
627 this->SetGridDirection( images[0]->GetDirection() );
629 for(
unsigned int j = 0; j < SpaceDimension; j++ )
631 m_CoefficientImage[j] = images[j];
636 m_InputParametersPointer =
NULL;
643 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
651 this->Superclass::PrintSelf(os, indent);
653 os << indent <<
"GridRegion: " << m_GridRegion << std::endl;
654 os << indent <<
"GridOrigin: " << m_GridOrigin << std::endl;
655 os << indent <<
"GridSpacing: " << m_GridSpacing << std::endl;
656 os << indent <<
"GridDirection: " << m_GridDirection << std::endl;
657 os << indent <<
"IndexToPoint: " << m_IndexToPoint << std::endl;
658 os << indent <<
"PointToIndex: " << m_PointToIndex << std::endl;
660 os << indent <<
"CoefficientImage: [ ";
661 for ( j = 0; j < SpaceDimension - 1; j++ )
663 os << m_CoefficientImage[j].GetPointer() <<
", ";
665 os << m_CoefficientImage[j].GetPointer() <<
" ]" << std::endl;
667 os << indent <<
"WrappedImage: [ ";
668 for ( j = 0; j < SpaceDimension - 1; j++ )
670 os << m_WrappedImage[j].GetPointer() <<
", ";
672 os << m_WrappedImage[j].GetPointer() <<
" ]" << std::endl;
674 os << indent <<
"InputParametersPointer: "
675 << m_InputParametersPointer << std::endl;
676 os << indent <<
"ValidRegion: " << m_ValidRegion << std::endl;
677 os << indent <<
"LastJacobianIndex: " << m_LastJacobianIndex << std::endl;
678 os << indent <<
"BulkTransform: ";
679 os << m_BulkTransform.GetPointer() << std::endl;
680 os << indent <<
"WeightsFunction: ";
681 os << m_WeightsFunction.GetPointer() << std::endl;
683 if ( m_BulkTransform )
685 os << indent <<
"BulkTransformType: "
692 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
700 #ifndef ITK_USE_CENTERED_PIXEL_COORDINATES_CONSISTENTLY
701 if( !m_ValidRegion.IsInside( index ) )
707 if ( inside && m_SplineOrderOdd )
710 for(
unsigned int j = 0; j < SpaceDimension; j++ )
712 if ( index[j] >= static_cast<ValueType>( m_ValidRegionLast[j] ) )
717 #ifdef ITK_USE_CENTERED_PIXEL_COORDINATES_CONSISTENTLY
718 if ( index[j] < static_cast<ValueType>( m_ValidRegionFirst[j] ) )
731 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
747 if ( m_BulkTransform )
749 transformedPoint = m_BulkTransform->TransformPoint( point );
753 transformedPoint = point;
756 if ( m_CoefficientImage[0] )
760 this->TransformPointToContinuousIndex( point, index );
764 inside = this->InsideValidRegion( index );
767 outputPoint = transformedPoint;
772 m_WeightsFunction->Evaluate( index, weights, supportIndex );
776 supportRegion.
SetSize( m_SupportSize );
777 supportRegion.
SetIndex( supportIndex );
779 outputPoint.
Fill( NumericTraits<ScalarType>::Zero );
782 IteratorType m_Iterator[ SpaceDimension ];
783 unsigned long counter = 0;
784 const PixelType * basePointer = m_CoefficientImage[0]->GetBufferPointer();
786 for ( j = 0; j < SpaceDimension; j++ )
788 m_Iterator[j] = IteratorType( m_CoefficientImage[j], supportRegion );
791 while ( ! m_Iterator[0].IsAtEnd() )
795 for ( j = 0; j < SpaceDimension; j++ )
798 weights[counter] * m_Iterator[j].Get());
802 indices[counter] = &(m_Iterator[0].Value()) - basePointer;
806 for ( j = 0; j < SpaceDimension; j++ )
813 for ( j = 0; j < SpaceDimension; j++ )
815 outputPoint[j] += transformedPoint[j];
822 itkWarningMacro( <<
"B-spline coefficients have not been set" );
824 for ( j = 0; j < SpaceDimension; j++ )
826 outputPoint[j] = transformedPoint[j];
834 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
841 WeightsType weights( m_WeightsFunction->GetNumberOfWeights() );
846 this->TransformPoint( point, outputPoint, weights, indices, inside );
854 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
863 if( m_InputParametersPointer ==
NULL )
865 itkExceptionMacro( <<
"Cannot compute Jacobian: parameters not set" );
872 supportRegion.
SetSize( m_SupportSize );
873 supportRegion.
SetIndex( m_LastJacobianIndex );
876 IteratorType m_Iterator[ SpaceDimension ];
879 for ( j = 0; j < SpaceDimension; j++ )
881 m_Iterator[j] = IteratorType( m_JacobianImage[j], supportRegion );
884 while ( ! m_Iterator[0].IsAtEnd() )
888 for ( j = 0; j < SpaceDimension; j++ )
890 m_Iterator[j].Set( NumericTraits<JacobianPixelType>::Zero );
893 for ( j = 0; j < SpaceDimension; j++ )
902 this->TransformPointToContinuousIndex( point, index );
906 if ( !this->InsideValidRegion( index ) )
908 return this->m_Jacobian;
912 WeightsType weights( m_WeightsFunction->GetNumberOfWeights() );
915 m_WeightsFunction->Evaluate( index, weights, supportIndex );
916 m_LastJacobianIndex = supportIndex;
919 supportRegion.
SetIndex( supportIndex );
920 unsigned long counter = 0;
922 for ( j = 0; j < SpaceDimension; j++ )
924 m_Iterator[j] = IteratorType( m_JacobianImage[j], supportRegion );
927 while ( ! m_Iterator[0].IsAtEnd() )
931 for ( j = 0; j < SpaceDimension; j++ )
933 m_Iterator[j].Set( static_cast<JacobianPixelType>( weights[counter] ) );
938 for ( j = 0; j < SpaceDimension; j++ )
946 return this->m_Jacobian;
952 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
959 supportRegion.
SetSize( m_SupportSize );
960 const PixelType * basePointer = m_CoefficientImage[0]->GetBufferPointer();
964 this->TransformPointToContinuousIndex( point, index );
968 if ( !this->InsideValidRegion( index ) )
978 m_WeightsFunction->Evaluate( index, weights, supportIndex );
981 supportRegion.
SetIndex( supportIndex );
982 unsigned long counter = 0;
986 IteratorType m_Iterator = IteratorType( m_CoefficientImage[0], supportRegion );
989 while ( ! m_Iterator.IsAtEnd() )
993 indexes[counter] = &(m_Iterator.Value()) - basePointer;
1004 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
1013 for ( j = 0; j < SpaceDimension; j++ )
1015 tvector[j] = point[j] - this->m_GridOrigin[j];
1020 cvector = m_PointToIndex * tvector;
1022 for ( j = 0; j < SpaceDimension; j++ )
1029 template<
class TScalarType,
unsigned int NDimensions,
unsigned int VSplineOrder>
1034 return m_WeightsFunction->GetNumberOfWeights();