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 itkSaltAndPepperNoiseImageFilter_hxx
19 #define itkSaltAndPepperNoiseImageFilter_hxx
20 
21 #include "itkSaltAndPepperNoiseImageFilter.h"
22 #include "itkMersenneTwisterRandomVariateGenerator.h"
23 #include "itkImageScanlineIterator.h"
24 #include "itkProgressReporter.h"
25 
26 namespace itk
27 {
28 
29 template <class TInputImage, class TOutputImage>
30 SaltAndPepperNoiseImageFilter<TInputImage, TOutputImage>
SaltAndPepperNoiseImageFilter()31 ::SaltAndPepperNoiseImageFilter() :
32   m_SaltValue( NumericTraits<OutputImagePixelType>::max() ),
33   m_PepperValue( NumericTraits<OutputImagePixelType>::NonpositiveMin() )
34 {
35   this->DynamicMultiThreadingOn();
36 }
37 
38 template <class TInputImage, class TOutputImage>
39 void
40 SaltAndPepperNoiseImageFilter<TInputImage, TOutputImage>
DynamicThreadedGenerateData(const OutputImageRegionType & outputRegionForThread)41 ::DynamicThreadedGenerateData( const OutputImageRegionType &outputRegionForThread )
42 {
43   const InputImageType* inputPtr = this->GetInput();
44   OutputImageType*      outputPtr = this->GetOutput(0);
45 
46   // Create a random generator per thread
47   IndexValueType indSeed = 0;
48   for (unsigned d=0; d<TOutputImage::ImageDimension; d++)
49     {
50     indSeed += outputRegionForThread.GetIndex(d);
51     }
52   typename Statistics::MersenneTwisterRandomVariateGenerator::Pointer rand =
53     Statistics::MersenneTwisterRandomVariateGenerator::New();
54   const uint32_t seed = Self::Hash( this->GetSeed(), uint32_t(indSeed) );
55   rand->Initialize(seed);
56 
57   // Define the portion of the input to walk for this thread, using
58   // the CallCopyOutputRegionToInputRegion method allows for the input
59   // and output images to be different dimensions
60   InputImageRegionType inputRegionForThread;
61   this->CallCopyOutputRegionToInputRegion(inputRegionForThread, outputRegionForThread);
62 
63   // Define the iterators
64   ImageScanlineConstIterator<TInputImage> inputIt(inputPtr, inputRegionForThread);
65   ImageScanlineIterator<TOutputImage>     outputIt(outputPtr, outputRegionForThread);
66 
67   inputIt.GoToBegin();
68   outputIt.GoToBegin();
69 
70   while ( !inputIt.IsAtEnd() )
71     {
72     while ( !inputIt.IsAtEndOfLine() )
73       {
74       if( rand->GetVariate() < m_Probability )
75         {
76         if( rand->GetVariate() < 0.5 )
77           {
78           // Salt
79           outputIt.Set( m_SaltValue );
80           }
81         else
82           {
83           // Pepper
84           outputIt.Set( m_PepperValue );
85           }
86         }
87       else
88         {
89         // Keep the data unchanged
90         outputIt.Set( (OutputImagePixelType) inputIt.Get() );
91         }
92       ++inputIt;
93       ++outputIt;
94       }
95     inputIt.NextLine();
96     outputIt.NextLine();
97     }
98 }
99 
100 template <class TInputImage, class TOutputImage>
101 void
102 SaltAndPepperNoiseImageFilter<TInputImage, TOutputImage>
PrintSelf(std::ostream & os,Indent indent) const103 ::PrintSelf(std::ostream& os, Indent indent) const
104 {
105   Superclass::PrintSelf(os, indent);
106 
107   os << indent << "Probability: "
108      << static_cast<typename NumericTraits<double>::PrintType>( m_Probability )
109      << std::endl;
110 }
111 } // end namespace itk
112 
113 #endif
114