ANIMA  4.0
animaBalooExternalExtrapolateImageFilter.hxx
Go to the documentation of this file.
1 #pragma once
3 
4 #include <itkImageRegionIterator.h>
5 #include <itkImageRegionConstIterator.h>
6 
7 #include <itkThresholdImageFilter.h>
8 #include <itkThresholdLabelerImageFilter.h>
9 #include <itkSignedMaurerDistanceMapImageFilter.h>
10 
11 namespace anima
12 {
13 
14 template <class TScalarType, unsigned int NDegreesOfFreedom, unsigned int NDimensions>
15 void
18 {
19  unsigned int nbInputs = this->GetNumberOfIndexedInputs();
20  if (nbInputs != 1)
21  itkExceptionMacro("Error: There should be one input...");
22 
23  if (!this->GetRunningInPlace())
24  itkExceptionMacro("Error: this filter is made to run in place.");
25 
26  this->Superclass::BeforeThreadedGenerateData();
27 
28  // Compute outside part distance to later on smooth to identity when too far
29  typedef itk::Image <unsigned char, NDimensions> MaskImageType;
30  typedef itk::ThresholdImageFilter <WeightImageType> ThresholdFilterType;
31  typedef itk::ThresholdLabelerImageFilter <WeightImageType, MaskImageType> LabelerFilterType;
32 
33  typename ThresholdFilterType::Pointer thrFilter = ThresholdFilterType::New();
34  thrFilter->SetInput(m_WeightImage);
35  thrFilter->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
36  thrFilter->ThresholdBelow(1.0e-3);
37 
38  typename LabelerFilterType::Pointer labelFilter = LabelerFilterType::New();
39  labelFilter->SetInput(thrFilter->GetOutput());
40  typename LabelerFilterType::RealThresholdVector thrVals;
41  thrVals.push_back(0);
42 
43  labelFilter->SetRealThresholds(thrVals);
44  labelFilter->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
45  labelFilter->Update();
46 
47  typedef itk::SignedMaurerDistanceMapImageFilter <MaskImageType, WeightImageType> DistanceFilterType;
48  typename DistanceFilterType::Pointer distFilter = DistanceFilterType::New();
49 
50  distFilter->SetInput(labelFilter->GetOutput());
51  distFilter->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
52  distFilter->SetSquaredDistance(false);
53  distFilter->SetBackgroundValue(0);
54  distFilter->InsideIsPositiveOff();
55  distFilter->UseImageSpacingOn();
56  distFilter->Update();
57 
58  m_DistanceImage = distFilter->GetOutput();
59  m_DistanceImage->DisconnectPipeline();
60 }
61 
62 template <class TScalarType, unsigned int NDegreesOfFreedom, unsigned int NDimensions>
63 void
66 {
67  typedef itk::ImageRegionIterator <TOutputImage> OutRegionIteratorType;
68  OutRegionIteratorType outIterator(this->GetOutput(), outputRegionForThread);
69 
70  itk::ImageRegionConstIterator <WeightImageType> weightItr(m_WeightImage,outputRegionForThread);
71  itk::ImageRegionConstIterator <WeightImageType> distItr(m_DistanceImage,outputRegionForThread);
72 
73  InputPixelType curTrsf, zeroTrsf;
74  zeroTrsf.Fill(0);
75 
76  while (!outIterator.IsAtEnd())
77  {
78  double weight = weightItr.Value();
79  if (weight > 0)
80  {
81  curTrsf = outIterator.Get();
82 
83  double distValue = distItr.Value();
84  double externalWeight = 1.0;
85  if (distValue > 0)
86  {
87  double centerDist = distValue / (3.0 * m_ExtrapolationSigma);
88  // Wendland function phi_{3,1}
89  externalWeight = 0.0;
90  if (centerDist < 1.0)
91  externalWeight = std::pow((1.0 - centerDist), 4) * (4.0 * centerDist + 1.0);
92  }
93 
94  curTrsf *= externalWeight / weight;
95  outIterator.Set(curTrsf);
96  }
97  else
98  outIterator.Set(zeroTrsf);
99 
100  ++weightItr;
101  ++outIterator;
102  ++distItr;
103  }
104 }
105 
106 } // end of namespace anima
void DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread) ITK_OVERRIDE