ITK  4.2.0
Insight Segmentation and Registration Toolkit
itkPatchBasedDenoisingImageFilter.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef __itkPatchBasedDenoisingImageFilter_h
19 #define __itkPatchBasedDenoisingImageFilter_h
20 
22 #include "itkImageRegionIterator.h"
24 #include "itkVector.h"
25 #include "itkVectorImage.h"
26 #include "itkRGBPixel.h"
27 #include "itkRGBAPixel.h"
28 #include "itkDiffusionTensor3D.h"
30 #include "itkEnableIf.h"
31 #include "itkIsSame.h"
32 
33 namespace itk
34 {
35 
58 template <class TInputImage, class TOutputImage>
60 public PatchBasedDenoisingBaseImageFilter<TInputImage, TOutputImage>
61 {
62  public:
68  typedef typename Superclass::OutputImagePointer OutputImagePointer;
69 
71  itkNewMacro(Self);
72 
75 
77  typedef typename Superclass::InputImageType InputImageType;
78  typedef typename Superclass::OutputImageType OutputImageType;
79 
81  itkStaticConstMacro(ImageDimension, unsigned int,
82  Superclass::ImageDimension);
83 
85  typedef typename InputImageType::RegionType InputImageRegionType;
86 
90 
93  typedef typename Superclass::PixelType PixelType;
94  typedef typename Superclass::PixelValueType PixelValueType;
95 
101 
103  typedef typename Superclass::ListAdaptorType ListAdaptorType;
104  typedef typename Superclass::PatchRadiusType PatchRadiusType;
105  typedef typename Superclass::InputImagePatchIterator InputImagePatchIterator;
107  typedef typename Superclass::PatchWeightsType PatchWeightsType;
108 
114 
116  {
124  };
125 
126 
131  itkSetMacro(UseSmoothDiscPatchWeights, bool);
132  itkBooleanMacro(UseSmoothDiscPatchWeights);
133  itkGetConstMacro(UseSmoothDiscPatchWeights, bool);
135 
136 
141  itkSetMacro(GaussianKernelSigma, RealArrayType);
142  itkGetConstMacro(GaussianKernelSigma, RealArrayType);
144 
149  itkSetClampMacro(FractionPixelsForSigmaUpdate, double, 0.01, 1.0);
150  itkGetConstReferenceMacro(FractionPixelsForSigmaUpdate, double);
152 
154  itkSetMacro(ComputeConditionalDerivatives, bool);
155  itkBooleanMacro(ComputeConditionalDerivatives);
156  itkGetConstMacro(ComputeConditionalDerivatives, bool);
158 
160  itkStaticConstMacro(MaxSigmaUpdateIterations, unsigned int,
161  20);
162 
168  itkSetClampMacro(SigmaMultiplicationFactor, double, 0.01, 100);
169  itkGetConstReferenceMacro(SigmaMultiplicationFactor, double);
171 
175  void SetNoiseSigma(const RealType& sigma);
176  itkGetConstMacro(NoiseSigma, RealType);
178 
179 
181  itkSetObjectMacro(Sampler, BaseSamplerType);
182  itkGetObjectMacro(Sampler, BaseSamplerType);
184 
185  protected:
188  virtual void PrintSelf(std::ostream& os, Indent indent) const;
189 
191  virtual void AllocateUpdateBuffer();
192 
193  virtual void CopyInputToOutput();
194 
195  virtual void GenerateInputRequestedRegion();
196 
203  template< typename T>
204  typename EnableIfC<
205  IsSame<T, typename NumericTraits<T>::ValueType>::Value,
206  T >::Type
207  GetComponent(const T pix,
208  unsigned int itkNotUsed( idx ) ) const
209  {
210  // The enable if idiom is used to overload this method for both
211  // scalars and multi-component types. By exploiting that
212  // NumericTraits' ValueType typedef (defines the per-element type
213  // for multi-component types ) is different then the parameterize
214  // type, the bracket operator is used only for multi-component
215  // types.
216  return pix;
217  }
218  template< typename T>
219  typename DisableIfC<
220  IsSame<T, typename NumericTraits<T>::ValueType>::Value,
221  typename NumericTraits<T>::ValueType>::Type
222  GetComponent(const T& pix,
223  unsigned int idx ) const
224  {
225  return pix[idx];
226  }
227 
229  template< typename T >
230  void
231  SetComponent( T &pix,
232  unsigned int itkNotUsed( idx ),
233  typename EnableIfC< IsSame<T, typename NumericTraits<T>::ValueType>::Value, RealValueType>::Type val) const
234  {
235  pix = val;
236  }
237  template< typename T >
238  void
239  SetComponent( T &pix,
240  unsigned int idx,
241  typename DisableIfC< IsSame<T, typename NumericTraits<T>::ValueType>::Value, RealValueType>::Type val) const
242  {
243  pix[idx] = val;
244  }
245 
246 
249  void ComputeMinMax(const Image< DiffusionTensor3D<PixelValueType> , ImageDimension>* img)
250  {
251  if (this->m_ComponentSpace == Superclass::RIEMANNIAN)
252  {
253  DispatchedRiemannianMinMax(img);
254  }
255  else
256  {
257  DispatchedArrayMinMax(img);
258  }
259  }
260 
261  template< typename TImageType>
262  typename EnableIfC<
263  IsSame<typename TImageType::PixelType, typename NumericTraits<typename TImageType::PixelType>::ValueType>::Value
264  >::Type
265  ComputeMinMax(const TImageType* img)
266  {
267  DispatchedMinMax(img);
268  }
269  template< typename TImageType>
270  typename DisableIfC<
271  IsSame<typename TImageType::PixelType, typename NumericTraits<typename TImageType::PixelType>::ValueType>::Value
272  >::Type
273  ComputeMinMax(const TImageType* img)
274  {
275  DispatchedArrayMinMax(img);
276  }
277 
283  void ComputeDifferenceAndWeightedSquaredNorm(const DiffusionTensor3D<PixelValueType>& a,
285  const RealArrayType& weight,
286  RealType& diff, RealArrayType& norm)
287  {
288  if (this->m_ComponentSpace == Superclass::RIEMANNIAN)
289  {
290  ComputeLogMapAndWeightedSquaredGeodesicDifference(a, b, weight, diff, norm);
291  }
292  else
293  {
294  ComputeSignedEuclideanDifferenceAndWeightedSquaredNorm(a, b, weight, diff, norm);
295  }
296  }
297  template <class PixelT>
298  void ComputeDifferenceAndWeightedSquaredNorm(const PixelT& a,
299  const PixelT& b,
300  const RealArrayType& weight,
301  RealType& diff, RealArrayType& norm)
302  {
303  ComputeSignedEuclideanDifferenceAndWeightedSquaredNorm(a, b, weight, diff, norm);
304  }
306 
311  const RealType& b)
312  {
313  if (this->m_ComponentSpace == Superclass::RIEMANNIAN)
314  {
315  return this->AddExponentialMapUpdate(a, b);
316  }
317  else
318  {
319  return this->AddEuclideanUpdate(a, b);
320  }
321  }
322  template <class RealT>
323  RealType AddUpdate(const RealT& a,
324  const RealType& b)
325  {
326  return this->AddEuclideanUpdate(a, b);
327  }
329 
330 
331  virtual void EnforceConstraints();
332 
333  virtual void Initialize();
334 
335  virtual void InitializeKernelSigma();
336 
337  virtual void InitializePatchWeights();
338  virtual void InitializePatchWeightsSmoothDisc();
339 
340  virtual void InitializeIteration();
341 
342  virtual void ComputeKernelBandwidthUpdate(); // derived from base class; define here
343  virtual ThreadDataStruct ThreadedComputeSigmaUpdate(const InputImageRegionType& regionToProcess,
344  const int itkNotUsed(threadId),
345  ThreadDataStruct threadData);
346  virtual RealArrayType ResolveSigmaUpdate();
347 
348 
349  virtual void ComputeImageUpdate();
350  virtual ThreadDataStruct ThreadedComputeImageUpdate(const InputImageRegionType& regionToProcess,
351  const int threadId,
352  ThreadDataStruct threadData);
353  virtual RealType ComputeGradientJointEntropy(InstanceIdentifier id,
354  typename ListAdaptorType::Pointer& inList,
355  BaseSamplerPointer& sampler);
356 
357 
358  virtual void ApplyUpdate();
359  virtual void ThreadedApplyUpdate(const InputImageRegionType& regionToProcess,
360  const int itkNotUsed(threadId));
361 
362 
363  virtual void PostProcessOutput();
364 
365  virtual void SetThreadData(int threadId, const ThreadDataStruct& data);
366  virtual ThreadDataStruct GetThreadData(int threadId);
367 
368  std::vector<ThreadDataStruct> m_ThreadData;
369 
371  typename OutputImageType::Pointer m_UpdateBuffer;
372 
373  unsigned int m_NumPixelComponents;
375  unsigned int m_TotalNumberPixels;
376  //
378  //
386  double m_MinSigma;
392  //
396  //
399 
400  private:
401  PatchBasedDenoisingImageFilter(const Self&); // purposely not implemented
402  void operator=(const Self&); // purposely not implemented
403 
406  static ITK_THREAD_RETURN_TYPE ComputeSigmaUpdateThreaderCallback( void *arg );
407 
410  static ITK_THREAD_RETURN_TYPE ComputeImageUpdateThreaderCallback( void *arg );
411 
414  static ITK_THREAD_RETURN_TYPE ApplyUpdateThreaderCallback( void *arg );
415 
416  template <typename TInputImageType>
417  void DispatchedMinMax(const TInputImageType* img);
418 
419  template <typename TInputImageType>
420  void DispatchedArrayMinMax(const TInputImageType* img);
421 
422  template <typename TInputImageType>
423  void DispatchedVectorMinMax(const TInputImageType* img);
424 
425  template <typename TInputImageType>
426  void DispatchedRiemannianMinMax(const TInputImageType* img);
429  static ITK_THREAD_RETURN_TYPE RiemannianMinMaxThreaderCallback( void *arg );
430 
431  ThreadDataStruct ThreadedRiemannianMinMax(const InputImageRegionType& regionToProcess,
432  const int itkNotUsed(threadId),
433  const InputImageType* img,
434  ThreadDataStruct threadData);
435 
436  virtual void ResolveRiemannianMinMax();
437 
438 
439  void ComputeSignedEuclideanDifferenceAndWeightedSquaredNorm(const PixelType& a, const PixelType& b,
440  const RealArrayType& weight,
441  RealType& diff, RealArrayType& norm);
442 
444  void ComputeLogMapAndWeightedSquaredGeodesicDifference(const DiffusionTensor3D<PixelValueType>& spdMatrixA,
445  const DiffusionTensor3D<PixelValueType>& spdMatrixB,
446  const RealArrayType& weight,
447  RealType& symMatrixLogMap, RealArrayType& geodesicDist);
448 
449  RealType AddEuclideanUpdate(const RealType& a, const RealType& b);
451  RealType AddExponentialMapUpdate(const DiffusionTensor3D<RealValueType>& spdMatrix,
452  const DiffusionTensor3D<RealValueType>& symMatrix);
453 
455  {
458  };
459 
460  }; // end class PatchBasedDenoisingImageFilter
461 
462 } // end namespace itk
463 
464 // Define instantiation macro for this template
465 #define ITK_TEMPLATE_PatchBasedDenoisingImageFilter(_, EXPORT, x, y) namespace itk { \
466  _(2(class EXPORT PatchBasedDenoisingImageFilter< ITK_TEMPLATE_2 x >)) | \
467  namespace Templates { typedef PatchBasedDenoisingImageFilter< ITK_TEMPLATE_2 x > \
468  PatchBasedDenoisingImageFilter##y; } \
469  }
470 
471 #if ITK_TEMPLATE_EXPLICIT
472 # include "Templates/itkPatchBasedDenoisingImageFilter+-.h"
473 #endif
474 
475 #if ITK_TEMPLATE_TXX
476 # include "itkPatchBasedDenoisingImageFilter.hxx"
477 #endif
478 
479 #endif
480