22 #ifndef otbStreamingStatisticsMapFromLabelImageFilter_hxx
23 #define otbStreamingStatisticsMapFromLabelImageFilter_hxx
26 #include "itkInputDataObjectIterator.h"
27 #include "itkImageRegionIterator.h"
28 #include "itkProgressReporter.h"
36 template <
class TInputVectorImage,
class TLabelImage>
46 this->itk::ProcessObject::SetNthOutput(1, output.GetPointer());
51 template <
class TInputVectorImage,
class TLabelImage>
52 typename itk::DataObject::Pointer
55 return static_cast<itk::DataObject*
>(PixelValueMapObjectType::New().GetPointer());
58 template <
class TInputVectorImage,
class TLabelImage>
62 this->itk::ProcessObject::SetNthInput(1,
const_cast<LabelImageType*
>(input));
65 template <
class TInputVectorImage,
class TLabelImage>
69 return static_cast<const TLabelImage*
>(this->itk::ProcessObject::GetInput(1));
72 template <
class TInputVectorImage,
class TLabelImage>
76 return m_MeanRadiometricValue;
79 template <
class TInputVectorImage,
class TLabelImage>
83 return m_StDevRadiometricValue;
86 template <
class TInputVectorImage,
class TLabelImage>
90 return m_MinRadiometricValue;
93 template <
class TInputVectorImage,
class TLabelImage>
97 return m_MaxRadiometricValue;
100 template <
class TInputVectorImage,
class TLabelImage>
104 return m_LabelPopulation;
107 template <
class TInputVectorImage,
class TLabelImage>
110 Superclass::GenerateOutputInformation();
112 if (this->GetInput())
114 this->GetOutput()->CopyInformation(this->GetInput());
115 this->GetOutput()->SetLargestPossibleRegion(this->GetInput()->GetLargestPossibleRegion());
117 if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
119 this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
124 template <
class TInputVectorImage,
class TLabelImage>
134 template <
class TInputVectorImage,
class TLabelImage>
139 auto endAcc = outputAcc.end();
141 for (
auto const& threadAccMap : m_AccumulatorMaps)
143 for (
auto const& it : threadAccMap)
145 auto label = it.first;
146 auto itAcc = outputAcc.find(label);
149 outputAcc.emplace(label, it.second);
153 itAcc->second.Update(it.second);
159 for (
auto& it : outputAcc)
162 const auto& bandCount = it.second.GetBandCount();
163 const auto& sum = it.second.GetSum();
164 const auto& sqSum = it.second.GetSqSum();
167 m_LabelPopulation[label] = it.second.GetCount();
174 for (
unsigned int band = 0; band <
mean.GetSize(); band++)
177 auto count = bandCount[band];
182 const double variance = (sqSum[band] - (sum[band] *
mean[band])) / (count - 1);
183 std[band] = std::sqrt(variance);
186 if (this->GetUseNoDataValue() && count == 0)
188 min[band] = this->GetNoDataValue();
189 max[band] = this->GetNoDataValue();
192 m_MeanRadiometricValue.emplace(label, std::move(
mean));
193 m_StDevRadiometricValue.emplace(label, std::move(std));
196 m_MinRadiometricValue.emplace(label, std::move(min));
197 m_MaxRadiometricValue.emplace(label, std::move(max));
201 template <
class TInputVectorImage,
class TLabelImage>
204 m_AccumulatorMaps.clear();
206 m_MeanRadiometricValue.clear();
207 m_StDevRadiometricValue.clear();
208 m_MinRadiometricValue.clear();
209 m_MaxRadiometricValue.clear();
210 m_LabelPopulation.clear();
211 m_AccumulatorMaps.resize(this->GetNumberOfThreads());
214 template <
class TInputVectorImage,
class TLabelImage>
218 this->itk::ProcessObject::GenerateInputRequestedRegion();
221 for (itk::InputDataObjectIterator it(
this); !it.IsAtEnd(); it++)
236 this->CallCopyOutputRegionToInputRegion(inputRegion, this->GetOutput()->GetRequestedRegion());
237 input->SetRequestedRegion(inputRegion);
242 template <
class TInputVectorImage,
class TLabelImage>
244 itk::ThreadIdType threadId)
250 LabelImagePointer labelInputPtr =
const_cast<TLabelImage*
>(this->GetInputLabelImage());
253 itk::ImageRegionConstIterator<TInputVectorImage> inIt(inputPtr, outputRegionForThread);
254 itk::ImageRegionConstIterator<TLabelImage> labelIt(labelInputPtr, outputRegionForThread);
255 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels());
257 auto& acc = m_AccumulatorMaps[threadId];
258 auto endAcc = acc.end();
261 for (inIt.GoToBegin(), labelIt.GoToBegin(); !inIt.IsAtEnd() && !labelIt.IsAtEnd(); ++inIt, ++labelIt)
263 const auto& value = inIt.Get();
264 auto label = labelIt.Get();
267 auto itAcc = acc.find(label);
270 acc.emplace(label,
AccumulatorType(this->GetNoDataValue(), this->GetUseNoDataValue(), value));
274 itAcc->second.Update(value);
277 progress.CompletedPixel();
281 template <
class TInputVectorImage,
class TLabelImage>
284 Superclass::PrintSelf(os, indent);