18 #ifndef __otbStreamingStatisticsVectorImageFilter_txx
19 #define __otbStreamingStatisticsVectorImageFilter_txx
24 #include "itkNumericTraits.h"
31 template<
class TInputImage,
class TPrecision>
34 : m_EnableMinMax(true),
35 m_EnableFirstOrderStats(true),
36 m_EnableSecondOrderStats(true),
37 m_UseUnbiasedEstimator(true)
44 for (
unsigned int i = 1; i < 10; ++i)
50 template<
class TInputImage,
class TPrecision>
63 return static_cast<itk::DataObject*
>(PixelObjectType::New().GetPointer());
68 return static_cast<itk::DataObject*
>(RealPixelObjectType::New().GetPointer());
73 return static_cast<itk::DataObject*
>(MatrixObjectType::New().GetPointer());
79 return static_cast<itk::DataObject*
>(RealObjectType::New().GetPointer());
88 template<
class TInputImage,
class TPrecision>
96 template<
class TInputImage,
class TPrecision>
104 template<
class TInputImage,
class TPrecision>
112 template<
class TInputImage,
class TPrecision>
120 template<
class TInputImage,
class TPrecision>
128 template<
class TInputImage,
class TPrecision>
136 template<
class TInputImage,
class TPrecision>
144 template<
class TInputImage,
class TPrecision>
153 template<
class TInputImage,
class TPrecision>
161 template<
class TInputImage,
class TPrecision>
169 template<
class TInputImage,
class TPrecision>
177 template<
class TInputImage,
class TPrecision>
185 template<
class TInputImage,
class TPrecision>
193 template<
class TInputImage,
class TPrecision>
201 template<
class TInputImage,
class TPrecision>
209 template<
class TInputImage,
class TPrecision>
217 template<
class TInputImage,
class TPrecision>
225 template<
class TInputImage,
class TPrecision>
233 template<
class TInputImage,
class TPrecision>
238 Superclass::GenerateOutputInformation();
239 if (this->GetInput())
241 this->GetOutput()->CopyInformation(this->GetInput());
242 this->GetOutput()->SetLargestPossibleRegion(this->GetInput()->GetLargestPossibleRegion());
244 if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
246 this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
251 template<
class TInputImage,
class TPrecision>
263 template<
class TInputImage,
class TPrecision>
268 TInputImage * inputPtr =
const_cast<TInputImage *
>(this->GetInput());
269 inputPtr->UpdateOutputInformation();
271 unsigned int numberOfThreads = this->GetNumberOfThreads();
272 unsigned int numberOfComponent = inputPtr->GetNumberOfComponentsPerPixel();
277 tempPixel.SetSize(numberOfComponent);
279 tempPixel.Fill(itk::NumericTraits<InternalPixelType>::max());
280 this->GetMinimumOutput()->Set(tempPixel);
282 tempPixel.Fill(itk::NumericTraits<InternalPixelType>::NonpositiveMin());
283 this->GetMaximumOutput()->Set(tempPixel);
286 tempTemporiesPixel.SetSize(numberOfComponent);
287 tempTemporiesPixel.Fill(itk::NumericTraits<InternalPixelType>::max());
288 m_ThreadMin = std::vector<PixelType>(numberOfThreads, tempTemporiesPixel);
290 tempTemporiesPixel.Fill(itk::NumericTraits<InternalPixelType>::NonpositiveMin());
291 m_ThreadMax = std::vector<PixelType>(numberOfThreads, tempTemporiesPixel);
294 if (m_EnableSecondOrderStats)
296 m_EnableFirstOrderStats =
true;
299 if (m_EnableFirstOrderStats)
302 zeroRealPixel.
SetSize(numberOfComponent);
303 zeroRealPixel.
Fill(itk::NumericTraits<PrecisionType>::ZeroValue());
304 this->GetMeanOutput()->Set(zeroRealPixel);
305 this->GetSumOutput()->Set(zeroRealPixel);
306 m_ThreadFirstOrderAccumulators.resize(numberOfThreads);
307 std::fill(m_ThreadFirstOrderAccumulators.begin(), m_ThreadFirstOrderAccumulators.end(), zeroRealPixel);
309 RealType zeroReal = itk::NumericTraits<RealType>::ZeroValue();
310 m_ThreadFirstOrderComponentAccumulators.resize(numberOfThreads);
311 std::fill(m_ThreadFirstOrderComponentAccumulators.begin(), m_ThreadFirstOrderComponentAccumulators.end(), zeroReal);
315 if (m_EnableSecondOrderStats)
318 zeroMatrix.
SetSize(numberOfComponent, numberOfComponent);
319 zeroMatrix.
Fill(itk::NumericTraits<PrecisionType>::Zero);
320 this->GetCovarianceOutput()->Set(zeroMatrix);
321 this->GetCorrelationOutput()->Set(zeroMatrix);
323 m_ThreadSecondOrderAccumulators.resize(numberOfThreads);
324 std::fill(m_ThreadSecondOrderAccumulators.begin(), m_ThreadSecondOrderAccumulators.end(), zeroMatrix);
326 RealType zeroReal = itk::NumericTraits<RealType>::ZeroValue();
327 m_ThreadSecondOrderComponentAccumulators.resize(numberOfThreads);
328 std::fill(m_ThreadSecondOrderComponentAccumulators.begin(), m_ThreadSecondOrderComponentAccumulators.end(), zeroReal);
333 template<
class TInputImage,
class TPrecision>
338 TInputImage * inputPtr =
const_cast<TInputImage *
>(this->GetInput());
339 const unsigned int nbPixels = inputPtr->GetLargestPossibleRegion().GetNumberOfPixels();
340 const unsigned int numberOfComponent = inputPtr->GetNumberOfComponentsPerPixel();
343 minimum.SetSize(numberOfComponent);
344 minimum.Fill(itk::NumericTraits<InternalPixelType>::max());
346 maximum.SetSize(numberOfComponent);
347 maximum.Fill(itk::NumericTraits<InternalPixelType>::NonpositiveMin());
349 RealPixelType streamFirstOrderAccumulator(numberOfComponent);
350 streamFirstOrderAccumulator.
Fill(itk::NumericTraits<PrecisionType>::Zero);
351 MatrixType streamSecondOrderAccumulator(numberOfComponent, numberOfComponent);
352 streamSecondOrderAccumulator.
Fill(itk::NumericTraits<PrecisionType>::Zero);
354 RealType streamFirstOrderComponentAccumulator = itk::NumericTraits<RealType>::Zero;
355 RealType streamSecondOrderComponentAccumulator = itk::NumericTraits<RealType>::Zero;
358 const unsigned int numberOfThreads = this->GetNumberOfThreads();
359 for (
unsigned int threadId = 0; threadId < numberOfThreads; ++threadId)
363 const PixelType& threadMin = m_ThreadMin [threadId];
364 const PixelType& threadMax = m_ThreadMax [threadId];
366 for (
unsigned int j = 0; j < numberOfComponent; ++j)
368 if (threadMin[j] < minimum[j])
370 minimum[j] = threadMin[j];
372 if (threadMax[j] > maximum[j])
374 maximum[j] = threadMax[j];
379 if (m_EnableFirstOrderStats)
381 streamFirstOrderAccumulator += m_ThreadFirstOrderAccumulators[threadId];
382 streamFirstOrderComponentAccumulator += m_ThreadFirstOrderComponentAccumulators[threadId];
385 if (m_EnableSecondOrderStats)
387 streamSecondOrderAccumulator += m_ThreadSecondOrderAccumulators[threadId];
388 streamSecondOrderComponentAccumulator += m_ThreadSecondOrderComponentAccumulators[threadId];
395 this->GetMinimumOutput()->Set(minimum);
396 this->GetMaximumOutput()->Set(maximum);
399 if (m_EnableFirstOrderStats)
401 this->GetComponentMeanOutput()->Set(streamFirstOrderComponentAccumulator / (nbPixels * numberOfComponent));
403 this->GetMeanOutput()->Set(streamFirstOrderAccumulator / nbPixels);
404 this->GetSumOutput()->Set(streamFirstOrderAccumulator);
407 if (m_EnableSecondOrderStats)
410 MatrixType cor = streamSecondOrderAccumulator / nbPixels;
411 this->GetCorrelationOutput()->Set(cor);
414 double regul =
static_cast<double>(nbPixels) / (nbPixels - 1);
416 if (!m_UseUnbiasedEstimator)
422 for (
unsigned int r = 0; r < numberOfComponent; ++r)
424 for (
unsigned int c = 0; c < numberOfComponent; ++c)
426 cov(r, c) = regul * (cov(r, c) - mean[r] * mean[c]);
429 this->GetCovarianceOutput()->Set(cov);
431 this->GetComponentMeanOutput()->Set(streamFirstOrderComponentAccumulator / (nbPixels * numberOfComponent));
432 this->GetComponentCorrelationOutput()->Set(streamSecondOrderComponentAccumulator / (nbPixels * numberOfComponent));
433 this->GetComponentCovarianceOutput()->Set(
434 (nbPixels * numberOfComponent) / (nbPixels * numberOfComponent - 1)
435 * (this->GetComponentCorrelation()
436 - (this->GetComponentMean() * this->GetComponentMean())));
440 template<
class TInputImage,
class TPrecision>
450 PixelType& threadMin = m_ThreadMin [threadId];
451 PixelType& threadMax = m_ThreadMax [threadId];
462 for (
unsigned int j = 0; j < vectorValue.GetSize(); ++j)
464 if (vectorValue[j] < threadMin[j])
466 threadMin[j] = vectorValue[j];
468 if (vectorValue[j] > threadMax[j])
470 threadMax[j] = vectorValue[j];
475 if (m_EnableFirstOrderStats)
477 RealPixelType& threadFirstOrder = m_ThreadFirstOrderAccumulators [threadId];
478 RealType& threadFirstOrderComponent = m_ThreadFirstOrderComponentAccumulators [threadId];
480 threadFirstOrder += vectorValue;
482 for (
unsigned int i = 0; i < vectorValue.GetSize(); ++i)
484 threadFirstOrderComponent += vectorValue[i];
488 if (m_EnableSecondOrderStats)
490 MatrixType& threadSecondOrder = m_ThreadSecondOrderAccumulators[threadId];
491 RealType& threadSecondOrderComponent = m_ThreadSecondOrderComponentAccumulators[threadId];
493 for (
unsigned int r = 0; r < threadSecondOrder.
Rows(); ++r)
495 for (
unsigned int c = 0; c < threadSecondOrder.
Cols(); ++c)
497 threadSecondOrder(r, c) += vectorValue[r] * vectorValue[c];
500 threadSecondOrderComponent += vectorValue.GetSquaredNorm();
506 template <
class TImage,
class TPrecision>
511 Superclass::PrintSelf(os, indent);
513 os << indent <<
"Min: " << this->GetMinimumOutput()->Get() << std::endl;
514 os << indent <<
"Max: " << this->GetMaximumOutput()->Get() << std::endl;
515 os << indent <<
"Mean: " << this->GetMeanOutput()->Get() << std::endl;
516 os << indent <<
"Covariance: " << this->GetCovarianceOutput()->Get() << std::endl;
517 os << indent <<
"Correlation: " << this->GetCorrelationOutput()->Get() << std::endl;
518 os << indent <<
"Component Mean: " << this->GetComponentMeanOutput()->Get() << std::endl;
519 os << indent <<
"Component Covariance: " << this->GetComponentCovarianceOutput()->Get() << std::endl;
520 os << indent <<
"Component Correlation: " << this->GetComponentCorrelationOutput()->Get() << std::endl;
521 os << indent <<
"UseUnbiasedEstimator: " << (this->m_UseUnbiasedEstimator ?
"true" :
"false") << std::endl;