OTB  9.0.0
Orfeo Toolbox
otbStreamingHistogramVectorImageFilter.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 otbStreamingHistogramVectorImageFilter_hxx
23 #define otbStreamingHistogramVectorImageFilter_hxx
25 
26 #include "itkImageRegionIterator.h"
27 #include "itkImageRegionConstIteratorWithIndex.h"
28 #include "itkProgressReporter.h"
29 #include "otbMacro.h"
30 
31 namespace otb
32 {
33 
34 template <class TInputImage>
36  : m_ThreadHistogramList(),
37  m_Size(),
38  m_HistogramMin(),
39  m_HistogramMax(),
40  m_NoDataFlag(false),
41  m_NoDataValue(itk::NumericTraits<InternalPixelType>::Zero),
42  m_SubSamplingRate(1)
43 {
44  // first output is a copy of the image, DataObject created by
45  // superclass
46  //
47  // allocate the data objects for the outputs which are
48  // just decorators around pixel types and histogram list
49 
50  m_Size.Fill(255);
51 
52  HistogramListPointerType output = static_cast<HistogramListType*>(this->MakeOutput(1).GetPointer());
53  this->itk::ProcessObject::SetNthOutput(1, output.GetPointer());
54 }
55 
56 template <class TInputImage>
58 {
59  itk::DataObject::Pointer ret;
60  switch (output)
61  {
62  case 0:
63  ret = static_cast<itk::DataObject*>(TInputImage::New().GetPointer());
64  break;
65  case 1:
66  ret = static_cast<itk::DataObject*>(HistogramListType::New().GetPointer());
67  break;
68  }
69  return ret;
70 }
71 
72 template <class TInputImage>
74 {
75  return static_cast<HistogramListType*>(this->itk::ProcessObject::GetOutput(1));
76 }
77 
78 template <class TInputImage>
81 {
82  return static_cast<const HistogramListType*>(this->itk::ProcessObject::GetOutput(1));
83 }
84 
85 template <class TInputImage>
87 {
88  Superclass::GenerateOutputInformation();
89  if (this->GetInput())
90  {
91  this->GetOutput()->CopyInformation(this->GetInput());
92  this->GetOutput()->SetLargestPossibleRegion(this->GetInput()->GetLargestPossibleRegion());
93 
94  if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
95  {
96  this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
97  }
98  }
99 }
100 
101 template <class TInputImage>
103 {
104  // This is commented to prevent the streaming of the whole image for the first stream strip
105  // It shall not cause any problem because the output image of this filter is not intended to be used.
106  // InputImagePointer image = const_cast< TInputImage * >( this->GetInput() );
107  // this->GraftOutput( image );
108  // Nothing that needs to be allocated for the remaining outputs
109 }
110 
111 template <class TInputImage>
113 {
114  TInputImage* inputPtr = const_cast<TInputImage*>(this->GetInput());
115  inputPtr->UpdateOutputInformation();
116 
117  unsigned int numberOfThreads = this->GetNumberOfThreads();
118  unsigned int numberOfComponent = inputPtr->GetNumberOfComponentsPerPixel();
119 
120  // TODO which is the good value ? (false in MVD2)
121  bool clipBins = false;
122 
123  // if histogram Min and Max have the wrong size : set to default [0, 255]
124  if (m_HistogramMin.Size() != numberOfComponent || m_HistogramMax.Size() != numberOfComponent)
125  {
126  m_HistogramMin.SetSize(numberOfComponent);
127  m_HistogramMax.SetSize(numberOfComponent);
128 
129  m_HistogramMin.Fill(itk::NumericTraits<InternalPixelType>::Zero);
130  m_HistogramMax.Fill(255);
131  }
132 
133  // Setup output histogram
134  HistogramListType* outputHisto = this->GetHistogramListOutput();
135  outputHisto->Clear();
136  for (unsigned int k = 0; k < numberOfComponent; ++k)
137  {
138  typename HistogramType::MeasurementVectorType bandMin, bandMax;
139  bandMin.SetSize(1);
140  bandMax.SetSize(1);
141  bandMin.Fill(m_HistogramMin[k]);
142  bandMax.Fill(m_HistogramMax[k]);
143 
144  typename HistogramType::Pointer histogram = HistogramType::New();
145  histogram->SetClipBinsAtEnds(clipBins);
146 
147  typename HistogramType::SizeType size;
148  size.SetSize(1);
149  size.Fill(m_Size[k]);
150  histogram->SetMeasurementVectorSize(1);
151  histogram->Initialize(size, bandMin, bandMax);
152 
153  outputHisto->PushBack(histogram);
154  }
155 
156 
157  // Setup HistogramLists for each thread
158  m_ThreadHistogramList.clear();
159  for (unsigned int i = 0; i < numberOfThreads; ++i)
160  {
161  HistogramListPointerType histoList = HistogramListType::New();
162  histoList->Clear();
163  for (unsigned int k = 0; k < numberOfComponent; ++k)
164  {
165  typename HistogramType::MeasurementVectorType bandMin, bandMax;
166  bandMin.SetSize(1);
167  bandMax.SetSize(1);
168  bandMin.Fill(m_HistogramMin[k]);
169  bandMax.Fill(m_HistogramMax[k]);
170 
171  typename HistogramType::Pointer histogram = HistogramType::New();
172  histogram->SetClipBinsAtEnds(clipBins);
173 
174  typename HistogramType::SizeType size;
175  size.SetSize(1);
176  size.Fill(m_Size[k]);
177  histogram->SetMeasurementVectorSize(1);
178  histogram->Initialize(size, bandMin, bandMax);
179 
180  histoList->PushBack(histogram);
181  }
182  m_ThreadHistogramList.push_back(histoList);
183  }
184 }
185 
186 template <class TInputImage>
188 {
189  HistogramListType* outputHisto = this->GetHistogramListOutput();
190 
191  int numberOfThreads = this->GetNumberOfThreads();
192  unsigned int numberOfComponent = this->GetInput()->GetNumberOfComponentsPerPixel();
193 
194  // copy histograms to output
195  for (int i = 0; i < numberOfThreads; ++i)
196  {
197  for (unsigned int j = 0; j < numberOfComponent; ++j)
198  {
199  HistogramType* outHisto = outputHisto->GetNthElement(j);
200  HistogramType* threadHisto = m_ThreadHistogramList[i]->GetNthElement(j);
201 
202  typename HistogramType::Iterator iterOutput = outHisto->Begin();
203  typename HistogramType::Iterator iterThread = threadHisto->Begin();
204 
205  while (iterOutput != outHisto->End() && iterThread != threadHisto->End())
206  {
207  iterOutput.SetFrequency(iterOutput.GetFrequency() + iterThread.GetFrequency());
208 
209  ++iterOutput;
210  ++iterThread;
211  }
212  }
213  }
214 }
215 
216 template <class TInputImage>
217 void PersistentHistogramVectorImageFilter<TInputImage>::ThreadedGenerateData(const RegionType& outputRegionForThread, itk::ThreadIdType threadId)
218 {
222  InputImagePointer inputPtr = const_cast<TInputImage*>(this->GetInput());
223  // support progress methods/callbacks
224  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
226 
227  typename HistogramType::IndexType index;
228 
229  itk::ImageRegionConstIteratorWithIndex<TInputImage> it(inputPtr, outputRegionForThread);
230  it.GoToBegin();
231 
232  bool skipSample = false;
233 
234  // do the work
235  while (!it.IsAtEnd())
236  {
237  if (m_SubSamplingRate > 1)
238  {
239  skipSample = false;
240  for (unsigned int i = 0; i < InputImageDimension; ++i)
241  {
242  if (it.GetIndex()[i] % m_SubSamplingRate != 0)
243  {
244  skipSample = true;
245  break;
246  }
247  }
248  if (skipSample)
249  {
250  ++it;
251  progress.CompletedPixel();
252  continue;
253  }
254  }
255 
256  PixelType vectorValue = it.Get();
257 
258  bool skipSampleNoData = false;
259  if (m_NoDataFlag)
260  {
261  unsigned int itComp = 0;
262  while (itComp < vectorValue.GetSize())
263  {
264  if (vectorValue[itComp] == m_NoDataValue)
265  {
266  skipSampleNoData = true;
267  itComp++;
268  }
269  else
270  {
271  skipSampleNoData = false;
272  break;
273  }
274  }
275  }
276 
277  if (!skipSampleNoData)
278  {
279  for (unsigned int j = 0; j < vectorValue.GetSize(); ++j)
280  {
281  typename HistogramType::MeasurementVectorType value;
282  value.SetSize(1);
283  value.Fill(vectorValue[j]);
284 
285  m_ThreadHistogramList[threadId]->GetNthElement(j)->GetIndex(value, index);
286  if (!m_ThreadHistogramList[threadId]->GetNthElement(j)->IsIndexOutOfBounds(index))
287  {
288  // if the measurement vector is out of bound then
289  // the GetIndex method has returned an index set to the max size of
290  // the invalid dimension - even if the hvector is less than the minimum
291  // bin value.
292  // If the index isn't valid, we don't increase the frequency.
293  // See the comments in Histogram->GetIndex() for more info.
294  m_ThreadHistogramList[threadId]->GetNthElement(j)->IncreaseFrequencyOfIndex(index, 1);
295  }
296  }
297  }
298 
299  ++it;
300  progress.CompletedPixel();
301  }
302 }
303 
304 template <class TImage>
305 void PersistentHistogramVectorImageFilter<TImage>::PrintSelf(std::ostream& os, itk::Indent indent) const
306 {
307  Superclass::PrintSelf(os, indent);
308 
309  os << indent << "Histogram minimum: " << this->GetHistogramMin() << std::endl;
310  os << indent << "Histogram maximum: " << this->GetHistogramMax() << std::endl;
311  os << indent << "Number of bins: " << m_Size[0] << std::endl;
312  if (m_NoDataFlag)
313  {
314  os << indent << "Use NoData: true" << std::endl;
315  }
316  else
317  {
318  os << indent << "Use NoData: false" << std::endl;
319  }
320  os << indent << "NoData value: " << this->GetNoDataValue() << std::endl;
321 }
322 
323 } // end namespace otb
324 #endif
otb::ObjectList::Clear
void Clear(void)
Definition: otbObjectList.hxx:201
otb::ObjectList::PushBack
void PushBack(ObjectType *element)
Definition: otbObjectList.hxx:82
otb::PersistentHistogramVectorImageFilter::m_Size
CountVectorType m_Size
Definition: otbStreamingHistogramVectorImageFilter.h:194
otb::ObjectList::GetNthElement
ObjectPointerType GetNthElement(unsigned int index) const
Definition: otbObjectList.hxx:144
otb::PersistentHistogramVectorImageFilter::AllocateOutputs
void AllocateOutputs() override
Definition: otbStreamingHistogramVectorImageFilter.hxx:102
otb::PersistentHistogramVectorImageFilter::GenerateOutputInformation
void GenerateOutputInformation() override
Definition: otbStreamingHistogramVectorImageFilter.hxx:86
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::PersistentHistogramVectorImageFilter::Synthetize
void Synthetize(void) override
Definition: otbStreamingHistogramVectorImageFilter.hxx:187
otbMacro.h
otb::PersistentHistogramVectorImageFilter::RegionType
TInputImage::RegionType RegionType
Definition: otbStreamingHistogramVectorImageFilter.h:73
otb::PersistentHistogramVectorImageFilter::HistogramListPointerType
HistogramListType::Pointer HistogramListPointerType
Definition: otbStreamingHistogramVectorImageFilter.h:103
otb::PersistentHistogramVectorImageFilter::DataObjectPointerArraySizeType
itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType
Definition: otbStreamingHistogramVectorImageFilter.h:90
otb::PersistentHistogramVectorImageFilter::ThreadedGenerateData
void ThreadedGenerateData(const RegionType &outputRegionForThread, itk::ThreadIdType threadId) override
Definition: otbStreamingHistogramVectorImageFilter.hxx:217
otbStreamingHistogramVectorImageFilter.h
otb::PersistentHistogramVectorImageFilter::GetHistogramListOutput
HistogramListType * GetHistogramListOutput()
Definition: otbStreamingHistogramVectorImageFilter.hxx:73
otb::PersistentHistogramVectorImageFilter::InputImagePointer
TInputImage::Pointer InputImagePointer
Definition: otbStreamingHistogramVectorImageFilter.h:72
otb::PersistentHistogramVectorImageFilter::MakeOutput
DataObjectPointer MakeOutput(DataObjectPointerArraySizeType idx) override
Definition: otbStreamingHistogramVectorImageFilter.hxx:57
otb::PersistentHistogramVectorImageFilter::InternalPixelType
TInputImage::InternalPixelType InternalPixelType
Definition: otbStreamingHistogramVectorImageFilter.h:77
itk
Definition: otbNoDataHelper.h:31
otb::PersistentHistogramVectorImageFilter::HistogramType
itk::Statistics::Histogram< HistogramMeasurementRealType, DFContainerType > HistogramType
Definition: otbStreamingHistogramVectorImageFilter.h:97
otb::PersistentHistogramVectorImageFilter::Reset
void Reset(void) override
Definition: otbStreamingHistogramVectorImageFilter.hxx:112
otb::ObjectList
This class is a generic all-purpose wrapping around an std::vector<itk::SmartPointer<ObjectType> >.
Definition: otbObjectList.h:40
otb::PersistentHistogramVectorImageFilter::PixelType
TInputImage::PixelType PixelType
Definition: otbStreamingHistogramVectorImageFilter.h:76
otb::PersistentHistogramVectorImageFilter::PrintSelf
void PrintSelf(std::ostream &os, itk::Indent indent) const override
Definition: otbStreamingHistogramVectorImageFilter.hxx:305
otb::PersistentHistogramVectorImageFilter::PersistentHistogramVectorImageFilter
PersistentHistogramVectorImageFilter()
Definition: otbStreamingHistogramVectorImageFilter.hxx:35