OTB  9.0.0
Orfeo Toolbox
otbListSampleToHistogramListGenerator.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 otbListSampleToHistogramListGenerator_hxx
23 #define otbListSampleToHistogramListGenerator_hxx
24 
26 #include "itkArray.h"
27 #include "otbMacro.h"
28 
29 namespace otb
30 {
31 
32 template <class TListSample, class THistogramMeasurement, class TFrequencyContainer>
34  : m_Size(10), m_MarginalScale(100), m_AutoMinMax(true), m_NoDataFlag(false), m_NoDataValue(itk::NumericTraits<THistogramMeasurement>::Zero)
35 {
36  m_Size.Fill(255);
37 
38  this->SetNumberOfRequiredInputs(1);
39  this->SetNumberOfRequiredOutputs(1);
40 
41  this->itk::ProcessObject::SetNthOutput(0, this->MakeOutput(0).GetPointer());
42 }
43 
44 // Set the input ListSample
45 template <class TListSample, class THistogramMeasurement, class TFrequencyContainer>
47 {
48  // Process object is not const-correct so the const_cast is required here
49  this->itk::ProcessObject::SetNthInput(0, const_cast<ListSampleType*>(inputlist));
50 }
51 
52 // Get the input ListSample
53 template <class TListSample, class THistogramMeasurement, class TFrequencyContainer>
56 {
57  if (this->GetNumberOfInputs() < 1)
58  {
59  return nullptr;
60  }
61  return static_cast<const ListSampleType*>(this->itk::ProcessObject::GetInput(0));
62 }
63 
64 // Get the output
65 template <class TListSample, class THistogramMeasurement, class TFrequencyContainer>
68 {
69  return dynamic_cast<HistogramListType*>(this->itk::ProcessObject::GetOutput(0));
70 }
71 
72 // MakeOutput implementation
73 template <class TListSample, class THistogramMeasurement, class TFrequencyContainer>
76 {
77  DataObjectPointer output;
78  output = static_cast<itk::DataObject*>(HistogramListType::New().GetPointer());
79  return output;
80 }
81 
82 // GenerateData
83 template <class TListSample, class THistogramMeasurement, class TFrequencyContainer>
85 {
86  otbMsgDebugMacro(<< "ListSampleToHistogramListGenerator::GenerateData(): Entering");
87 
88  // Get the input ListSample
89  const ListSampleType* inputList = this->GetListSample();
90 
91  // Get a pointer on the output
92  typename HistogramListType::Pointer histogramList = const_cast<HistogramListType*>(this->GetOutput());
93 
94  if (!m_AutoMinMax)
95  {
96  if (m_HistogramMin.GetSize() != inputList->GetMeasurementVectorSize())
97  {
98  itkExceptionMacro("Sample list measurement vectors and histogram min have different dimensions !");
99  }
100  if (m_HistogramMax.GetSize() != inputList->GetMeasurementVectorSize())
101  {
102  itkExceptionMacro("Sample list measurement vectors and histogram max have different dimensions !");
103  }
104  }
105  typename TListSample::MeasurementVectorType lower(inputList->GetMeasurementVectorSize());
106  typename TListSample::MeasurementVectorType upper(inputList->GetMeasurementVectorSize());
107 
108  typename TListSample::MeasurementVectorType h_upper(inputList->GetMeasurementVectorSize());
109  typename TListSample::MeasurementVectorType h_lower(inputList->GetMeasurementVectorSize());
110 
111  bool clipBinsAtEnds = true;
112 
113  // must test for the list size to avoid making FindSampleBound() segfault.
114  // Also, the min and max can't be found automatically in that case. We can
115  // only return an empty histogram
116  if (m_AutoMinMax && inputList->Size() != 0)
117  {
118  itk::Statistics::Algorithm::FindSampleBound<ListSampleType>(inputList, inputList->Begin(), inputList->End(), lower, upper);
119  float margin;
120 
121  for (unsigned int i = 0; i < inputList->GetMeasurementVectorSize(); ++i)
122  {
123  if (!itk::NumericTraits<THistogramMeasurement>::is_integer)
124  {
125  margin = ((THistogramMeasurement)(upper[i] - lower[i]) / (THistogramMeasurement)m_Size[0]) / (THistogramMeasurement)m_MarginalScale;
126  h_upper[i] = (THistogramMeasurement)(upper[i] + margin);
127  if (h_upper[i] <= upper[i])
128  {
129  // an overflow has occurred therefore set upper to upper
130  h_upper[i] = upper[i];
131  // Histogram measurement type would force the clipping the max value.
132  // Therefore we must call the following to include the max value:
133  clipBinsAtEnds = false;
134  // The above function is okay since here we are within the autoMinMax
135  // computation and clearly the user intended to include min and max.
136  }
137  }
138  else
139  {
140  h_upper[i] = ((THistogramMeasurement)upper[i]) + itk::NumericTraits<THistogramMeasurement>::One;
141  if (h_upper[i] <= upper[i])
142  {
143  // an overflow has occurred therefore set upper to upper
144  h_upper[i] = upper[i];
145  // Histogram measurement type would force the clipping the max value.
146  // Therefore we must call the following to include the max value:
147  clipBinsAtEnds = false;
148  // The above function is okay since here we are within the autoMinMax
149  // computation and clearly the user intended to include min and max.
150  }
151  }
152  h_lower[i] = (THistogramMeasurement)lower[i];
153  }
154  }
155  else
156  {
157  h_lower = m_HistogramMin;
158  h_upper = m_HistogramMax;
159  }
160 
161  // Clearing previous histograms
162  histogramList->Clear();
163 
164  // For each dimension
165  for (unsigned int comp = 0; comp < inputList->GetMeasurementVectorSize(); ++comp)
166  {
167  // initialize the Histogram object using the sizes and
168  // the upper and lower bound from the FindSampleBound function
169  typename HistogramType::MeasurementVectorType comp_lower(inputList->GetMeasurementVectorSize());
170  typename HistogramType::MeasurementVectorType comp_upper(inputList->GetMeasurementVectorSize());
171 
172  comp_lower[0] = h_lower[comp];
173  comp_upper[0] = h_upper[comp];
174 
175  otbMsgDevMacro(<< "ListSampleToHistogramListGenerator::GenerateData(): Initializing histogram " << comp << " with (size= " << m_Size
176  << ", lower = " << comp_lower << ", upper = " << comp_upper << ")");
177 
178  // Create a new histogrma for this component : size of the
179  // measurement vector is : 1
180  histogramList->PushBack(HistogramType::New());
181  histogramList->Back()->SetMeasurementVectorSize(1);
182  histogramList->Back()->SetClipBinsAtEnds(clipBinsAtEnds);
183  histogramList->Back()->Initialize(m_Size, comp_lower, comp_upper);
184 
185  typename TListSample::ConstIterator iter = inputList->Begin();
186  typename TListSample::ConstIterator last = inputList->End();
187  typename HistogramType::IndexType index;
188  typename HistogramType::MeasurementVectorType hvector(inputList->GetMeasurementVectorSize());
189 
190  while (iter != last)
191  {
192  hvector[0] = static_cast<THistogramMeasurement>(iter.GetMeasurementVector()[comp]);
193  histogramList->Back()->GetIndex(hvector, index);
194  if ((!m_NoDataFlag) || hvector[0] != m_NoDataValue)
195  {
196 
197 
198  if (!histogramList->Back()->IsIndexOutOfBounds(index))
199  {
200  // if the measurement vector is out of bound then
201  // the GetIndex method has returned an index set to the max size of
202  // the invalid dimension - even if the hvector is less than the minimum
203  // bin value.
204  // If the index isn't valid, we don't increase the frequency.
205  // See the comments in Histogram->GetIndex() for more info.
206  histogramList->Back()->IncreaseFrequencyOfIndex(index, 1);
207  }
208  }
209  ++iter;
210  }
211  }
212  otbMsgDebugMacro(<< "ListSampleToHistogramListGenerator::GenerateData(): Leaving");
213 }
214 
215 template <class TListSample, class THistogramMeasurement, class TFrequencyContainer>
217 {
218  Superclass::PrintSelf(os, indent);
219  os << indent << "AutoMinMax: " << m_AutoMinMax << std::endl;
220  os << indent << "Size: " << m_Size << std::endl;
221  os << indent << "MarginalScale: " << m_MarginalScale << std::endl;
222  os << indent << "HistogramMin: " << m_HistogramMin << std::endl;
223  os << indent << "HistogramMax: " << m_HistogramMax << std::endl;
224 }
225 
226 } // end of namespace itk
227 
228 #endif
otb::ListSampleToHistogramListGenerator::m_Size
HistogramSizeType m_Size
Definition: otbListSampleToHistogramListGenerator.h:161
otb::ListSampleToHistogramListGenerator::GetOutput
const HistogramListType * GetOutput()
Definition: otbListSampleToHistogramListGenerator.hxx:67
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::ListSampleToHistogramListGenerator::SetListSample
void SetListSample(const ListSampleType *inputlist)
Definition: otbListSampleToHistogramListGenerator.hxx:46
otbMacro.h
otbListSampleToHistogramListGenerator.h
otb::ObjectList::Pointer
itk::SmartPointer< Self > Pointer
Definition: otbObjectList.h:46
otb::ListSampleToHistogramListGenerator::DataObjectPointerArraySizeType
itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType
Definition: otbListSampleToHistogramListGenerator.h:76
otb::ListSampleToHistogramListGenerator::ListSampleToHistogramListGenerator
ListSampleToHistogramListGenerator()
Definition: otbListSampleToHistogramListGenerator.hxx:33
otbMsgDebugMacro
#define otbMsgDebugMacro(x)
Definition: otbMacro.h:62
otb::ListSampleToHistogramListGenerator::ListSampleType
TListSample ListSampleType
Definition: otbListSampleToHistogramListGenerator.h:59
itk
Definition: otbNoDataHelper.h:31
otbMsgDevMacro
#define otbMsgDevMacro(x)
Definition: otbMacro.h:64
otb::ListSampleToHistogramListGenerator::GetListSample
const ListSampleType * GetListSample() const
Definition: otbListSampleToHistogramListGenerator.hxx:55
otb::ListSampleToHistogramListGenerator::MakeOutput
DataObjectPointer MakeOutput(DataObjectPointerArraySizeType idx) override
Definition: otbListSampleToHistogramListGenerator.hxx:75
otb::ListSampleToHistogramListGenerator::PrintSelf
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Definition: otbListSampleToHistogramListGenerator.hxx:216
otb::ObjectList
This class is a generic all-purpose wrapping around an std::vector<itk::SmartPointer<ObjectType> >.
Definition: otbObjectList.h:40
otb::ListSampleToHistogramListGenerator::GenerateData
void GenerateData() override
Definition: otbListSampleToHistogramListGenerator.hxx:84
otb::ListSampleToHistogramListGenerator::DataObjectPointer
Superclass::DataObjectPointer DataObjectPointer
Definition: otbListSampleToHistogramListGenerator.h:75