OTB  9.0.0
Orfeo Toolbox
otbListSampleToVariableDimensionHistogramGenerator.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1999-2011 Insight Software Consortium
3  * Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
4  *
5  * This file is part of Orfeo Toolbox
6  *
7  * https://www.orfeo-toolbox.org/
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 #ifndef otbListSampleToVariableDimensionHistogramGenerator_hxx
23 #define otbListSampleToVariableDimensionHistogramGenerator_hxx
24 
26 #include "otbMacro.h"
27 #include "itkStatisticsAlgorithm.h"
28 
29 namespace otb
30 {
31 
32 template <class TListSample, class THistogramMeasurement, class TFrequencyContainer>
34  : m_Sizes(1)
35 {
36  m_MarginalScale = 100;
37  m_AutoMinMax = true;
38 
39  this->SetNumberOfRequiredInputs(1);
40  this->SetNumberOfRequiredOutputs(1);
41 
42  this->itk::ProcessObject::SetNthOutput(0, this->MakeOutput(0).GetPointer());
43 }
44 
45 // Set the input sample list
46 template <class TListSample, class THistogramMeasurement, class TFrequencyContainer>
48 {
49  // Process object is not const-correct so the const_cast is required here
50  this->itk::ProcessObject::SetNthInput(0, const_cast<ListSampleType*>(inputlist));
51 }
52 
53 // Get the input sample list
54 template <class TListSample, class THistogramMeasurement, class TFrequencyContainer>
57 {
58  if (this->GetNumberOfInputs() < 1)
59  {
60  return nullptr;
61  }
62  return static_cast<const ListSampleType*>(this->itk::ProcessObject::GetInput(0));
63 }
64 
65 // Get the output Histogram
66 template <class TListSample, class THistogramMeasurement, class TFrequencyContainer>
69 {
70  return dynamic_cast<HistogramType*>(this->itk::ProcessObject::GetOutput(0));
71 }
72 
73 // MakeOutput implementation
74 template <class TListSample, class THistogramMeasurement, class TFrequencyContainer>
77  DataObjectPointerArraySizeType itkNotUsed(idx))
78 {
79  DataObjectPointer output;
80  output = static_cast<itk::DataObject*>(HistogramType::New().GetPointer());
81  return output;
82 }
83 
84 // GenerateData method,
85 template <class TListSample, class THistogramMeasurement, class TFrequencyContainer>
87 {
88  // Get the input ListSample
89  const ListSampleType* inputList = this->GetListSample();
90 
91  // Get a pointer on the output
92  typename HistogramType::Pointer histogram = const_cast<HistogramType*>(this->GetOutput());
93 
94  otbMsgDebugMacro(<< "ListSampleToVariableDimensionHistogramGenerator::GenerateData(): Entering");
95  // TODO : Sanity checks
96  if (m_Sizes.GetSize() != inputList->GetMeasurementVectorSize())
97  {
98  itkExceptionMacro("Sample list measurement vectors and histogram bin sizes vector have different dimensions !");
99  }
100 
101  if (!m_AutoMinMax)
102  {
103  if (m_HistogramMin.GetSize() != inputList->GetMeasurementVectorSize())
104  {
105  itkExceptionMacro("Sample list measurement vectors and histogram min have different dimensions !");
106  }
107  if (m_HistogramMax.GetSize() != inputList->GetMeasurementVectorSize())
108  {
109  itkExceptionMacro("Sample list measurement vectors and histogram max have different dimensions !");
110  }
111  }
112 
113  typename TListSample::MeasurementVectorType lower(inputList->GetMeasurementVectorSize());
114  typename TListSample::MeasurementVectorType upper(inputList->GetMeasurementVectorSize());
115 
116  typename HistogramType::MeasurementVectorType h_upper(inputList->GetMeasurementVectorSize());
117  typename HistogramType::MeasurementVectorType h_lower(inputList->GetMeasurementVectorSize());
118 
119  // must test for the list size to avoid making FindSampleBound() segfault.
120  // Also, the min and max can't be found automatically in that case. We can
121  // only return an empty histogram
122  if (m_AutoMinMax && inputList->Size() != 0)
123  {
124  itk::Statistics::Algorithm::FindSampleBound<ListSampleType>(inputList, inputList->Begin(), inputList->End(), lower, upper);
125  float margin;
126 
127  for (unsigned int i = 0; i < inputList->GetMeasurementVectorSize(); ++i)
128  {
129  if (!itk::NumericTraits<THistogramMeasurement>::is_integer)
130  {
131  margin = ((THistogramMeasurement)(upper[i] - lower[i]) / (THistogramMeasurement)m_Sizes[i]) / (THistogramMeasurement)m_MarginalScale;
132  h_upper[i] = (THistogramMeasurement)(upper[i] + margin);
133  if (h_upper[i] <= upper[i])
134  {
135  // an overflow has occurred therefore set upper to upper
136  h_upper[i] = upper[i];
137  // Histogram measurement type would force the clipping the max value.
138  // Therefore we must call the following to include the max value:
139  histogram->SetClipBinsAtEnds(false);
140  // The above function is okay since here we are within the autoMinMax
141  // computation and clearly the user intended to include min and max.
142  }
143  }
144  else
145  {
146  h_upper[i] = ((THistogramMeasurement)upper[i]) + itk::NumericTraits<THistogramMeasurement>::One;
147  if (h_upper[i] <= upper[i])
148  {
149  // an overflow has occurred therefore set upper to upper
150  h_upper[i] = upper[i];
151  // Histogram measurement type would force the clipping the max value.
152  // Therefore we must call the following to include the max value:
153  histogram->SetClipBinsAtEnds(false);
154  // The above function is okay since here we are within the autoMinMax
155  // computation and clearly the user intended to include min and max.
156  }
157  }
158  h_lower[i] = (THistogramMeasurement)lower[i];
159  }
160  }
161  else
162  {
163  h_lower = m_HistogramMin;
164  h_upper = m_HistogramMax;
165  }
166 
167  // initialize the Histogram object using the sizes and
168  // the upper and lower bound from the FindSampleBound function
169  // Have to Set the MeasurementVectorSize
170  histogram->SetMeasurementVectorSize(inputList->GetMeasurementVectorSize());
171 
172 
173  otbMsgDevMacro(<< "ListSampleToVariableDimensionHistogramGenerator::GenerateData(): Initializing histogram with (sizes= " << m_Sizes
174  << ", lower = " << h_lower << ", upper = " << h_upper << ")");
175  histogram->Initialize(m_Sizes, h_lower, h_upper);
176  otbMsgDevMacro(<< "ListSampleToVariableDimensionHistogramGenerator::GenerateData(): Histogram initialized");
177  typename TListSample::ConstIterator iter = inputList->Begin();
178  typename TListSample::ConstIterator last = inputList->End();
179  typename HistogramType::IndexType index(inputList->GetMeasurementVectorSize());
180  typename TListSample::MeasurementVectorType lvector(inputList->GetMeasurementVectorSize());
181  typename HistogramType::MeasurementVectorType hvector(inputList->GetMeasurementVectorSize());
182  unsigned int i;
183 
184  otbMsgDevMacro(<< "ListSampleToVariableDimensionHistogramGenerator::GenerateData(): Filling the histogram");
185  while (iter != last)
186  {
187  lvector = iter.GetMeasurementVector();
188  for (i = 0; i < inputList->GetMeasurementVectorSize(); ++i)
189  {
190  hvector[i] = (THistogramMeasurement)lvector[i];
191  }
192  histogram->GetIndex(hvector, index);
193 
194  if (!histogram->IsIndexOutOfBounds(index))
195  {
196  // if the measurement vector is out of bound then
197  // the GetIndex method has returned an index set to the max size of
198  // the invalid dimension - even if the hvector is less than the minimum
199  // bin value.
200  // If the index isn't valid, we don't increase the frequency.
201  // See the comments in Histogram->GetIndex() for more info.
202  histogram->IncreaseFrequencyOfIndex(index, 1);
203  }
204  ++iter;
205  }
206 
207  otbMsgDebugMacro(<< "ListSampleToVariableDimensionHistogramGenerator::GenerateData(): Leaving");
208 }
209 
210 template <class TListSample, class THistogramMeasurement, class TFrequencyContainer>
212  itk::Indent indent) const
213 {
214  Superclass::PrintSelf(os, indent);
215  os << indent << "AutoMinMax: " << m_AutoMinMax << std::endl;
216  os << indent << "Sizes: " << m_Sizes << std::endl;
217  os << indent << "MarginalScale: " << m_MarginalScale << std::endl;
218  os << indent << "HistogramMin: " << m_HistogramMin << std::endl;
219  os << indent << "HistogramMax: " << m_HistogramMax << std::endl;
220 }
221 
222 } // end of namespace itk
223 
224 #endif
otb::ListSampleToVariableDimensionHistogramGenerator::SetListSample
void SetListSample(const ListSampleType *inputlist)
Definition: otbListSampleToVariableDimensionHistogramGenerator.hxx:47
otbListSampleToVariableDimensionHistogramGenerator.h
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::ListSampleToVariableDimensionHistogramGenerator::ListSampleType
TListSample ListSampleType
Definition: otbListSampleToVariableDimensionHistogramGenerator.h:63
otbMacro.h
otb::ListSampleToVariableDimensionHistogramGenerator::m_MarginalScale
float m_MarginalScale
Definition: otbListSampleToVariableDimensionHistogramGenerator.h:124
otb::ListSampleToVariableDimensionHistogramGenerator::GetOutput
const HistogramType * GetOutput()
Definition: otbListSampleToVariableDimensionHistogramGenerator.hxx:68
otb::ListSampleToVariableDimensionHistogramGenerator::PrintSelf
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Definition: otbListSampleToVariableDimensionHistogramGenerator.hxx:211
otb::ListSampleToVariableDimensionHistogramGenerator::MakeOutput
DataObjectPointer MakeOutput(DataObjectPointerArraySizeType idx) override
Definition: otbListSampleToVariableDimensionHistogramGenerator.hxx:76
otb::ListSampleToVariableDimensionHistogramGenerator::DataObjectPointer
Superclass::DataObjectPointer DataObjectPointer
Definition: otbListSampleToVariableDimensionHistogramGenerator.h:77
otb::ListSampleToVariableDimensionHistogramGenerator::HistogramType
itk::Statistics::Histogram< HistogramMeasurementRealType, TFrequencyContainer > HistogramType
Definition: otbListSampleToVariableDimensionHistogramGenerator.h:71
otb::ListSampleToVariableDimensionHistogramGenerator::GetListSample
const ListSampleType * GetListSample() const
Definition: otbListSampleToVariableDimensionHistogramGenerator.hxx:56
otb::ListSampleToVariableDimensionHistogramGenerator::GenerateData
void GenerateData() override
Definition: otbListSampleToVariableDimensionHistogramGenerator.hxx:86
otbMsgDebugMacro
#define otbMsgDebugMacro(x)
Definition: otbMacro.h:62
otbMsgDevMacro
#define otbMsgDevMacro(x)
Definition: otbMacro.h:64
otb::ListSampleToVariableDimensionHistogramGenerator::DataObjectPointerArraySizeType
itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType
Definition: otbListSampleToVariableDimensionHistogramGenerator.h:78
otb::ListSampleToVariableDimensionHistogramGenerator::ListSampleToVariableDimensionHistogramGenerator
ListSampleToVariableDimensionHistogramGenerator()
Definition: otbListSampleToVariableDimensionHistogramGenerator.hxx:33
otb::ListSampleToVariableDimensionHistogramGenerator::m_AutoMinMax
bool m_AutoMinMax
Definition: otbListSampleToVariableDimensionHistogramGenerator.h:127