4 #include <itkVariableLengthVector.h> 5 #include <itkImageRegionIterator.h> 6 #include <itkImageRegionConstIterator.h> 7 #include <itkImageLinearIteratorWithIndex.h> 20 template<
typename TInputImage >
21 DistortionCorrectionImageFilter < TInputImage >
25 this->SetNumberOfRequiredInputs( 2 );
28 template<
typename TInputImage >
30 ::GenerateOutputInformation(
void)
35 this->Superclass::GenerateOutputInformation();
38 output->SetVectorLength( 3 );
41 template<
typename TInputImage >
47 this->AllocateOutputs();
52 this->BeforeThreadedGenerateData();
54 using RegionType = itk::ImageRegion <TInputImage::ImageDimension>;
55 typename OutputImageType::Pointer outputImage(this->GetOutput());
56 const RegionType region = outputImage->GetRequestedRegion();
58 this->GetMultiThreader()->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
59 this->GetMultiThreader()->template ParallelizeImageRegionRestrictDirection<OutputImageType::ImageDimension>(
60 this->m_Direction, region, [
this](
const RegionType & lambdaRegion) { this->DynamicThreadedGenerateData(lambdaRegion); },
this);
63 template<
typename TInputImage >
65 ::BeforeThreadedGenerateData()
67 Superclass::BeforeThreadedGenerateData();
69 m_ReferenceGeometry = this->GetInput(0)->GetDirection();
71 for (
unsigned int i = 0;i < 3;++i)
72 for (
unsigned int j = 0;j < 3;++j)
73 m_ReferenceGeometry(i,j) *= this->GetInput(0)->GetSpacing()[j];
76 template<
typename TInputImage >
83 typedef itk::ImageLinearConstIteratorWithIndex< TInputImage > ConstIteratorType;
84 typedef itk::ImageLinearIteratorWithIndex< OutputImageType > IteratorType;
86 ConstIteratorType forwardIt (forwardImage, outputRegionForThread);
87 ConstIteratorType backwardIt (backwardImage, outputRegionForThread);
88 IteratorType outputIt (this->GetOutput(), outputRegionForThread);
90 forwardIt.SetDirection(m_Direction);
91 backwardIt.SetDirection(m_Direction);
92 outputIt.SetDirection(m_Direction);
94 unsigned int lengthLine = outputRegionForThread.GetSize()[ this->m_Direction ];
97 double epsilon = 0.0001;
98 itk::VariableLengthVector< PixelType > fillVectorField(3);
99 itk::VariableLengthVector< PixelType > fillScaledVectorField(3);
100 fillVectorField.Fill(0);
101 fillScaledVectorField.Fill(0);
103 std::vector<double> forwardScale;
104 std::vector<double> backwardScale;
105 std::vector<double> middleScale;
106 std::vector<double> differenceForwardBackward;
107 std::vector<double> differenceForwardBackwardResampled;
109 while (!forwardIt.IsAtEnd())
112 std::vector<double> forwardCumulatedLine;
113 std::vector<double> backwardCumulatedLine;
115 forwardCumulatedLine.push_back(forwardIt.Get());
116 backwardCumulatedLine.push_back(backwardIt.Get());
121 while (!forwardIt.IsAtEndOfLine())
124 forwardCumulatedLine.push_back(forwardCumulatedLine.back() + forwardIt.Get() + epsilon);
125 backwardCumulatedLine.push_back(backwardCumulatedLine.back() + backwardIt.Get() + epsilon);
132 double forwMax = forwardCumulatedLine.back();
133 double forwMin = forwardCumulatedLine.front();
134 double backMax = backwardCumulatedLine.back();
135 double backMin = backwardCumulatedLine.front();
137 for (
int i=0; i<lengthLine; i++)
138 backwardCumulatedLine[i]-= backMin;
139 for (
int i=0; i<lengthLine; i++)
140 backwardCumulatedLine[i]*= (forwMax - forwMin)/(backMax - backMin);
141 for (
int i=0; i<lengthLine; i++)
142 backwardCumulatedLine[i]+= forwMin;
144 step = (forwMax - forwMin)/(10*forwardCumulatedLine.size());
149 differenceForwardBackward.resize(forwardScale.size());
150 middleScale.resize(forwardScale.size());
152 for (
int i=0; i< differenceForwardBackward.size(); i++)
154 differenceForwardBackward[i] = (forwardScale[i] - backwardScale[i])/2;
155 middleScale[i] = (forwardScale[i] + backwardScale[i])/2;
158 CubicInterpolator<double>(differenceForwardBackward, middleScale, differenceForwardBackwardResampled, lengthLine);
160 unsigned int pos = 0;
162 while (!outputIt.IsAtEndOfLine())
164 fillVectorField[m_Direction] = differenceForwardBackwardResampled[pos];
166 for (
unsigned int i = 0;i < 3;++i)
168 fillScaledVectorField[i] = m_ReferenceGeometry(i,m_Direction) * fillVectorField[m_Direction];
171 outputIt.Set(fillScaledVectorField);
176 forwardIt.NextLine();
177 backwardIt.NextLine();
182 template<
typename TInputImage >
184 ::AfterThreadedGenerateData()
187 if (m_FieldSmoothingSigma > 0)
191 typename SmoothingFilterType::Pointer fieldSmoother = SmoothingFilterType::New();
192 fieldSmoother->SetInput(this->GetOutput());
193 fieldSmoother->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
194 fieldSmoother->SetSigma(m_FieldSmoothingSigma);
196 fieldSmoother->Update();
198 this->SetNthOutput(0,fieldSmoother->GetOutput());
201 Superclass::AfterThreadedGenerateData();
itk::VectorImage< typename TInputImage::InternalPixelType, TInputImage::ImageDimension > OutputImageType
TInputImage::ConstPointer InputImagePointer
TOutputImage::RegionType OutputImageRegionType
void InverseCubicInterpolator(std::vector< T > &inputVect, std::vector< T > &outputVect, T step)