Orfeo Toolbox  4.2
otbStreamingMinMaxImageFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: ORFEO Toolbox
4  Language: C++
5  Date: $Date$
6  Version: $Revision$
7 
8 
9  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
10  See OTBCopyright.txt for details.
11 
12 Some parts of this code are derived from ITK. See ITKCopyright.txt
13 for details.
14 
15 
16  This software is distributed WITHOUT ANY WARRANTY; without even
17  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
18  PURPOSE. See the above copyright notices for more information.
19 
20 =========================================================================*/
21 #ifndef __otbStreamingMinMaxImageFilter_txx
22 #define __otbStreamingMinMaxImageFilter_txx
24 
25 #include <algorithm>
26 #include "itkImageRegionIterator.h"
28 #include "itkNumericTraits.h"
29 #include "itkProgressReporter.h"
30 #include "otbMacro.h"
31 
32 namespace otb
33 {
34 
35 template<class TInputImage>
38 {
39  // TODO : SetNumberOfRequiredOutputs
40 
41  // first output is a copy of the image, DataObject created by
42  // superclass
43  //
44  // allocate the data objects for the outputs which are
45  // just decorators around pixel & index types
46  for (int i = 1; i < 5; ++i)
47  {
48  this->itk::ProcessObject::SetNthOutput(i, this->MakeOutput(i));
49  }
50 
51  this->GetMinimumOutput()->Set(itk::NumericTraits<PixelType>::max());
52  this->GetMaximumOutput()->Set(itk::NumericTraits<PixelType>::NonpositiveMin());
53 
54  this->Reset();
55 }
56 
57 template<class TInputImage>
60 ::MakeOutput(unsigned int output)
61 {
63  switch (output)
64  {
65  case 0:
66  ret = static_cast<itk::DataObject*>(TInputImage::New().GetPointer());
67  break;
68  case 1:
69  case 2:
70  ret = static_cast<itk::DataObject*>(PixelObjectType::New().GetPointer());
71  break;
72  case 3:
73  case 4:
74  ret = static_cast<itk::DataObject*>(IndexObjectType::New().GetPointer());
75  break;
76  }
77  return ret;
78 }
79 
80 template<class TInputImage>
84 {
85  return static_cast<PixelObjectType*>(this->itk::ProcessObject::GetOutput(1));
86 }
87 
88 template<class TInputImage>
92 {
93  return static_cast<const PixelObjectType*>(this->itk::ProcessObject::GetOutput(1));
94 }
95 
96 template<class TInputImage>
100 {
101  return static_cast<PixelObjectType*>(this->itk::ProcessObject::GetOutput(2));
102 }
103 
104 template<class TInputImage>
108 {
109  return static_cast<const PixelObjectType*>(this->itk::ProcessObject::GetOutput(2));
110 }
111 
112 
113 template<class TInputImage>
117 {
118  return static_cast<IndexObjectType*>(this->itk::ProcessObject::GetOutput(3));
119 }
120 
121 template<class TInputImage>
125 {
126  return static_cast<const IndexObjectType*>(this->itk::ProcessObject::GetOutput(3));
127 }
128 
129 template<class TInputImage>
133 {
134  return static_cast<IndexObjectType*>(this->itk::ProcessObject::GetOutput(4));
135 }
136 
137 template<class TInputImage>
141 {
142  return static_cast<const IndexObjectType*>(this->itk::ProcessObject::GetOutput(4));
143 }
144 
145 template<class TInputImage>
146 void
149 {
150  Superclass::GenerateOutputInformation();
151  if (this->GetInput())
152  {
153  this->GetOutput()->CopyInformation(this->GetInput());
154  this->GetOutput()->SetLargestPossibleRegion(this->GetInput()->GetLargestPossibleRegion());
155 
156  if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
157  {
158  this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
159  }
160  }
161 }
162 template<class TInputImage>
163 void
166 {
167  // This is commented to prevent the streaming of the whole image for the first stream strip
168  // It shall not cause any problem because the output image of this filter is not intended to be used.
169  //InputImagePointer image = const_cast< TInputImage * >( this->GetInput() );
170  //this->GraftOutput( image );
171  // Nothing that needs to be allocated for the remaining outputs
172 }
173 
174 template<class TInputImage>
175 void
178 {
179  int i;
180  int numberOfThreads = this->GetNumberOfThreads();
181 
184  IndexType minimumIdx;
185  IndexType maximumIdx;
186 
187  for (i = 0; i < numberOfThreads; ++i)
188  {
189  if (m_ThreadMin[i] < minimum)
190  {
191  minimum = m_ThreadMin[i];
192  minimumIdx = m_ThreadMinIndex[i];
193  }
194  if (m_ThreadMax[i] > maximum)
195  {
196  maximum = m_ThreadMax[i];
197  maximumIdx = m_ThreadMaxIndex[i];
198  }
199  }
200 
201  // Set the outputs
202  this->GetMinimumOutput()->Set(minimum);
203  this->GetMaximumOutput()->Set(maximum);
204  this->GetMinimumIndexOutput()->Set(minimumIdx);
205  this->GetMaximumIndexOutput()->Set(maximumIdx);
206 }
207 
208 template<class TInputImage>
209 void
212 {
213  int numberOfThreads = this->GetNumberOfThreads();
214 
215  m_ThreadMin.resize(numberOfThreads);
216  m_ThreadMax.resize(numberOfThreads);
217  std::fill(m_ThreadMin.begin(), m_ThreadMin.end(), itk::NumericTraits<PixelType>::max());
218  std::fill(m_ThreadMax.begin(), m_ThreadMax.end(), itk::NumericTraits<PixelType>::NonpositiveMin());
219 
220  IndexType zeroIdx;
221  zeroIdx.Fill(0);
222  m_ThreadMinIndex.resize(numberOfThreads);
223  m_ThreadMaxIndex.resize(numberOfThreads);
224  std::fill(m_ThreadMinIndex.begin(), m_ThreadMinIndex.end(), zeroIdx);
225  std::fill(m_ThreadMaxIndex.begin(), m_ThreadMaxIndex.end(), zeroIdx);
226 }
227 
228 template<class TInputImage>
229 void
231 ::ThreadedGenerateData(const RegionType& outputRegionForThread,
232  itk::ThreadIdType threadId)
233 {
234  // support progress methods/callbacks
235  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
236 
237  InputImagePointer inputPtr = const_cast<TInputImage *>(this->GetInput(0));
238  itk::ImageRegionConstIterator<TInputImage> it(inputPtr, outputRegionForThread);
239  it.GoToBegin();
240  // do the work
241  while (!it.IsAtEnd())
242  {
243  PixelType value = it.Get();
244  if (value < m_ThreadMin[threadId])
245  {
246  m_ThreadMin[threadId] = value;
247  m_ThreadMinIndex[threadId] = it.GetIndex();
248  }
249  if (value > m_ThreadMax[threadId])
250  {
251  m_ThreadMax[threadId] = value;
252  m_ThreadMaxIndex[threadId] = it.GetIndex();
253  }
254  ++it;
255  progress.CompletedPixel();
256  }
257 }
258 
259 template <class TImage>
260 void
262 ::PrintSelf(std::ostream& os, itk::Indent indent) const
263 {
264  Superclass::PrintSelf(os, indent);
265 
266  os << indent << "Minimum: "
267  << static_cast<typename itk::NumericTraits<PixelType>::PrintType>(this->GetMinimum()) << std::endl;
268  os << indent << "Maximum: "
269  << static_cast<typename itk::NumericTraits<PixelType>::PrintType>(this->GetMaximum()) << std::endl;
270  os << indent << "Minimum Index: " << this->GetMinimumIndex() << std::endl;
271  os << indent << "Maximum Index: " << this->GetMaximumIndex() << std::endl;
272 }
273 
274 } // end namespace otb
275 #endif

Generated at Sat Jul 19 2014 16:25:42 for Orfeo Toolbox with doxygen 1.8.3.1