22 #ifndef otbStreamingStatisticsImageFilter_hxx
23 #define otbStreamingStatisticsImageFilter_hxx
26 #include "itkImageRegionIterator.h"
27 #include "itkProgressReporter.h"
33 template <
class TInputImage>
35 : m_ThreadSum(1), m_SumOfSquares(1), m_Count(1), m_ThreadMin(1), m_ThreadMax(1), m_IgnoreInfiniteValues(true), m_IgnoreUserDefinedValue(false)
42 for (
int i = 1; i < 3; ++i)
45 this->itk::ProcessObject::SetNthOutput(i, output.GetPointer());
49 for (
int i = 3; i < 7; ++i)
52 this->itk::ProcessObject::SetNthOutput(i, output.GetPointer());
56 this->
GetMaximumOutput()->Set(itk::NumericTraits<PixelType>::NonpositiveMin());
57 this->
GetMeanOutput()->Set(itk::NumericTraits<RealType>::max());
60 this->
GetSumOutput()->Set(itk::NumericTraits<RealType>::Zero);
69 template <
class TInputImage>
75 return static_cast<itk::DataObject*
>(TInputImage::New().GetPointer());
78 return static_cast<itk::DataObject*
>(PixelObjectType::New().GetPointer());
81 return static_cast<itk::DataObject*
>(PixelObjectType::New().GetPointer());
87 return static_cast<itk::DataObject*
>(RealObjectType::New().GetPointer());
91 return static_cast<itk::DataObject*
>(TInputImage::New().GetPointer());
96 template <
class TInputImage>
99 return static_cast<PixelObjectType*
>(this->itk::ProcessObject::GetOutput(1));
102 template <
class TInputImage>
105 return static_cast<const PixelObjectType*
>(this->itk::ProcessObject::GetOutput(1));
108 template <
class TInputImage>
111 return static_cast<PixelObjectType*
>(this->itk::ProcessObject::GetOutput(2));
114 template <
class TInputImage>
117 return static_cast<const PixelObjectType*
>(this->itk::ProcessObject::GetOutput(2));
120 template <
class TInputImage>
123 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(3));
126 template <
class TInputImage>
129 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(3));
132 template <
class TInputImage>
135 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(4));
138 template <
class TInputImage>
141 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(4));
144 template <
class TInputImage>
147 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(5));
150 template <
class TInputImage>
153 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(5));
156 template <
class TInputImage>
159 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(6));
162 template <
class TInputImage>
165 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(6));
167 template <
class TInputImage>
170 Superclass::GenerateOutputInformation();
171 if (this->GetInput())
173 this->GetOutput()->CopyInformation(this->GetInput());
174 this->GetOutput()->SetLargestPossibleRegion(this->GetInput()->GetLargestPossibleRegion());
176 if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
178 this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
182 template <
class TInputImage>
192 template <
class TInputImage>
199 int numberOfThreads = this->GetNumberOfThreads();
204 RealType sigma = itk::NumericTraits<RealType>::Zero;
205 RealType variance = itk::NumericTraits<RealType>::Zero;
208 sum = sumOfSquares = itk::NumericTraits<RealType>::Zero;
213 minimum = itk::NumericTraits<PixelType>::max();
214 maximum = itk::NumericTraits<PixelType>::NonpositiveMin();
215 for (i = 0; i < numberOfThreads; ++i)
218 sum += m_ThreadSum[i];
219 sumOfSquares += m_SumOfSquares[i];
221 if (m_ThreadMin[i] < minimum)
223 minimum = m_ThreadMin[i];
225 if (m_ThreadMax[i] > maximum)
227 maximum = m_ThreadMax[i];
238 variance = (sumOfSquares - (sum * sum /
static_cast<RealType>(count))) /
static_cast<RealType>(count - 1);
239 sigma = std::sqrt(variance);
244 itkWarningMacro(<<
"No pixel found to compute statistics!");
248 this->GetMinimumOutput()->Set(minimum);
249 this->GetMaximumOutput()->Set(maximum);
250 this->GetMeanOutput()->Set(
mean);
251 this->GetSigmaOutput()->Set(sigma);
252 this->GetVarianceOutput()->Set(variance);
253 this->GetSumOutput()->Set(sum);
256 template <
class TInputImage>
259 int numberOfThreads = this->GetNumberOfThreads();
262 m_Count.SetSize(numberOfThreads);
263 m_SumOfSquares.SetSize(numberOfThreads);
264 m_ThreadSum.SetSize(numberOfThreads);
265 m_ThreadMin.SetSize(numberOfThreads);
266 m_ThreadMax.SetSize(numberOfThreads);
268 m_Count.Fill(itk::NumericTraits<long>::Zero);
269 m_ThreadSum.Fill(itk::NumericTraits<RealType>::Zero);
270 m_SumOfSquares.Fill(itk::NumericTraits<RealType>::Zero);
271 m_ThreadMin.Fill(itk::NumericTraits<PixelType>::max());
272 m_ThreadMax.Fill(itk::NumericTraits<PixelType>::NonpositiveMin());
273 if (m_IgnoreInfiniteValues)
275 m_IgnoredInfinitePixelCount = std::vector<unsigned int>(numberOfThreads, 0);
278 if (m_IgnoreUserDefinedValue)
280 m_IgnoredUserPixelCount = std::vector<unsigned int>(this->GetNumberOfThreads(), 0);
284 template <
class TInputImage>
292 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels());
298 itk::ImageRegionConstIterator<TInputImage> it(inputPtr, outputRegionForThread);
302 while (!it.IsAtEnd())
305 realValue =
static_cast<RealType>(value);
306 if (m_IgnoreInfiniteValues && !(vnl_math_isfinite(realValue)))
308 m_IgnoredInfinitePixelCount[threadId]++;
312 if (m_IgnoreUserDefinedValue && (value == m_UserIgnoredValue))
314 m_IgnoredUserPixelCount[threadId]++;
318 if (value < m_ThreadMin[threadId])
320 m_ThreadMin[threadId] = value;
322 if (value > m_ThreadMax[threadId])
324 m_ThreadMax[threadId] = value;
327 m_ThreadSum[threadId] += realValue;
328 m_SumOfSquares[threadId] += (realValue * realValue);
333 progress.CompletedPixel();
336 template <
class TImage>
339 Superclass::PrintSelf(os, indent);
341 os << indent <<
"Minimum: " <<
static_cast<typename itk::NumericTraits<PixelType>::PrintType
>(this->GetMinimum()) << std::endl;
342 os << indent <<
"Maximum: " <<
static_cast<typename itk::NumericTraits<PixelType>::PrintType
>(this->GetMaximum()) << std::endl;
343 os << indent <<
"Sum: " << this->GetSum() << std::endl;
344 os << indent <<
"Mean: " << this->GetMean() << std::endl;
345 os << indent <<
"Sigma: " << this->GetSigma() << std::endl;
346 os << indent <<
"Variance: " << this->GetVariance() << std::endl;