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