22 #ifndef otbStreamingHistogramVectorImageFilter_hxx
23 #define otbStreamingHistogramVectorImageFilter_hxx
26 #include "itkImageRegionIterator.h"
27 #include "itkImageRegionConstIteratorWithIndex.h"
28 #include "itkProgressReporter.h"
34 template <
class TInputImage>
36 : m_ThreadHistogramList(),
49 this->DynamicMultiThreadingOff();
52 this->itk::ProcessObject::SetNthOutput(1, output.GetPointer());
55 template <
class TInputImage>
58 itk::DataObject::Pointer ret;
62 ret =
static_cast<itk::DataObject*
>(TInputImage::New().GetPointer());
65 ret =
static_cast<itk::DataObject*
>(HistogramListType::New().GetPointer());
71 template <
class TInputImage>
77 template <
class TInputImage>
81 return static_cast<const HistogramListType*
>(this->itk::ProcessObject::GetOutput(1));
84 template <
class TInputImage>
87 Superclass::GenerateOutputInformation();
90 this->GetOutput()->CopyInformation(this->GetInput());
91 this->GetOutput()->SetLargestPossibleRegion(this->GetInput()->GetLargestPossibleRegion());
93 if (this->GetOutput()->GetRequestedRegion().GetNumberOfPixels() == 0)
95 this->GetOutput()->SetRequestedRegion(this->GetOutput()->GetLargestPossibleRegion());
100 template <
class TInputImage>
110 template <
class TInputImage>
113 TInputImage* inputPtr =
const_cast<TInputImage*
>(this->GetInput());
114 inputPtr->UpdateOutputInformation();
116 unsigned int numberOfThreads = this->GetNumberOfWorkUnits();
117 unsigned int numberOfComponent = inputPtr->GetNumberOfComponentsPerPixel();
120 bool clipBins =
false;
123 if (m_HistogramMin.Size() != numberOfComponent || m_HistogramMax.Size() != numberOfComponent)
125 m_HistogramMin.SetSize(numberOfComponent);
126 m_HistogramMax.SetSize(numberOfComponent);
128 m_HistogramMin.Fill(itk::NumericTraits<InternalPixelType>::Zero);
129 m_HistogramMax.Fill(255);
134 outputHisto->
Clear();
135 for (
unsigned int k = 0; k < numberOfComponent; ++k)
137 typename HistogramType::MeasurementVectorType bandMin, bandMax;
140 bandMin.Fill(m_HistogramMin[k]);
141 bandMax.Fill(m_HistogramMax[k]);
143 typename HistogramType::Pointer histogram = HistogramType::New();
144 histogram->SetClipBinsAtEnds(clipBins);
146 typename HistogramType::SizeType size;
148 size.Fill(m_Size[k]);
149 histogram->SetMeasurementVectorSize(1);
150 histogram->Initialize(size, bandMin, bandMax);
157 m_ThreadHistogramList.clear();
158 for (
unsigned int i = 0; i < numberOfThreads; ++i)
162 for (
unsigned int k = 0; k < numberOfComponent; ++k)
164 typename HistogramType::MeasurementVectorType bandMin, bandMax;
167 bandMin.Fill(m_HistogramMin[k]);
168 bandMax.Fill(m_HistogramMax[k]);
170 typename HistogramType::Pointer histogram = HistogramType::New();
171 histogram->SetClipBinsAtEnds(clipBins);
173 typename HistogramType::SizeType size;
175 size.Fill(m_Size[k]);
176 histogram->SetMeasurementVectorSize(1);
177 histogram->Initialize(size, bandMin, bandMax);
179 histoList->PushBack(histogram);
181 m_ThreadHistogramList.push_back(histoList);
185 template <
class TInputImage>
190 int numberOfThreads = this->GetNumberOfWorkUnits();
191 unsigned int numberOfComponent = this->GetInput()->GetNumberOfComponentsPerPixel();
194 for (
int i = 0; i < numberOfThreads; ++i)
196 for (
unsigned int j = 0; j < numberOfComponent; ++j)
199 HistogramType* threadHisto = m_ThreadHistogramList[i]->GetNthElement(j);
201 typename HistogramType::Iterator iterOutput = outHisto->Begin();
202 typename HistogramType::Iterator iterThread = threadHisto->Begin();
204 while (iterOutput != outHisto->End() && iterThread != threadHisto->End())
206 iterOutput.SetFrequency(iterOutput.GetFrequency() + iterThread.GetFrequency());
215 template <
class TInputImage>
223 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels());
226 typename HistogramType::IndexType index;
228 itk::ImageRegionConstIteratorWithIndex<TInputImage> it(inputPtr, outputRegionForThread);
231 bool skipSample =
false;
234 while (!it.IsAtEnd())
236 if (m_SubSamplingRate > 1)
239 for (
unsigned int i = 0; i < InputImageDimension; ++i)
241 if (it.GetIndex()[i] % m_SubSamplingRate != 0)
250 progress.CompletedPixel();
257 bool skipSampleNoData =
false;
260 unsigned int itComp = 0;
261 while (itComp < vectorValue.GetSize())
263 if (vectorValue[itComp] == m_NoDataValue)
265 skipSampleNoData =
true;
270 skipSampleNoData =
false;
276 if (!skipSampleNoData)
278 for (
unsigned int j = 0; j < vectorValue.GetSize(); ++j)
280 typename HistogramType::MeasurementVectorType value;
282 value.Fill(vectorValue[j]);
284 m_ThreadHistogramList[threadId]->GetNthElement(j)->GetIndex(value, index);
285 if (!m_ThreadHistogramList[threadId]->GetNthElement(j)->IsIndexOutOfBounds(index))
293 m_ThreadHistogramList[threadId]->GetNthElement(j)->IncreaseFrequencyOfIndex(index, 1);
299 progress.CompletedPixel();
303 template <
class TImage>
306 Superclass::PrintSelf(os, indent);
308 os << indent <<
"Histogram minimum: " << this->GetHistogramMin() << std::endl;
309 os << indent <<
"Histogram maximum: " << this->GetHistogramMax() << std::endl;
310 os << indent <<
"Number of bins: " << m_Size[0] << std::endl;
313 os << indent <<
"Use NoData: true" << std::endl;
317 os << indent <<
"Use NoData: false" << std::endl;
319 os << indent <<
"NoData value: " << this->GetNoDataValue() << std::endl;
This class is a generic all-purpose wrapping around an std::vector<itk::SmartPointer<ObjectType> >.
ObjectPointerType GetNthElement(unsigned int index) const
void PushBack(ObjectType *element)
HistogramListType * GetHistogramListOutput()
DataObjectPointer MakeOutput(DataObjectPointerArraySizeType idx) override
void AllocateOutputs() override
itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType
TInputImage::RegionType RegionType
PersistentHistogramVectorImageFilter()
HistogramListType::Pointer HistogramListPointerType
itk::Statistics::Histogram< HistogramMeasurementRealType, DFContainerType > HistogramType
void Synthetize(void) override
TInputImage::Pointer InputImagePointer
void PrintSelf(std::ostream &os, itk::Indent indent) const override
void Reset(void) override
TInputImage::PixelType PixelType
TInputImage::InternalPixelType InternalPixelType
void GenerateOutputInformation() override
void ThreadedGenerateData(const RegionType &outputRegionForThread, itk::ThreadIdType threadId) override
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.