OTB  7.2.0
Orfeo Toolbox
otbStreamingMinMaxVectorImageFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1999-2011 Insight Software Consortium
3  * Copyright (C) 2005-2020 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 otbStreamingMinMaxVectorImageFilter_hxx
23 #define otbStreamingMinMaxVectorImageFilter_hxx
25 
26 #include "itkImageRegionIterator.h"
27 #include "itkImageRegionConstIteratorWithIndex.h"
28 #include "itkNumericTraits.h"
29 #include "itkProgressReporter.h"
30 #include "otbMacro.h"
31 
32 namespace otb
33 {
34 
35 template <class TInputImage>
37  : m_NoDataFlag(false), m_NoDataValue(itk::NumericTraits<InternalPixelType>::Zero)
38 {
39  // first output is a copy of the image, DataObject created by
40  // superclass
41  //
42  // allocate the data objects for the outputs which are
43  // just decorators around pixel types
44 
45  for (int i = 1; i < 3; ++i)
46  {
47  typename PixelObjectType::Pointer output = static_cast<PixelObjectType*>(this->MakeOutput(i).GetPointer());
48  this->itk::ProcessObject::SetNthOutput(i, output.GetPointer());
49  }
50 }
51 
52 template <class TInputImage>
54 {
55  itk::DataObject::Pointer ret;
56  switch (output)
57  {
58  case 0:
59  ret = static_cast<itk::DataObject*>(TInputImage::New().GetPointer());
60  break;
61  case 1:
62  case 2:
63  ret = static_cast<itk::DataObject*>(PixelObjectType::New().GetPointer());
64  break;
65  }
66  return ret;
67 }
68 
69 template <class TInputImage>
71 {
72  return static_cast<PixelObjectType*>(this->itk::ProcessObject::GetOutput(1));
73 }
74 
75 template <class TInputImage>
77 {
78  return static_cast<const PixelObjectType*>(this->itk::ProcessObject::GetOutput(1));
79 }
80 
81 template <class TInputImage>
83 {
84  return static_cast<PixelObjectType*>(this->itk::ProcessObject::GetOutput(2));
85 }
86 
87 template <class TInputImage>
89 {
90  return static_cast<const PixelObjectType*>(this->itk::ProcessObject::GetOutput(2));
91 }
92 
93 template <class TInputImage>
95 {
96  Superclass::GenerateOutputInformation();
97  if (this->GetInput())
98  {
99  this->GetOutput()->CopyInformation(this->GetInput());
100  this->GetOutput()->SetLargestPossibleRegion(this->GetInput()->GetLargestPossibleRegion());
101 
102  if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
103  {
104  this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
105  }
106  }
107 }
108 
109 template <class TInputImage>
111 {
112  // This is commented to prevent the streaming of the whole image for the first stream strip
113  // It shall not cause any problem because the output image of this filter is not intended to be used.
114  // InputImagePointer image = const_cast< TInputImage * >( this->GetInput() );
115  // this->GraftOutput( image );
116  // Nothing that needs to be allocated for the remaining outputs
117 }
118 
119 template <class TInputImage>
121 {
122  TInputImage* inputPtr = const_cast<TInputImage*>(this->GetInput());
123  inputPtr->UpdateOutputInformation();
124 
125  unsigned int numberOfThreads = this->GetNumberOfThreads();
126  unsigned int numberOfComponent = inputPtr->GetNumberOfComponentsPerPixel();
127 
128  // Variable Initialization
129  PixelType tempPixel;
130  tempPixel.SetSize(numberOfComponent);
131  tempPixel.Fill(itk::NumericTraits<InternalPixelType>::NonpositiveMin());
132  this->GetMaximumOutput()->Set(tempPixel);
133 
134  tempPixel.Fill(itk::NumericTraits<InternalPixelType>::max());
135  this->GetMinimumOutput()->Set(tempPixel);
136 
137  PixelType tempTemporiesPixel;
138  tempTemporiesPixel.SetSize(numberOfComponent);
139  tempTemporiesPixel.Fill(itk::NumericTraits<InternalPixelType>::max());
140  m_ThreadMin = ArrayPixelType(numberOfThreads, tempTemporiesPixel);
141 
142  tempTemporiesPixel.Fill(itk::NumericTraits<InternalPixelType>::NonpositiveMin());
143  m_ThreadMax = ArrayPixelType(numberOfThreads, tempTemporiesPixel);
144 }
145 
146 template <class TInputImage>
148 {
149  int i;
150 
151  int numberOfThreads = this->GetNumberOfThreads();
152  unsigned int numberOfComponent = this->GetInput()->GetNumberOfComponentsPerPixel();
153 
154  PixelType minimumVector;
155  minimumVector.SetSize(numberOfComponent);
156  minimumVector.Fill(itk::NumericTraits<InternalPixelType>::max());
157 
158  PixelType maximumVector;
159  maximumVector.SetSize(numberOfComponent);
160  maximumVector.Fill(itk::NumericTraits<InternalPixelType>::NonpositiveMin());
161 
162  // Find the min/max over all threads and accumulate count, sum and
163  // sum of squares
164  for (i = 0; i < numberOfThreads; ++i)
165  {
166  for (unsigned int j = 0; j < numberOfComponent; ++j)
167  {
168  if (m_ThreadMin[i][j] < minimumVector[j])
169  {
170  minimumVector[j] = m_ThreadMin[i][j];
171  }
172  if (m_ThreadMax[i][j] > maximumVector[j])
173  {
174  maximumVector[j] = m_ThreadMax[i][j];
175  }
176  }
177  } // end for( i = 0; i < numberOfThreads; ++i)
178 
179  // Set the outputs
180  this->GetMinimumOutput()->Set(minimumVector);
181  this->GetMaximumOutput()->Set(maximumVector);
182 }
183 
184 template <class TInputImage>
185 void PersistentMinMaxVectorImageFilter<TInputImage>::ThreadedGenerateData(const RegionType& outputRegionForThread, itk::ThreadIdType threadId)
186 {
190  InputImagePointer inputPtr = const_cast<TInputImage*>(this->GetInput());
191  // support progress methods/callbacks
192  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
194 
195  itk::ImageRegionConstIteratorWithIndex<TInputImage> it(inputPtr, outputRegionForThread);
196  it.GoToBegin();
197 
198  // do the work
199  while (!it.IsAtEnd())
200  {
201  // IndexType index = it.GetIndex();
202  PixelType vectorValue = it.Get();
203  for (unsigned int j = 0; j < vectorValue.GetSize(); ++j)
204  {
205  InternalPixelType value = vectorValue[j];
206 
207  if ((!m_NoDataFlag) || value != m_NoDataValue)
208  {
209  if (value < m_ThreadMin[threadId][j])
210  {
211  m_ThreadMin[threadId][j] = value;
212  }
213  if (value > m_ThreadMax[threadId][j])
214  {
215  m_ThreadMax[threadId][j] = value;
216  }
217  }
218  }
219  ++it;
220  progress.CompletedPixel();
221  }
222 }
223 
224 template <class TImage>
225 void PersistentMinMaxVectorImageFilter<TImage>::PrintSelf(std::ostream& os, itk::Indent indent) const
226 {
227  Superclass::PrintSelf(os, indent);
228 
229  os << indent << "Minimum: " << this->GetMinimumOutput()->Get() << std::endl;
230  os << indent << "Maximum: " << this->GetMaximumOutput()->Get() << std::endl;
231 }
232 
233 } // end namespace otb
234 #endif
void PrintSelf(std::ostream &os, itk::Indent indent) const override
void PrintSelf(std::ostream &os, itk::Indent indent) const override
DataObjectPointer MakeOutput(DataObjectPointerArraySizeType idx) override
itk::SimpleDataObjectDecorator< PixelType > PixelObjectType
itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType
void ThreadedGenerateData(const RegionType &outputRegionForThread, itk::ThreadIdType threadId) override
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
static constexpr GLenum value() noexcept