#ifndef _rpiDisplacementFieldTransform_cxx_ #define _rpiDisplacementFieldTransform_cxx_ #include "rpiDisplacementFieldTransform.h" #include "itkNeighborhoodAlgorithm.h" #include "itkImageRegionIterator.h" #include "vnl/vnl_det.h" #include #include "itkFixedPointInverseDisplacementFieldImageFilter.h" namespace rpi { template DisplacementFieldTransform:: DisplacementFieldTransform() : Superclass( ParametersDimension ) { this->m_InterpolateFunction = InterpolateFunctionType::New(); } template void DisplacementFieldTransform:: SetIdentity(void) { itk::Vector value; value.Fill(0); VectorFieldPointerType field = VectorFieldType::New(); field->Allocate(); field->FillBuffer(value); field->Register(); this->m_VectorField = field; } template void DisplacementFieldTransform:: PrintSelf(std::ostream &os, itk::Indent indent) const { Superclass::PrintSelf(os,indent); } template const typename DisplacementFieldTransform::VectorFieldType * DisplacementFieldTransform:: GetParametersAsVectorField(void) const { return this->m_VectorField.GetPointer(); } template void DisplacementFieldTransform:: SetParametersAsVectorField(const VectorFieldType * field) { // Set displacement field and affect it to the interpolate object this->m_VectorField = field; this->m_InterpolateFunction->SetInputImage(this->m_VectorField); // Compute the derivative weights itk::Vector spacing = GetSpacing(); for (unsigned int i=0; iModified(); } template bool DisplacementFieldTransform:: GetInverse( Self* inverse ) const { // Initial field VectorFieldConstPointerType initial_field = this->m_VectorField;//GetParametersAsVectorField(); // Initialize the field inverter typedef itk::FixedPointInverseDisplacementFieldImageFilter FPInverseType; typename FPInverseType::Pointer filter = FPInverseType::New(); filter->SetInput( initial_field ); filter->SetOutputOrigin( initial_field->GetOrigin() ); filter->SetSize( initial_field->GetLargestPossibleRegion().GetSize() ); filter->SetOutputSpacing( initial_field->GetSpacing() ); filter->SetNumberOfIterations( 20 ); // Update the filter filter->UpdateLargestPossibleRegion(); // Get the inverted field and set the orientation that has been lost VectorFieldPointerType inverted_field = filter->GetOutput(); inverted_field->SetDirection( initial_field->GetDirection() ); // Set the displacement field to the current objet inverse->SetParametersAsVectorField( inverted_field ); return true; } template typename DisplacementFieldTransform::InverseTransformBasePointer DisplacementFieldTransform:: GetInverseTransform() const { Pointer inv = New(); return GetInverse(inv) ? inv.GetPointer() : NULL; } template typename DisplacementFieldTransform::OutputPointType DisplacementFieldTransform:: TransformPoint(const InputPointType & point) const { if (this->m_VectorField.IsNull()) itkExceptionMacro("No field has been set."); OutputPointType output = point; typename InterpolateFunctionType::OutputType vector = m_InterpolateFunction->Evaluate(output); for (unsigned int i=0; i typename DisplacementFieldTransform::OutputVectorType DisplacementFieldTransform:: TransformVector(const InputVectorType & vector) const { // Convert vector into point InputPointType point_0; for (unsigned int i=0; i typename DisplacementFieldTransform::OutputVnlVectorType DisplacementFieldTransform:: TransformVector(const InputVnlVectorType & vector) const { // Convert vector into point InputPointType point_0; for (unsigned int i=0; i typename DisplacementFieldTransform::OriginType DisplacementFieldTransform:: GetOrigin(void) { if (this->m_VectorField.IsNull()) itkExceptionMacro("No field has been set."); return this->m_VectorField->GetOrigin(); } template typename DisplacementFieldTransform::SpacingType DisplacementFieldTransform:: GetSpacing(void) { if (this->m_VectorField.IsNull()) itkExceptionMacro("No field has been set."); return this->m_VectorField->GetSpacing(); } template typename DisplacementFieldTransform::DirectionType DisplacementFieldTransform:: GetDirection(void) { if (this->m_VectorField.IsNull()) itkExceptionMacro("No field has been set."); return this->m_VectorField->GetDirection(); } template typename DisplacementFieldTransform::RegionType DisplacementFieldTransform:: GetLargestPossibleRegion(void) { if (this->m_VectorField.IsNull()) itkExceptionMacro("No field has been set."); return this->m_VectorField->GetLargestPossibleRegion(); } template vnl_matrix_fixed DisplacementFieldTransform:: GetSpatialJacobian( const InputPointType & point) const { unsigned int i, j; vnl_matrix_fixed J; if (!this->m_VectorField) itkExceptionMacro("No field has been set, cannot compute Jacobian !"); double weight; itk::Vector spacing = m_VectorField->GetSpacing(); InputPointType point_prev, point_next; for (i = 0; i < NDimensions; ++i) { point_prev[i] = static_cast(point[i]) - spacing[i]; point_next[i] = static_cast(point[i]) + spacing[i]; } typename InterpolateFunctionType::OutputType vector_prev = m_InterpolateFunction->Evaluate(point_prev); typename InterpolateFunctionType::OutputType vector_next = m_InterpolateFunction->Evaluate(point_next); for (i = 0; i < NDimensions; ++i) { weight = 0.5 * m_DerivativeWeights[i]; for (j = 0; j < NDimensions; ++j) J[i][j] = weight * ( static_cast(vector_next[j]) - static_cast(vector_prev[j]) ); // Add one on the diagonal to consider the warp and not only the deformation field J[i][i] += 1.0; } return J; } template typename DisplacementFieldTransform::ScalarType DisplacementFieldTransform< TScalarType, NDimensions >:: GetSpatialJacobianDeterminant( const InputPointType & point) const { return static_cast(vnl_det(this->GetSpatialJacobian(point))); } } // namespace #endif // _itkDisplacementFieldTransform_cxx_