ANIMA  4.0
animaNonLocalMeansImageFilter.hxx
Go to the documentation of this file.
1 #pragma once
3 
6 
7 #include <itkImageRegionIterator.h>
8 #include <itkImageRegionIteratorWithIndex.h>
9 #include <itkImageRegionConstIterator.h>
10 #include <itkImageRegionConstIteratorWithIndex.h>
11 
12 namespace anima
13 {
14 
15 template <class TInputImage>
16 void
17 NonLocalMeansImageFilter <TInputImage>
18 ::BeforeThreadedGenerateData()
19 {
20  Superclass::BeforeThreadedGenerateData();
21 
22  this->computeAverageLocalVariance();
23  this->computeMeanAndVarImages();
24  m_maxAbsDisp = std::floor((double)(m_SearchNeighborhood / m_SearchStepSize)) * m_SearchStepSize;
25 }
26 
27 template <class TInputImage>
28 void
30 ::computeMeanAndVarImages()
31 {
33  MeanAndVarianceImagesFilterType;
34  typename MeanAndVarianceImagesFilterType::Pointer filter = MeanAndVarianceImagesFilterType::New();
35  filter->SetInput(this->GetInput());
36  typename InputImageType::SizeType radius;
37 
38  for (unsigned int j = 0;j < InputImageDimension;++j)
39  {
40  radius[j] = m_PatchHalfSize;
41  }
42 
43  filter->SetRadius(radius);
44  filter->SetNumberOfWorkUnits(this->GetNumberOfWorkUnits());
45  filter->Update();
46  m_meanImage = filter->GetMeanImage();
47  m_varImage = filter->GetVarImage();
48 }
49 
50 template <class TInputImage>
51 void
53 ::computeAverageLocalVariance()
54 {
55  typedef itk::ImageRegionConstIteratorWithIndex< InputImageType > InIteratorType;
56  InputImageRegionType largestRegion (this->GetInput()->GetLargestPossibleRegion());
57  InIteratorType dataIterator (this->GetInput(), largestRegion);
58 
59  double averageLocalSignal, diffSignal;
60  double baseSignal;
61  typename InputImageRegionType::IndexType baseIndex;
62 
63  double averageCovariance = 0;
64  unsigned int numEstimations = 0;
65  unsigned int numLocalPixels = 2 * InputImageDimension;
66 
67  while (!dataIterator.IsAtEnd())
68  {
69  baseSignal = static_cast<double>(dataIterator.Get());
70  baseIndex = dataIterator.GetIndex();
71  averageLocalSignal = 0;
72 
73  typename InputImageRegionType::IndexType valueIndex;
74  for (unsigned int d = 0; d < InputImageDimension; ++d)
75  {
76  valueIndex = baseIndex;
77  int tmpIndex = baseIndex[d] - m_localNeighborhood;
78  valueIndex[d] = std::max(tmpIndex,0);
79  averageLocalSignal += static_cast<double> (this->GetInput()->GetPixel(valueIndex));
80 
81  valueIndex = baseIndex;
82  tmpIndex = baseIndex[d] + m_localNeighborhood;
83  int maxIndex = largestRegion.GetSize()[d] - 1;
84  valueIndex[d] = std::min(tmpIndex, maxIndex);
85  averageLocalSignal += static_cast<double> (this->GetInput()->GetPixel(valueIndex));
86  }
87 
88  averageLocalSignal /= numLocalPixels;
89  diffSignal = sqrt(numLocalPixels / (numLocalPixels + 1.0)) * (baseSignal - averageLocalSignal);
90 
91  averageCovariance += diffSignal * diffSignal;
92 
93  ++numEstimations;
94  ++dataIterator;
95  }
96 
97  // Now divide by number of estimations and compute average variance
98  m_noiseCovariance = averageCovariance / numEstimations;
99 }
100 
101 template < class TInputImage>
102 void
104 ::DynamicThreadedGenerateData(const OutputImageRegionType &outputRegionForThread)
105 {
106  // Allocate output
107  typename OutputImageType::Pointer output = this->GetOutput();
108  typename InputImageType::Pointer input = const_cast<InputImageType *> (this->GetInput());
109 
110  typedef itk::ImageRegionConstIterator< InputImageType > InIteratorType;
111  typedef itk::ImageRegionIteratorWithIndex< OutputImageType > OutRegionIteratorType;
112 
113  InIteratorType inputIterator(input, outputRegionForThread);
114  OutRegionIteratorType outputIterator(output, outputRegionForThread);
115 
116  std::vector <InputPixelType> databaseSamples;
117  std::vector <double> databaseWeights;
118 
120 
121  PatchSearcherType patchSearcher;
122  patchSearcher.SetPatchHalfSize(m_PatchHalfSize);
123  patchSearcher.SetSearchStepSize(m_SearchStepSize);
124  patchSearcher.SetMaxAbsDisp(m_maxAbsDisp);
125  patchSearcher.SetInputImage(input);
126  patchSearcher.SetBetaParameter(m_BetaParameter);
127  patchSearcher.SetNoiseCovariance(m_noiseCovariance);
128  patchSearcher.SetWeightThreshold(m_WeightThreshold);
129  patchSearcher.SetMeanImage(m_meanImage);
130  patchSearcher.SetVarImage(m_varImage);
131  patchSearcher.SetMeanMinThreshold(m_MeanMinThreshold);
132  patchSearcher.SetVarMinThreshold(m_VarMinThreshold);
133 
134  while (!outputIterator.IsAtEnd())
135  {
136  patchSearcher.UpdateAtPosition(outputIterator.GetIndex());
137 
138  databaseSamples = patchSearcher.GetDatabaseSamples();
139  databaseWeights = patchSearcher.GetDatabaseWeights();
140 
141  //Compute weighted mean of databaseSamples
142  double average = 0, sum = 0, w_max = 0;
143 
144  switch (m_WeightMethod)
145  {
146  case EXP:
147  for (unsigned int d = 0;d < databaseSamples.size();++d)
148  {
149  average += databaseSamples[d] * databaseWeights[d];
150  sum += databaseWeights[d];
151 
152  if (w_max < databaseWeights[d])
153  w_max = databaseWeights[d];
154  }
155 
156  if (sum != 0)
157  outputIterator.Set((average + w_max * inputIterator.Get()) / (sum + w_max));
158  else
159  outputIterator.Set(inputIterator.Get());
160 
161  break;
162 
163  case RICIAN:
164  for (unsigned int d=0; d < databaseSamples.size(); d++)
165  {
166  average += databaseWeights[d] * (databaseSamples[d] * databaseSamples[d]);
167  sum += databaseWeights[d];
168  if (w_max < databaseWeights[d])
169  w_max = databaseWeights[d];
170  }
171 
172  if (sum != 0)
173  {
174  double t = ((average + (inputIterator.Get() * inputIterator.Get())
175  * w_max) / (sum + w_max)) - (2.0 * m_noiseCovariance);
176 
177  if (t < 0)
178  t = 0;
179 
180  outputIterator.Set(std::sqrt(t));
181  }
182  else
183  outputIterator.Set(inputIterator.Get());
184 
185  break;
186  }
187 
188  this->IncrementNumberOfProcessedPoints();
189  ++outputIterator;
190  ++inputIterator;
191  }
192 }
193 
194 } // end of namespace anima
Applies an variance filter to an image.
InputImageType::RegionType InputImageRegionType
OutputImageType::RegionType OutputImageRegionType