4 #include <itkImageRegionIteratorWithIndex.h> 5 #include <itkImageRegionConstIteratorWithIndex.h> 12 template <
class TScalarType,
unsigned int NDegreesOfFreedom,
unsigned int NDimensions>
17 unsigned int nbInputs = this->GetNumberOfIndexedInputs();
19 itkExceptionMacro(
"Error: There should be one input...");
22 typedef itk::ImageRegionIterator <WeightImageType> WeightIteratorType;
24 WeightIteratorType weightOriginalIterator(m_WeightImage,this->GetInput()->GetLargestPossibleRegion());
26 tmpWeights->SetRegions (this->GetInput()->GetLargestPossibleRegion());
27 tmpWeights->SetSpacing (this->GetInput()->GetSpacing());
28 tmpWeights->SetOrigin (this->GetInput()->GetOrigin());
29 tmpWeights->SetDirection (this->GetInput()->GetDirection());
30 tmpWeights->Allocate();
31 tmpWeights->FillBuffer(0);
33 WeightIteratorType tmpWeightIterator(tmpWeights,tmpWeights->GetLargestPossibleRegion());
35 while (!tmpWeightIterator.IsAtEnd())
37 if (weightOriginalIterator.Value() <= 0)
39 ++weightOriginalIterator;
44 tmpWeightIterator.Set(1.0);
45 ++weightOriginalIterator;
50 typename WeightSmootherType::Pointer weightSmooth = WeightSmootherType::New();
52 weightSmooth->SetInput(tmpWeights);
53 weightSmooth->SetSigma(m_FluidSigma);
54 weightSmooth->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
56 weightSmooth->Update();
59 typename FieldSmootherType::Pointer fieldSmooth = FieldSmootherType::New();
61 fieldSmooth->SetInput(this->GetInput());
62 fieldSmooth->SetSigma(m_FluidSigma);
63 fieldSmooth->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
65 fieldSmooth->Update();
68 smoothSVFImage->DisconnectPipeline();
74 double averageDist = 0;
75 unsigned int numPairings = 0;
78 typedef itk::ImageRegionIterator <WeightImageType> WeightIteratorWithIndexType;
79 WeightIteratorWithIndexType tmpWeightIteratorWithIndex(tmpWeights,tmpWeights->GetLargestPossibleRegion());
81 while (!tmpWeightIteratorWithIndex.IsAtEnd())
83 if (tmpWeightIteratorWithIndex.Value() <= 0)
85 ++tmpWeightIteratorWithIndex;
89 tmpIndex = tmpWeightIteratorWithIndex.GetIndex();
90 curDisp = smoothSVFImage->GetPixel(tmpIndex);
91 curDisp /= smoothWeightImage->GetPixel(tmpIndex);
93 originDisp = this->GetInput()->GetPixel(tmpIndex);
96 for (
unsigned int i = 0;i < NDegreesOfFreedom;++i)
97 dist += (curDisp[i] - originDisp[i]) * (curDisp[i] - originDisp[i]);
102 ++tmpWeightIteratorWithIndex;
105 m_AverageResidualValue = averageDist / numPairings;
111 m_NeighborhoodHalfSizes.resize(NDimensions);
113 for (
unsigned int i = 0;i < NDimensions;++i)
115 tmpRegion.SetIndex(i,0);
116 m_NeighborhoodHalfSizes[i] = std::ceil(3.0 * m_FluidSigma / this->GetInput()->GetSpacing()[i]);
117 tmpRegion.SetSize(i,2 * m_NeighborhoodHalfSizes[i] + 1);
118 centerIndex[i] = m_NeighborhoodHalfSizes[i];
121 typename WeightImageType::Pointer internalSpatialWeight = WeightImageType::New();
123 internalSpatialWeight->Initialize();
124 internalSpatialWeight->SetRegions (tmpRegion);
125 internalSpatialWeight->SetSpacing (this->GetInput()->GetSpacing());
126 internalSpatialWeight->SetOrigin (this->GetInput()->GetOrigin());
127 internalSpatialWeight->SetDirection (this->GetInput()->GetDirection());
128 internalSpatialWeight->Allocate();
130 WeightIteratorWithIndexType spatialWeightItr(internalSpatialWeight,tmpRegion);
131 internalSpatialWeight->TransformIndexToPhysicalPoint(centerIndex,centerPosition);
133 m_InternalSpatialKernelWeights.clear();
134 m_InternalSpatialKernelIndexes.clear();
136 while (!spatialWeightItr.IsAtEnd())
138 curIndex = spatialWeightItr.GetIndex();
139 internalSpatialWeight->TransformIndexToPhysicalPoint(curIndex,curPosition);
141 double centerDist = 0;
142 for (
unsigned int i = 0;i < NDimensions;++i)
143 centerDist += (centerPosition[i] - curPosition[i]) * (centerPosition[i] - curPosition[i]);
145 if (centerDist > 9.0 * m_FluidSigma * m_FluidSigma)
151 centerDist = std::sqrt(centerDist) / (3.0 * m_FluidSigma);
153 double wendlandFunctionValue = std::pow((1.0 - centerDist), 4) * (4.0 * centerDist + 1.0);
155 if (wendlandFunctionValue > 0.05)
157 m_InternalSpatialKernelWeights.push_back(wendlandFunctionValue);
158 m_InternalSpatialKernelIndexes.push_back(curIndex);
165 template <
class TScalarType,
unsigned int NDegreesOfFreedom,
unsigned int NDimensions>
170 typedef itk::ImageRegionIteratorWithIndex <TOutputImage> OutRegionIteratorType;
171 OutRegionIteratorType outIterator(this->GetOutput(), outputRegionForThread);
173 unsigned int numMaxEltsRegion = m_InternalSpatialKernelIndexes.size();
175 std::vector <double> weightsVector(numMaxEltsRegion);
176 std::vector <double> deltaVector(numMaxEltsRegion);
177 std::vector <InputPixelType> logTrsfsVector(numMaxEltsRegion);
182 std::vector <unsigned int> largestBound(NDimensions,0);
183 for (
unsigned int i = 0;i < NDimensions;++i)
184 largestBound[i] = largestRegion.GetIndex()[i] + largestRegion.GetSize()[i] - 1;
188 unsigned int numKernelWeights = m_InternalSpatialKernelWeights.size();
190 while (!outIterator.IsAtEnd())
193 centerIndex = outIterator.GetIndex();
195 double sumAbsoluteWeights = 0;
196 unsigned int pos = 0;
198 for (
unsigned int i = 0;i < numKernelWeights;++i)
201 for (
unsigned int j = 0;j < NDimensions;++j)
203 int testIndex = m_InternalSpatialKernelIndexes[i][j] + centerIndex[j] - m_NeighborhoodHalfSizes[j];
204 if ((testIndex < 0)||(testIndex > largestBound[j]))
210 inputIndex[j] = testIndex;
216 weight = m_WeightImage->GetPixel(inputIndex);
220 logTrsfsVector[pos] = this->GetInput()->GetPixel(inputIndex);
221 weightsVector[pos] = weight;
222 sumAbsoluteWeights += weightsVector[pos];
224 weightsVector[pos] *= m_InternalSpatialKernelWeights[i];
229 unsigned int numEltsRegion = pos;
231 if ((sumAbsoluteWeights <= 0)||(numEltsRegion < 1))
233 outIterator.Set(outValue);
238 bool stopLoop =
false;
239 unsigned int numIter = 0;
240 std::fill(deltaVector.begin(),deltaVector.begin()+numEltsRegion,1.0);
246 outValueOld = outValue;
249 double sumWeights = 0;
250 for (
unsigned int i = 0;i < numEltsRegion;++i)
252 double tmpWeight = weightsVector[i] * deltaVector[i];
253 outValue += logTrsfsVector[i] * tmpWeight;
255 sumWeights += tmpWeight;
258 outValue /= sumWeights;
260 if (numIter == m_MaxNumIterations)
264 stopLoop = checkConvergenceThreshold(outValueOld,outValue);
268 for (
unsigned int i = 0;i < numEltsRegion;++i)
271 for (
unsigned int j = 0;j < NDegreesOfFreedom;++j)
272 residual += (outValue[j] - logTrsfsVector[i][j]) * (outValue[j] - logTrsfsVector[i][j]);
274 deltaVector[i] = std::exp(- residual / (m_AverageResidualValue * m_MEstimateFactor));
279 outIterator.Set(outValue);
284 template <
class TScalarType,
unsigned int NDegreesOfFreedom,
unsigned int NDimensions>
289 for (
unsigned int i = 0;i < NDegreesOfFreedom;++i)
291 if (std::abs(outVal[i] - outValOld[i]) > m_ConvergenceThreshold)
Superclass::OutputImageRegionType OutputImageRegionType
TOutputImage::PixelType OutputPixelType
void DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread) ITK_OVERRIDE
TInputImage::PointType InputPointType
WeightImageType::Pointer WeightImagePointer
TInputImage::IndexType InputIndexType
void BeforeThreadedGenerateData() ITK_OVERRIDE
TInputImage::Pointer InputImagePointer