1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86
|
/*=========================================================================
Copyright (c) Kitware, Inc.
All rights reserved.
See Copyright.txt or http://www.kitware.com/VolViewCopyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "itkAdditiveGaussianNoiseImageFilter.h"
#include "itkImageRegionIterator.h"
#include "itkImageRegionConstIterator.h"
#include "itkProgressReporter.h"
#include "itkThreadSafeMersenneTwisterRandomVariateGenerator.h"
namespace itk
{
template <class TInputImage, class TOutputImage>
AdditiveGaussianNoiseImageFilter<TInputImage, TOutputImage>
::AdditiveGaussianNoiseImageFilter()
{
m_Mean = 0.0;
m_StandardDeviation = 1.0;
}
template <class TInputImage, class TOutputImage>
void
AdditiveGaussianNoiseImageFilter<TInputImage, TOutputImage>
::ThreadedGenerateData( const OutputImageRegionType &outputRegionForThread,
int threadId)
{
InputImageConstPointer inputPtr = this->GetInput();
OutputImagePointer outputPtr = this->GetOutput(0);
// create a random generator per thread
typename Statistics::ThreadSafeMersenneTwisterRandomVariateGenerator::Pointer rand = Statistics::ThreadSafeMersenneTwisterRandomVariateGenerator::New();
rand->Initialize();
// Define the portion of the input to walk for this thread, using
// the CallCopyOutputRegionToInputRegion method allows for the input
// and output images to be different dimensions
InputImageRegionType inputRegionForThread;
this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
// Define the iterators
ImageRegionConstIterator<TInputImage> inputIt(inputPtr, inputRegionForThread);
ImageRegionIterator<TOutputImage> outputIt(outputPtr, outputRegionForThread);
ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
inputIt.GoToBegin();
outputIt.GoToBegin();
while( !inputIt.IsAtEnd() )
{
double out = inputIt.Get() + rand->GetNormalVariate( m_Mean, m_StandardDeviation * m_StandardDeviation );
out = std::min( (double)NumericTraits<OutputImagePixelType>::max(), out );
out = std::max( (double)NumericTraits<OutputImagePixelType>::NonpositiveMin(), out );
outputIt.Set( (OutputImagePixelType) out );
++inputIt;
++outputIt;
progress.CompletedPixel(); // potential exception thrown here
}
}
template <class TInputImage, class TOutputImage>
void
AdditiveGaussianNoiseImageFilter<TInputImage, TOutputImage>
::PrintSelf(std::ostream& os,
Indent indent) const
{
Superclass::PrintSelf(os, indent);
os << indent << "Mean: "
<< static_cast<typename NumericTraits<double>::PrintType>(m_Mean)
<< std::endl;
os << indent << "StandardDeviation: "
<< static_cast<typename NumericTraits<double>::PrintType>(m_StandardDeviation)
<< std::endl;
}
} /* namespace itk */
|