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),
38 m_IgnoreInfiniteValues(true),
39 m_IgnoreUserDefinedValue(false)
46 for (
unsigned int i = 1; i < 10; ++i)
51 m_IgnoredInfinitePixelCount= std::vector<unsigned int>(this->GetNumberOfThreads(), 0);
52 m_IgnoredUserPixelCount= std::vector<unsigned int>(this->GetNumberOfThreads(), 0);
55 template<
class TInputImage,
class TPrecision>
68 return static_cast<itk::DataObject*
>(PixelObjectType::New().GetPointer());
73 return static_cast<itk::DataObject*
>(RealPixelObjectType::New().GetPointer());
78 return static_cast<itk::DataObject*
>(MatrixObjectType::New().GetPointer());
84 return static_cast<itk::DataObject*
>(RealObjectType::New().GetPointer());
93 template<
class TInputImage,
class TPrecision>
101 template<
class TInputImage,
class TPrecision>
109 template<
class TInputImage,
class TPrecision>
117 template<
class TInputImage,
class TPrecision>
125 template<
class TInputImage,
class TPrecision>
133 template<
class TInputImage,
class TPrecision>
141 template<
class TInputImage,
class TPrecision>
149 template<
class TInputImage,
class TPrecision>
158 template<
class TInputImage,
class TPrecision>
166 template<
class TInputImage,
class TPrecision>
174 template<
class TInputImage,
class TPrecision>
182 template<
class TInputImage,
class TPrecision>
190 template<
class TInputImage,
class TPrecision>
198 template<
class TInputImage,
class TPrecision>
206 template<
class TInputImage,
class TPrecision>
214 template<
class TInputImage,
class TPrecision>
222 template<
class TInputImage,
class TPrecision>
230 template<
class TInputImage,
class TPrecision>
238 template<
class TInputImage,
class TPrecision>
243 Superclass::GenerateOutputInformation();
244 if (this->GetInput())
246 this->GetOutput()->CopyInformation(this->GetInput());
247 this->GetOutput()->SetLargestPossibleRegion(this->GetInput()->GetLargestPossibleRegion());
249 if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
251 this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
256 template<
class TInputImage,
class TPrecision>
268 template<
class TInputImage,
class TPrecision>
273 TInputImage * inputPtr =
const_cast<TInputImage *
>(this->GetInput());
274 inputPtr->UpdateOutputInformation();
276 unsigned int numberOfThreads = this->GetNumberOfThreads();
277 unsigned int numberOfComponent = inputPtr->GetNumberOfComponentsPerPixel();
282 tempPixel.SetSize(numberOfComponent);
284 tempPixel.Fill(itk::NumericTraits<InternalPixelType>::max());
285 this->GetMinimumOutput()->Set(tempPixel);
287 tempPixel.Fill(itk::NumericTraits<InternalPixelType>::NonpositiveMin());
288 this->GetMaximumOutput()->Set(tempPixel);
291 tempTemporiesPixel.SetSize(numberOfComponent);
292 tempTemporiesPixel.Fill(itk::NumericTraits<InternalPixelType>::max());
293 m_ThreadMin = std::vector<PixelType>(numberOfThreads, tempTemporiesPixel);
295 tempTemporiesPixel.Fill(itk::NumericTraits<InternalPixelType>::NonpositiveMin());
296 m_ThreadMax = std::vector<PixelType>(numberOfThreads, tempTemporiesPixel);
299 if (m_EnableSecondOrderStats)
301 m_EnableFirstOrderStats =
true;
304 if (m_EnableFirstOrderStats)
307 zeroRealPixel.
SetSize(numberOfComponent);
308 zeroRealPixel.
Fill(itk::NumericTraits<PrecisionType>::ZeroValue());
309 this->GetMeanOutput()->Set(zeroRealPixel);
310 this->GetSumOutput()->Set(zeroRealPixel);
311 m_ThreadFirstOrderAccumulators.resize(numberOfThreads);
312 std::fill(m_ThreadFirstOrderAccumulators.begin(), m_ThreadFirstOrderAccumulators.end(), zeroRealPixel);
314 RealType zeroReal = itk::NumericTraits<RealType>::ZeroValue();
315 m_ThreadFirstOrderComponentAccumulators.resize(numberOfThreads);
316 std::fill(m_ThreadFirstOrderComponentAccumulators.begin(), m_ThreadFirstOrderComponentAccumulators.end(), zeroReal);
320 if (m_EnableSecondOrderStats)
323 zeroMatrix.
SetSize(numberOfComponent, numberOfComponent);
324 zeroMatrix.
Fill(itk::NumericTraits<PrecisionType>::Zero);
325 this->GetCovarianceOutput()->Set(zeroMatrix);
326 this->GetCorrelationOutput()->Set(zeroMatrix);
328 m_ThreadSecondOrderAccumulators.resize(numberOfThreads);
329 std::fill(m_ThreadSecondOrderAccumulators.begin(), m_ThreadSecondOrderAccumulators.end(), zeroMatrix);
331 RealType zeroReal = itk::NumericTraits<RealType>::ZeroValue();
332 m_ThreadSecondOrderComponentAccumulators.resize(numberOfThreads);
333 std::fill(m_ThreadSecondOrderComponentAccumulators.begin(), m_ThreadSecondOrderComponentAccumulators.end(), zeroReal);
336 if (m_IgnoreInfiniteValues)
338 m_IgnoredInfinitePixelCount= std::vector<unsigned int>(numberOfThreads, 0);
341 if (m_IgnoreUserDefinedValue)
343 m_IgnoredUserPixelCount= std::vector<unsigned int>(this->GetNumberOfThreads(), 0);
347 template<
class TInputImage,
class TPrecision>
352 TInputImage * inputPtr =
const_cast<TInputImage *
>(this->GetInput());
353 const unsigned int nbPixels = inputPtr->GetLargestPossibleRegion().GetNumberOfPixels();
354 const unsigned int numberOfComponent = inputPtr->GetNumberOfComponentsPerPixel();
357 minimum.SetSize(numberOfComponent);
358 minimum.Fill(itk::NumericTraits<InternalPixelType>::max());
360 maximum.SetSize(numberOfComponent);
361 maximum.Fill(itk::NumericTraits<InternalPixelType>::NonpositiveMin());
363 RealPixelType streamFirstOrderAccumulator(numberOfComponent);
364 streamFirstOrderAccumulator.
Fill(itk::NumericTraits<PrecisionType>::Zero);
365 MatrixType streamSecondOrderAccumulator(numberOfComponent, numberOfComponent);
366 streamSecondOrderAccumulator.
Fill(itk::NumericTraits<PrecisionType>::Zero);
368 RealType streamFirstOrderComponentAccumulator = itk::NumericTraits<RealType>::Zero;
369 RealType streamSecondOrderComponentAccumulator = itk::NumericTraits<RealType>::Zero;
371 unsigned int ignoredInfinitePixelCount = 0;
372 unsigned int ignoredUserPixelCount = 0;
375 const unsigned int numberOfThreads = this->GetNumberOfThreads();
376 for (
unsigned int threadId = 0; threadId < numberOfThreads; ++threadId)
380 const PixelType& threadMin = m_ThreadMin [threadId];
381 const PixelType& threadMax = m_ThreadMax [threadId];
383 for (
unsigned int j = 0; j < numberOfComponent; ++j)
385 if (threadMin[j] < minimum[j])
387 minimum[j] = threadMin[j];
389 if (threadMax[j] > maximum[j])
391 maximum[j] = threadMax[j];
396 if (m_EnableFirstOrderStats)
398 streamFirstOrderAccumulator += m_ThreadFirstOrderAccumulators[threadId];
399 streamFirstOrderComponentAccumulator += m_ThreadFirstOrderComponentAccumulators[threadId];
402 if (m_EnableSecondOrderStats)
404 streamSecondOrderAccumulator += m_ThreadSecondOrderAccumulators[threadId];
405 streamSecondOrderComponentAccumulator += m_ThreadSecondOrderComponentAccumulators[threadId];
408 ignoredInfinitePixelCount += m_IgnoredInfinitePixelCount[threadId];
410 ignoredUserPixelCount += m_IgnoredUserPixelCount[threadId];
413 unsigned int nbRelevantPixels = nbPixels - (ignoredInfinitePixelCount + ignoredUserPixelCount);
418 this->GetMinimumOutput()->Set(minimum);
419 this->GetMaximumOutput()->Set(maximum);
422 if (m_EnableFirstOrderStats)
424 this->GetComponentMeanOutput()->Set(streamFirstOrderComponentAccumulator / (nbRelevantPixels * numberOfComponent));
426 this->GetMeanOutput()->Set(streamFirstOrderAccumulator / nbRelevantPixels);
427 this->GetSumOutput()->Set(streamFirstOrderAccumulator);
430 if (m_EnableSecondOrderStats)
433 MatrixType cor = streamSecondOrderAccumulator / nbRelevantPixels;
434 this->GetCorrelationOutput()->Set(cor);
437 double regul =
static_cast<double>(nbRelevantPixels) / (nbRelevantPixels - 1);
439 if (!m_UseUnbiasedEstimator)
445 for (
unsigned int r = 0; r < numberOfComponent; ++r)
447 for (
unsigned int c = 0; c < numberOfComponent; ++c)
449 cov(r, c) = regul * (cov(r, c) - mean[r] * mean[c]);
452 this->GetCovarianceOutput()->Set(cov);
454 this->GetComponentMeanOutput()->Set(streamFirstOrderComponentAccumulator / (nbRelevantPixels * numberOfComponent));
455 this->GetComponentCorrelationOutput()->Set(streamSecondOrderComponentAccumulator / (nbRelevantPixels * numberOfComponent));
456 this->GetComponentCovarianceOutput()->Set(
457 (nbRelevantPixels * numberOfComponent) / (nbRelevantPixels * numberOfComponent - 1)
458 * (this->GetComponentCorrelation()
459 - (this->GetComponentMean() * this->GetComponentMean())));
463 template<
class TInputImage,
class TPrecision>
473 PixelType& threadMin = m_ThreadMin [threadId];
474 PixelType& threadMax = m_ThreadMax [threadId];
483 float finiteProbe = 0.;
484 bool userProbe =
true;
485 for (
unsigned int j = 0; j < vectorValue.GetSize(); ++j)
487 finiteProbe += (float)(vectorValue[j]);
488 userProbe = userProbe && (vectorValue[j] == m_UserIgnoredValue);
491 if (m_IgnoreInfiniteValues && !(vnl_math_isfinite(finiteProbe)))
493 m_IgnoredInfinitePixelCount[threadId] ++;
497 if (m_IgnoreUserDefinedValue && (userProbe))
499 m_IgnoredUserPixelCount[threadId] ++;
503 for (
unsigned int j = 0; j < vectorValue.GetSize(); ++j)
508 for (
unsigned int j = 0; j < vectorValue.GetSize(); ++j)
510 if (vectorValue[j] < threadMin[j])
512 threadMin[j] = vectorValue[j];
514 if (vectorValue[j] > threadMax[j])
516 threadMax[j] = vectorValue[j];
522 if (m_EnableFirstOrderStats)
524 RealPixelType& threadFirstOrder = m_ThreadFirstOrderAccumulators [threadId];
525 RealType& threadFirstOrderComponent = m_ThreadFirstOrderComponentAccumulators [threadId];
527 threadFirstOrder += vectorValue;
529 for (
unsigned int i = 0; i < vectorValue.GetSize(); ++i)
531 threadFirstOrderComponent += vectorValue[i];
535 if (m_EnableSecondOrderStats)
537 MatrixType& threadSecondOrder = m_ThreadSecondOrderAccumulators[threadId];
538 RealType& threadSecondOrderComponent = m_ThreadSecondOrderComponentAccumulators[threadId];
540 for (
unsigned int r = 0; r < threadSecondOrder.
Rows(); ++r)
542 for (
unsigned int c = 0; c < threadSecondOrder.
Cols(); ++c)
544 threadSecondOrder(r, c) += vectorValue[r] * vectorValue[c];
547 threadSecondOrderComponent += vectorValue.GetSquaredNorm();
555 template <
class TImage,
class TPrecision>
560 Superclass::PrintSelf(os, indent);
562 os << indent <<
"Min: " << this->GetMinimumOutput()->Get() << std::endl;
563 os << indent <<
"Max: " << this->GetMaximumOutput()->Get() << std::endl;
564 os << indent <<
"Mean: " << this->GetMeanOutput()->Get() << std::endl;
565 os << indent <<
"Covariance: " << this->GetCovarianceOutput()->Get() << std::endl;
566 os << indent <<
"Correlation: " << this->GetCorrelationOutput()->Get() << std::endl;
567 os << indent <<
"Component Mean: " << this->GetComponentMeanOutput()->Get() << std::endl;
568 os << indent <<
"Component Covariance: " << this->GetComponentCovarianceOutput()->Get() << std::endl;
569 os << indent <<
"Component Correlation: " << this->GetComponentCorrelationOutput()->Get() << std::endl;
570 os << indent <<
"UseUnbiasedEstimator: " << (this->m_UseUnbiasedEstimator ?
"true" :
"false") << std::endl;