ANIMA  4.0
animaKissingSymmetricBMRegistrationMethod.hxx
Go to the documentation of this file.
1 #pragma once
3 
6 
7 #include <itkMultiplyImageFilter.h>
8 #include <itkSubtractImageFilter.h>
9 
10 namespace anima
11 {
12 
13 template <typename TInputImageType>
14 void
15 KissingSymmetricBMRegistrationMethod <TInputImageType>
16 ::PerformOneIteration(InputImageType *refImage, InputImageType *movingImage, TransformPointer &addOn)
17 {
18  itk::TimeProbe tmpTime;
19  tmpTime.Start();
20 
21  this->GetBlockMatcher()->SetForceComputeBlocks(true);
22  this->GetBlockMatcher()->SetReferenceImage(refImage);
23  this->GetBlockMatcher()->SetMovingImage(movingImage);
24 
25  this->ChangeDefaultBackgroundValue(refImage, m_FloatingBackgroundValue);
26  this->GetBlockMatcher()->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
27  this->GetBlockMatcher()->Update();
28 
29  tmpTime.Stop();
30 
31  if (this->GetVerboseProgression())
32  std::cout << "Matching performed in " << tmpTime.GetTotal() << std::endl;
33 
34  this->GetAgregator()->SetInputRegions(this->GetBlockMatcher()->GetBlockRegions());
35  this->GetAgregator()->SetInputOrigins(this->GetBlockMatcher()->GetBlockPositions());
36  this->GetAgregator()->SetInputWeights(this->GetBlockMatcher()->GetBlockWeights());
37  this->GetAgregator()->SetInputTransforms(this->GetBlockMatcher()->GetBlockTransformPointers());
38 
39  TransformPointer usualAddOn = this->GetAgregator()->GetOutput();
40 
41  itk::TimeProbe tmpTimeReverse;
42  tmpTimeReverse.Start();
43 
44  this->GetBlockMatcher()->SetReferenceImage(movingImage);
45  this->GetBlockMatcher()->SetMovingImage(refImage);
46 
47  this->ChangeDefaultBackgroundValue(refImage, m_ReferenceBackgroundValue);
48  this->GetBlockMatcher()->Update();
49 
50  tmpTimeReverse.Stop();
51 
52  if (this->GetVerboseProgression())
53  std::cout << "Matching performed in " << tmpTimeReverse.GetTotal() << std::endl;
54 
55  this->GetAgregator()->SetInputRegions(this->GetBlockMatcher()->GetBlockRegions());
56  this->GetAgregator()->SetInputOrigins(this->GetBlockMatcher()->GetBlockPositions());
57  this->GetAgregator()->SetInputWeights(this->GetBlockMatcher()->GetBlockWeights());
58  this->GetAgregator()->SetInputTransforms(this->GetBlockMatcher()->GetBlockTransformPointers());
59 
60  TransformPointer reverseAddOn = this->GetAgregator()->GetOutput();
61 
62  if (this->GetAgregator()->GetOutputTransformType() == AgregatorType::SVF)
63  {
64  // Add update to current velocity field (cf. Vercauteren et al, 2008)
65  // First compute the SVF from two asymmetric ones: S = 0.25 * (S_0 - S_1)
66  // It's only a quarter since we are computing the half power of the transform between the two images
67  typedef typename SVFTransformType::VectorFieldType VelocityFieldType;
68 
69  typedef itk::MultiplyImageFilter <VelocityFieldType,itk::Image <double,InputImageType::ImageDimension>,VelocityFieldType> MultiplyFilterType;
70  typedef itk::SubtractImageFilter <VelocityFieldType,VelocityFieldType,VelocityFieldType> SubtractFilterType;
71 
72  SVFTransformType *usualAddOnCast = dynamic_cast <SVFTransformType *> (usualAddOn.GetPointer());
73  SVFTransformType *reverseAddOnCast = dynamic_cast <SVFTransformType *> (reverseAddOn.GetPointer());
74 
75  typename SubtractFilterType::Pointer subFilter = SubtractFilterType::New();
76  subFilter->SetInput1(usualAddOnCast->GetParametersAsVectorField());
77  subFilter->SetInput2(reverseAddOnCast->GetParametersAsVectorField());
78  subFilter->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
79  subFilter->InPlaceOn();
80 
81  subFilter->Update();
82 
83  typename MultiplyFilterType::Pointer multiplyFilter = MultiplyFilterType::New();
84  multiplyFilter->SetInput(subFilter->GetOutput());
85  multiplyFilter->SetConstant(0.25);
86  multiplyFilter->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
87  multiplyFilter->InPlaceOn();
88 
89  multiplyFilter->Update();
90 
91  typename VelocityFieldType::Pointer addonSVF = multiplyFilter->GetOutput();
92  addonSVF->DisconnectPipeline();
93 
94  usualAddOnCast->SetParametersAsVectorField(addonSVF);
95  }
96  else
97  {
98  AffineTransformType *usualAddOnCast = dynamic_cast <AffineTransformType *> (usualAddOn.GetPointer());
99  AffineTransformType *reverseAddOnCast = dynamic_cast <AffineTransformType *> (reverseAddOn.GetPointer());
100 
101  unsigned int NDimensions = InputImageType::ImageDimension;
102  vnl_matrix <double> usualAddOnMatrix(NDimensions+1,NDimensions+1,0);
103  vnl_matrix <double> reverseAddOnMatrix(NDimensions+1,NDimensions+1,0);
104  usualAddOnMatrix.set_identity();
105  reverseAddOnMatrix.set_identity();
106 
107  for (unsigned int i = 0;i < NDimensions;++i)
108  {
109  for (unsigned int j = 0;j < NDimensions;++j)
110  {
111  usualAddOnMatrix(i,j) = usualAddOnCast->GetMatrix()(i,j);
112  reverseAddOnMatrix(i,j) = reverseAddOnCast->GetMatrix()(i,j);
113  }
114 
115  usualAddOnMatrix(i,NDimensions) = usualAddOnCast->GetOffset()[i];
116  reverseAddOnMatrix(i,NDimensions) = reverseAddOnCast->GetOffset()[i];
117  }
118 
119  usualAddOnMatrix = anima::GetLogarithm(usualAddOnMatrix);
120  reverseAddOnMatrix = anima::GetLogarithm(reverseAddOnMatrix);
121 
122  usualAddOnMatrix -= reverseAddOnMatrix;
123  usualAddOnMatrix /= 4.0;
124 
125  usualAddOnMatrix = anima::GetExponential(usualAddOnMatrix);
126 
127  typename AffineTransformType::MatrixType trsfMatrix;
128 
129  for (unsigned int i = 0;i < NDimensions;++i)
130  for (unsigned int j = 0;j < NDimensions;++j)
131  trsfMatrix(i,j) = usualAddOnMatrix(i,j);
132 
133  usualAddOnCast->SetMatrix(trsfMatrix);
134 
135  typename AffineTransformType::OffsetType trsfOffset;
136  for (unsigned int i = 0;i < NDimensions;++i)
137  trsfOffset[i] = usualAddOnMatrix(i,NDimensions);
138 
139  usualAddOnCast->SetOffset(trsfOffset);
140  }
141 
142  addOn = usualAddOn;
143 }
144 
145 }
itk::AffineTransform< typename AgregatorType::ScalarType, TInputImageType::ImageDimension > AffineTransformType
vnl_matrix< T > GetExponential(const vnl_matrix< T > &m, const int numApprox=1)
Computation of the matrix exponential. Algo: classical scaling and squaring, as in Matlab...
vnl_matrix< T > GetLogarithm(const vnl_matrix< T > &m, const double precision=0.00000000001, const int numApprox=1)
Computation of the matrix logarithm. Algo: inverse scaling and squaring, variant proposed by Cheng et...
itk::StationaryVelocityFieldTransform< AgregatorScalarType, TInputImageType::ImageDimension > SVFTransformType