[5d12a0]: / src / invertDisplacementField.cxx

Download this file

143 lines (116 with data), 5.6 kB

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
#include <nanobind/nanobind.h>
#include <nanobind/stl/vector.h>
#include <nanobind/stl/string.h>
#include <nanobind/stl/tuple.h>
#include <nanobind/stl/list.h>
#include <nanobind/ndarray.h>
#include <nanobind/stl/shared_ptr.h>
#include <exception>
#include <vector>
#include <string>
#include "itkImage.h"
#include "itkVector.h"
#include "itkInvertDisplacementFieldImageFilter.h"
#include "itkImageRegionIteratorWithIndex.h"
#include "itkImageRegionConstIteratorWithIndex.h"
#include "antsImage.h"
namespace nb = nanobind;
using namespace nb::literals;
template <unsigned int Dimension>
AntsImage<itk::VectorImage<float, Dimension>> invertDisplacementField( AntsImage<itk::VectorImage<float, Dimension>> & antsDisplacementField,
AntsImage<itk::VectorImage<float, Dimension>> & antsInverseFieldInitialEstimate,
unsigned int maximumNumberOfIterations,
float meanErrorToleranceThreshold,
float maxErrorToleranceThreshold,
bool enforceBoundaryCondition )
{
using RealType = float;
using ANTsFieldType = itk::VectorImage<RealType, Dimension>;
using ANTsFieldPointerType = typename ANTsFieldType::Pointer;
using VectorType = itk::Vector<RealType, Dimension>;
using ITKFieldType = itk::Image<VectorType, Dimension>;
using ITKFieldPointerType = typename ITKFieldType::Pointer;
using IteratorType = itk::ImageRegionIteratorWithIndex<ITKFieldType>;
using ConstIteratorType = itk::ImageRegionConstIteratorWithIndex<ITKFieldType>;
ANTsFieldPointerType inputDisplacementField = antsDisplacementField.ptr;
ANTsFieldPointerType inputInverseFieldInitialEstimate = antsInverseFieldInitialEstimate.ptr;
typename ITKFieldType::PointType fieldOrigin;
typename ITKFieldType::SpacingType fieldSpacing;
typename ITKFieldType::SizeType fieldSize;
typename ITKFieldType::DirectionType fieldDirection;
for( unsigned int d = 0; d < Dimension; d++ )
{
fieldOrigin[d] = inputDisplacementField->GetOrigin()[d];
fieldSpacing[d] = inputDisplacementField->GetSpacing()[d];
fieldSize[d] = inputDisplacementField->GetRequestedRegion().GetSize()[d];
for( unsigned int e = 0; e < Dimension; e++ )
{
fieldDirection(d, e) = inputDisplacementField->GetDirection()(d, e);
}
}
ITKFieldPointerType inputITKDisplacementField = ITKFieldType::New();
inputITKDisplacementField->SetOrigin( fieldOrigin );
inputITKDisplacementField->SetRegions( fieldSize );
inputITKDisplacementField->SetSpacing( fieldSpacing );
inputITKDisplacementField->SetDirection( fieldDirection );
inputITKDisplacementField->AllocateInitialized();
ITKFieldPointerType inputITKInverseFieldInitialEstimate = ITKFieldType::New();
inputITKInverseFieldInitialEstimate->SetOrigin( fieldOrigin );
inputITKInverseFieldInitialEstimate->SetRegions( fieldSize );
inputITKInverseFieldInitialEstimate->SetSpacing( fieldSpacing );
inputITKInverseFieldInitialEstimate->SetDirection( fieldDirection );
inputITKInverseFieldInitialEstimate->AllocateInitialized();
IteratorType ItF( inputITKDisplacementField, inputITKDisplacementField->GetRequestedRegion() );
IteratorType ItE( inputITKInverseFieldInitialEstimate, inputITKInverseFieldInitialEstimate->GetRequestedRegion() );
for( ItF.GoToBegin(), ItE.GoToBegin(); !ItF.IsAtEnd(); ++ItF, ++ItE )
{
VectorType vectorF;
VectorType vectorE;
typename ANTsFieldType::PixelType antsVectorF = inputDisplacementField->GetPixel( ItF.GetIndex() );
typename ANTsFieldType::PixelType antsVectorE = inputInverseFieldInitialEstimate->GetPixel( ItE.GetIndex() );
for( unsigned int d = 0; d < Dimension; d++ )
{
vectorF[d] = antsVectorF[d];
vectorE[d] = antsVectorE[d];
}
ItF.Set( vectorF );
ItE.Set( vectorE );
}
using InverterType = itk::InvertDisplacementFieldImageFilter<ITKFieldType>;
typename InverterType::Pointer inverter = InverterType::New();
inverter->SetInput( inputITKDisplacementField );
inverter->SetInverseFieldInitialEstimate( inputITKInverseFieldInitialEstimate );
inverter->SetMaximumNumberOfIterations( maximumNumberOfIterations );
inverter->SetMeanErrorToleranceThreshold( meanErrorToleranceThreshold );
inverter->SetMaxErrorToleranceThreshold( maxErrorToleranceThreshold );
inverter->SetEnforceBoundaryCondition( enforceBoundaryCondition );
inverter->Update();
//////////////////////////
//
// Now convert back to vector image type.
//
ANTsFieldPointerType antsField = ANTsFieldType::New();
antsField->CopyInformation( inverter->GetOutput() );
antsField->SetRegions( inverter->GetOutput()->GetRequestedRegion() );
antsField->SetVectorLength( Dimension );
antsField->AllocateInitialized();
ConstIteratorType ItI( inverter->GetOutput(),
inverter->GetOutput()->GetRequestedRegion() );
for( ItI.GoToBegin(), ItF.GoToBegin(); !ItI.IsAtEnd(); ++ItI, ++ItF )
{
VectorType data = ItI.Value();
typename ANTsFieldType::PixelType antsVector( Dimension );
for( unsigned int d = 0; d < Dimension; d++ )
{
antsVector[d] = data[d];
}
antsField->SetPixel( ItI.GetIndex(), antsVector );
}
AntsImage<ANTsFieldType> out_ants_image = { antsField };
return out_ants_image;
}
void local_invertDisplacementField(nb::module_ &m)
{
m.def("invertDisplacementFieldD2", &invertDisplacementField<2>);
m.def("invertDisplacementFieldD3", &invertDisplacementField<3>);
}