22 #ifndef otbStreamingStatisticsImageFilter_hxx
23 #define otbStreamingStatisticsImageFilter_hxx
26 #include "itkImageRegionIterator.h"
27 #include "itkProgressReporter.h"
29 #include "vcl_legacy_aliases.h"
34 template<
class TInputImage>
42 m_IgnoreInfiniteValues(true),
43 m_IgnoreUserDefinedValue(false)
45 this->DynamicMultiThreadingOff();
51 for (
int i = 1; i < 3; ++i)
53 typename PixelObjectType::Pointer output =
static_cast<PixelObjectType*
>(this->MakeOutput(i).GetPointer());
54 this->itk::ProcessObject::SetNthOutput(i, output.GetPointer());
58 for (
int i = 3; i < 7; ++i)
60 typename RealObjectType::Pointer output =
static_cast<RealObjectType*
>(this->MakeOutput(i).GetPointer());
61 this->itk::ProcessObject::SetNthOutput(i, output.GetPointer());
64 this->GetMinimumOutput()->Set(itk::NumericTraits<PixelType>::max());
65 this->GetMaximumOutput()->Set(itk::NumericTraits<PixelType>::NonpositiveMin());
66 this->GetMeanOutput()->Set(itk::NumericTraits<RealType>::max());
67 this->GetSigmaOutput()->Set(itk::NumericTraits<RealType>::max());
68 this->GetVarianceOutput()->Set(itk::NumericTraits<RealType>::max());
69 this->GetSumOutput()->Set(itk::NumericTraits<RealType>::Zero);
72 m_IgnoredInfinitePixelCount = std::vector<unsigned int>(this->GetNumberOfWorkUnits(), 0);
73 m_IgnoredUserPixelCount = std::vector<unsigned int>(this->GetNumberOfWorkUnits(), 0);
78 template <
class TInputImage>
84 return static_cast<itk::DataObject*
>(TInputImage::New().GetPointer());
87 return static_cast<itk::DataObject*
>(PixelObjectType::New().GetPointer());
90 return static_cast<itk::DataObject*
>(PixelObjectType::New().GetPointer());
96 return static_cast<itk::DataObject*
>(RealObjectType::New().GetPointer());
100 return static_cast<itk::DataObject*
>(TInputImage::New().GetPointer());
105 template <
class TInputImage>
108 return static_cast<PixelObjectType*
>(this->itk::ProcessObject::GetOutput(1));
111 template <
class TInputImage>
114 return static_cast<const PixelObjectType*
>(this->itk::ProcessObject::GetOutput(1));
117 template <
class TInputImage>
120 return static_cast<PixelObjectType*
>(this->itk::ProcessObject::GetOutput(2));
123 template <
class TInputImage>
126 return static_cast<const PixelObjectType*
>(this->itk::ProcessObject::GetOutput(2));
129 template <
class TInputImage>
132 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(3));
135 template <
class TInputImage>
138 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(3));
141 template <
class TInputImage>
144 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(4));
147 template <
class TInputImage>
150 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(4));
153 template <
class TInputImage>
156 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(5));
159 template <
class TInputImage>
162 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(5));
165 template <
class TInputImage>
168 return static_cast<RealObjectType*
>(this->itk::ProcessObject::GetOutput(6));
171 template <
class TInputImage>
174 return static_cast<const RealObjectType*
>(this->itk::ProcessObject::GetOutput(6));
176 template <
class TInputImage>
179 Superclass::GenerateOutputInformation();
180 if (this->GetInput())
182 this->GetOutput()->CopyInformation(this->GetInput());
183 this->GetOutput()->SetLargestPossibleRegion(this->GetInput()->GetLargestPossibleRegion());
185 if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
187 this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
191 template <
class TInputImage>
201 template <
class TInputImage>
208 int numberOfThreads = this->GetNumberOfWorkUnits();
213 RealType sigma = itk::NumericTraits<RealType>::Zero;
214 RealType variance = itk::NumericTraits<RealType>::Zero;
217 sum = sumOfSquares = itk::NumericTraits<RealType>::Zero;
222 minimum = itk::NumericTraits<PixelType>::max();
223 maximum = itk::NumericTraits<PixelType>::NonpositiveMin();
224 for (i = 0; i < numberOfThreads; ++i)
227 sum += m_ThreadSum[i];
228 sumOfSquares += m_SumOfSquares[i];
230 if (m_ThreadMin[i] < minimum)
232 minimum = m_ThreadMin[i];
234 if (m_ThreadMax[i] > maximum)
236 maximum = m_ThreadMax[i];
247 variance = (sumOfSquares - (sum * sum /
static_cast<RealType>(count))) /
static_cast<RealType>(count - 1);
248 sigma = std::sqrt(variance);
253 itkWarningMacro(<<
"No pixel found to compute statistics!");
257 this->GetMinimumOutput()->Set(minimum);
258 this->GetMaximumOutput()->Set(maximum);
259 this->GetMeanOutput()->Set(
mean);
260 this->GetSigmaOutput()->Set(sigma);
261 this->GetVarianceOutput()->Set(variance);
262 this->GetSumOutput()->Set(sum);
265 template <
class TInputImage>
268 int numberOfThreads = this->GetNumberOfWorkUnits();
271 m_Count.SetSize(numberOfThreads);
272 m_SumOfSquares.SetSize(numberOfThreads);
273 m_ThreadSum.SetSize(numberOfThreads);
274 m_ThreadMin.SetSize(numberOfThreads);
275 m_ThreadMax.SetSize(numberOfThreads);
277 m_Count.Fill(itk::NumericTraits<long>::Zero);
278 m_ThreadSum.Fill(itk::NumericTraits<RealType>::Zero);
279 m_SumOfSquares.Fill(itk::NumericTraits<RealType>::Zero);
280 m_ThreadMin.Fill(itk::NumericTraits<PixelType>::max());
281 m_ThreadMax.Fill(itk::NumericTraits<PixelType>::NonpositiveMin());
282 if (m_IgnoreInfiniteValues)
284 m_IgnoredInfinitePixelCount = std::vector<unsigned int>(numberOfThreads, 0);
287 if (m_IgnoreUserDefinedValue)
289 m_IgnoredUserPixelCount = std::vector<unsigned int>(this->GetNumberOfWorkUnits(), 0);
293 template <
class TInputImage>
301 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels());
307 itk::ImageRegionConstIterator<TInputImage> it(inputPtr, outputRegionForThread);
311 while (!it.IsAtEnd())
314 realValue =
static_cast<RealType>(value);
315 if (m_IgnoreInfiniteValues && !(vnl_math_isfinite(realValue)))
317 m_IgnoredInfinitePixelCount[threadId]++;
321 if (m_IgnoreUserDefinedValue && (value == m_UserIgnoredValue))
323 m_IgnoredUserPixelCount[threadId]++;
327 if (value < m_ThreadMin[threadId])
329 m_ThreadMin[threadId] = value;
331 if (value > m_ThreadMax[threadId])
333 m_ThreadMax[threadId] = value;
336 m_ThreadSum[threadId] += realValue;
337 m_SumOfSquares[threadId] += (realValue * realValue);
342 progress.CompletedPixel();
345 template <
class TImage>
348 Superclass::PrintSelf(os, indent);
350 os << indent <<
"Minimum: " <<
static_cast<typename itk::NumericTraits<PixelType>::PrintType
>(this->GetMinimum()) << std::endl;
351 os << indent <<
"Maximum: " <<
static_cast<typename itk::NumericTraits<PixelType>::PrintType
>(this->GetMaximum()) << std::endl;
352 os << indent <<
"Sum: " << this->GetSum() << std::endl;
353 os << indent <<
"Mean: " << this->GetMean() << std::endl;
354 os << indent <<
"Sigma: " << this->GetSigma() << std::endl;
355 os << indent <<
"Variance: " << this->GetVariance() << std::endl;
void PrintSelf(std::ostream &os, itk::Indent indent) const override
void GenerateOutputInformation() override
void AllocateOutputs() override
DataObjectPointer MakeOutput(DataObjectPointerArraySizeType idx) override
PixelObjectType * GetMinimumOutput()
void ThreadedGenerateData(const RegionType &outputRegionForThread, itk::ThreadIdType threadId) override
itk::SimpleDataObjectDecorator< PixelType > PixelObjectType
RealObjectType * GetSigmaOutput()
PersistentStatisticsImageFilter()
itk::SimpleDataObjectDecorator< RealType > RealObjectType
RealObjectType * GetMeanOutput()
void Synthetize(void) override
itk::NumericTraits< PixelType >::RealType RealType
TInputImage::PixelType PixelType
itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType
TInputImage::Pointer InputImagePointer
PixelObjectType * GetMaximumOutput()
RealObjectType * GetSumOutput()
void Reset(void) override
RealObjectType * GetVarianceOutput()
TInputImage::RegionType RegionType
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.