OTB  6.7.0
Orfeo Toolbox
otbListSampleToBalancedListSampleFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2019 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbListSampleToBalancedListSampleFilter_hxx
22 #define otbListSampleToBalancedListSampleFilter_hxx
23 
25 #include "itkProgressReporter.h"
26 #include "itkHistogram.h"
27 #include "itkNumericTraits.h"
28 
29 namespace otb {
30 namespace Statistics {
31 
32 // constructor
33 template < class TInputSampleList, class TLabelSampleList, class TOutputSampleList >
36 {
37  this->SetNumberOfRequiredInputs(2);
38  this->SetNumberOfRequiredOutputs(2);
39 
40  // Create the second output
41  //this->itk::ProcessObject::SetNthOutput(0, this->MakeOutput(0).GetPointer());
42  this->itk::ProcessObject::SetNthOutput(1, this->MakeOutput(1).GetPointer());
43 
44  m_AddGaussianNoiseFilter = GaussianAdditiveNoiseType::New();
45  m_BalancingFactor = 5;
46 }
47 
48 template < class TInputSampleList, class TLabelSampleList, class TOutputSampleList >
50 ::DataObjectPointer
53 {
54  DataObjectPointer output;
55  switch (idx)
56  {
57  case 0:
58  Superclass::MakeOutput(0);
59  break;
60  case 1:
61  {
62  output = static_cast<itk::DataObject*>(LabelSampleListType::New().GetPointer());
63  break;
64  }
65  default:
66  output = static_cast<itk::DataObject*>(InputSampleListType::New().GetPointer());
67  break;
68  }
69  return output;
70 }
71 
72 // Method to set the SampleList as DataObject
73 template < class TInputSampleList, class TLabelSampleList, class TOutputSampleList >
74 void
77 {
78  // Process object is not const-correct so the const_cast is required here
80  const_cast< LabelSampleListType* >( labelPtr ) );
81 }
82 
83 // Method to get the SampleList as DataObject
84 template < class TInputSampleList, class TLabelSampleList, class TOutputSampleList >
86 ::LabelSampleListType *
89 {
90  if (this->GetNumberOfInputs() < 2)
91  {
92  return nullptr;
93  }
94 
95  return static_cast<const LabelSampleListType* >
96  (this->itk::ProcessObject::GetInput(1) );
97 }
98 
99 // Get the output label SampleList as DataObject
100 template < class TInputSampleList, class TLabelSampleList, class TOutputSampleList >
102 ::LabelSampleListType *
105 {
106  return dynamic_cast<LabelSampleListType*>(this->itk::ProcessObject::GetOutput(1));
107 }
108 
109 
110 // Get the max sample number having the same label
111 template < class TInputSampleList, class TLabelSampleList, class TOutputSampleList >
112 void
115 {
116  // Iterate on the labelSampleList to get the min and max label
118 
119  // Number of bins to add to the histogram
120  typename LabelSampleListType::ConstPointer labelPtr = this->GetInputLabel();
121  typename LabelSampleListType::ConstIterator labelIt = labelPtr->Begin();
122 
123  while(labelIt != labelPtr->End())
124  {
125  // Get the current label sample
126  LabelMeasurementVectorType currentInputMeasurement = labelIt.GetMeasurementVector();
127 
128  if (currentInputMeasurement[0] > maxLabel)
129  maxLabel = currentInputMeasurement[0];
130 
131  ++labelIt;
132  }
133 
134  // Prepare histogram with dimension 1 : default template parameters
135  typedef typename itk::Statistics::Histogram<unsigned int> HistogramType;
136  typename HistogramType::Pointer histogram = HistogramType::New();
137  typename HistogramType::SizeType size(1);
138  size.Fill(maxLabel +1);
139  histogram->SetMeasurementVectorSize(1); // we need only one dimension
140  histogram->Initialize(size);
141 
142  labelIt = labelPtr->Begin();
143  while (labelIt != labelPtr->End())
144  {
145  // Get the current label sample
146  LabelMeasurementVectorType currentInputMeasurement = labelIt.GetMeasurementVector();
147  histogram->IncreaseFrequency(currentInputMeasurement[0], 1);
148  ++labelIt;
149  }
150 
151  // Iterate through the histogram to get the maximum
152  unsigned int maxvalue = 0;
153  HistogramType::Iterator iter = histogram->Begin();
154 
155  while ( iter != histogram->End() )
156  {
157  if( static_cast<unsigned int>(iter.GetFrequency()) > maxvalue )
158  maxvalue = static_cast<unsigned int>(iter.GetFrequency());
159  ++iter;
160  }
161 
162  // Number of sample per label to reach in order to have a balanced
163  // ListSample
164  unsigned int balancedFrequency = m_BalancingFactor * maxvalue;
165 
166  // Guess how much noised samples must be added per sample to get
167  // a balanced ListSample : Computed using the
168  // - Frequency of each label (stored in the histogram)
169  // - The value maxvalue by m_BalancingFactor
170  // The std::vector below stores the multiplicative factor
171  iter = histogram->Begin();
172  while ( iter != histogram->End() )
173  {
174  if(iter.GetFrequency() - 1e-10 < 0.)
175  m_MultiplicativeCoefficient.push_back(0);
176  else
177  {
178  unsigned int coeff = static_cast<unsigned int>(balancedFrequency/iter.GetFrequency());
179  m_MultiplicativeCoefficient.push_back(coeff);
180  }
181 
182  ++iter;
183  }
184 }
185 
186 template < class TInputSampleList, class TLabelSampleList, class TOutputSampleList >
187 void
190 {
191  // Get the how much each sample must be expanded
192  this->ComputeMaxSampleFrequency();
193 
194  // Retrieve input and output pointers
195  InputSampleListConstPointer inputSampleListPtr = this->GetInput();
196  LabelSampleListConstPointer labelSampleListPtr = this->GetInputLabel();
197  OutputSampleListPointer outputSampleListPtr = this->GetOutput();
198  LabelSampleListPointer outputLabel = this->GetOutputLabel();
199 
200  // Clear any previous output
201  outputSampleListPtr->Clear();
202 
203  // Set the measurement vectors size
204  outputSampleListPtr->SetMeasurementVectorSize(inputSampleListPtr->GetMeasurementVectorSize());
205  outputLabel->SetMeasurementVectorSize(labelSampleListPtr->GetMeasurementVectorSize());
206 
207  typename InputSampleListType::ConstIterator inputIt = inputSampleListPtr->Begin();
208  typename LabelSampleListType::ConstIterator labelIt = labelSampleListPtr->Begin();
209 
210  // Set-up progress reporting
211  itk::ProgressReporter progress(this, 0, inputSampleListPtr->Size());
212 
213  // Noising filter
214  GaussianAdditiveNoisePointerType noisingFilter = GaussianAdditiveNoiseType::New();
215 
216  // Iterate on the InputSampleList
217  while(inputIt != inputSampleListPtr->End() && labelIt != labelSampleListPtr->End())
218  {
219  // Retrieve current input sample
220  InputMeasurementVectorType currentInputMeasurement = inputIt.GetMeasurementVector();
221  // Retrieve the current label
222  LabelMeasurementVectorType currentLabelMeasurement = labelIt.GetMeasurementVector();
223 
224  // Build a temporary ListSample with the current
225  // measurement vector to generate noised versions of this
226  // measurement vector
227  InputSampleListPointer tempListSample = InputSampleListType::New();
228  tempListSample->SetMeasurementVectorSize(inputSampleListPtr->GetMeasurementVectorSize());
229  tempListSample->PushBack(currentInputMeasurement);
230 
231  // Get how many times we have to noise this sample
232  unsigned int iterations = m_MultiplicativeCoefficient[currentLabelMeasurement[0]];
233 
234  // Noising filter
235  //GaussianAdditiveNoisePointerType noisingFilter = GaussianAdditiveNoiseType::New();
236  noisingFilter->SetInput(tempListSample);
237  noisingFilter->SetNumberOfIteration(iterations);
238  noisingFilter->Update();
239 
240  // Build current output sample
241  OutputMeasurementVectorType currentOutputMeasurement;
242  currentOutputMeasurement.SetSize(currentInputMeasurement.GetSize());
243 
244  // Cast the current sample in outputSampleValue
245  for(unsigned int idx = 0; idx < inputSampleListPtr->GetMeasurementVectorSize(); ++idx)
246  currentOutputMeasurement[idx] = static_cast<OutputValueType>(currentInputMeasurement[idx]);
247 
248  // Add the current input casted sample to the output SampleList
249  outputSampleListPtr->PushBack(currentOutputMeasurement);
250 
251  // Add the currentsample list label
252  outputLabel->PushBack(currentLabelMeasurement);
253 
254  // Add the noised versions of the current sample to OutputSampleList
255  typename OutputSampleListType::ConstIterator tempIt = noisingFilter->GetOutput()->Begin();
256 
257  while(tempIt != noisingFilter->GetOutput()->End())
258  {
259  // Get the noised sample of the current measurement vector
260  OutputMeasurementVectorType currentTempMeasurement = tempIt.GetMeasurementVector();
261  // Add to output SampleList
262  outputSampleListPtr->PushBack(currentTempMeasurement);
263 
264  // Add a label in the output ListSample
265  outputLabel->PushBack(currentLabelMeasurement);
266 
267  ++tempIt;
268  }
269 
270  // Update progress
271  progress.CompletedPixel();
272 
273  ++inputIt;
274  ++ labelIt;
275  }
276 }
277 
278 template < class TInputSampleList, class TLabelSampleList, class TOutputSampleList >
279 void
281 ::PrintSelf(std::ostream& os, itk::Indent indent) const
282 {
283  // Call superclass implementation
284  Superclass::PrintSelf(os, indent);
285 }
286 
287 } // End namespace Statistics
288 } // End namespace otb
289 
290 #endif
itk::Size< Monteverdi_DIMENSION > SizeType
Definition: mvdTypes.h:137
void PrintSelf(std::ostream &os, itk::Indent indent) const override
DataObjectPointerArray::size_type DataObjectPointerArraySizeType
DataObject * GetInput(const DataObjectIdentifierType &key)
static ITK_CONSTEXPR_FUNC T min(const T &)
virtual void SetNthInput(DataObjectPointerArraySizeType num, DataObject *input)
virtual void SetNthOutput(DataObjectPointerArraySizeType num, DataObject *output)
DataObjectPointer MakeOutput(DataObjectPointerArraySizeType idx) override
This class generate a balanced ListSample in order to have fair distribution of learning samples...
DataObject * GetOutput(const DataObjectIdentifierType &key)