OTB  9.0.0
Orfeo Toolbox
otbStreamingStatisticsMosaicFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 1999-2011 Insight Software Consortium
3  * Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
4  * Copyright (C) 2016-2019 IRSTEA
5  *
6  * This file is part of Orfeo Toolbox
7  *
8  * https://www.orfeo-toolbox.org/
9  *
10  * Licensed under the Apache License, Version 2.0 (the "License");
11  * you may not use this file except in compliance with the License.
12  * You may obtain a copy of the License at
13  *
14  * http://www.apache.org/licenses/LICENSE-2.0
15  *
16  * Unless required by applicable law or agreed to in writing, software
17  * distributed under the License is distributed on an "AS IS" BASIS,
18  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
19  * See the License for the specific language governing permissions and
20  * limitations under the License.
21  */
22 #ifndef __StreamingStatisticsMosaicFilter_hxx
23 #define __StreamingStatisticsMosaicFilter_hxx
24 
26 
27 namespace otb
28 {
29 
30 template <class TInputImage, class TOutputImage, class TInternalValueType>
32 {
33 
34  // allocate the data objects for the outputs which are
35  // just decorators around pixel types
36  // 1: means
37  // 2: stdevs
38  // 3: means of products
39  // 4: mins
40  // 5: maxs
41  for (int i = 1; i < 6; ++i)
42  {
43  typename RealMatrixListObjectType::Pointer output = static_cast<RealMatrixListObjectType*>(this->MakeOutput(i).GetPointer());
44  this->itk::ProcessObject::SetNthOutput(i, output.GetPointer());
45  }
46 
47  // allocate the data objects for the outputs which are
48  // just decorators around real matrices
49  //
50  // 6: count
51  typename RealMatrixObjectType::Pointer output = static_cast<RealMatrixObjectType*>(this->MakeOutput(6).GetPointer());
52  this->itk::ProcessObject::SetNthOutput(6, output.GetPointer());
53 }
54 
55 /*
56  * Make output
57  */
58 template <class TInputImage, class TOutputImage, class TInternalValueType>
59 typename itk::DataObject::Pointer
61 {
62  itkDebugMacro(<< "Entering MakeOutput(" << output << ")");
63  if (output == 0)
64  {
65  return static_cast<itk::DataObject*>(TOutputImage::New().GetPointer());
66  }
67  else if (output == 6)
68  {
69  return static_cast<itk::DataObject*>(RealMatrixObjectType::New().GetPointer());
70  }
71  return static_cast<itk::DataObject*>(RealMatrixListObjectType::New().GetPointer());
72 }
73 
74 template <class TInputImage, class TOutputImage, class TInternalValueType>
77 {
78  return static_cast<RealMatrixListObjectType*>(this->itk::ProcessObject::GetOutput(1));
79 }
80 
81 template <class TInputImage, class TOutputImage, class TInternalValueType>
84 {
85  return static_cast<RealMatrixListObjectType*>(this->itk::ProcessObject::GetOutput(2));
86 }
87 
88 template <class TInputImage, class TOutputImage, class TInternalValueType>
91 {
92  return static_cast<RealMatrixListObjectType*>(this->itk::ProcessObject::GetOutput(3));
93 }
94 
95 template <class TInputImage, class TOutputImage, class TInternalValueType>
98 {
99  return static_cast<RealMatrixListObjectType*>(this->itk::ProcessObject::GetOutput(4));
100 }
101 
102 template <class TInputImage, class TOutputImage, class TInternalValueType>
105 {
106  return static_cast<RealMatrixListObjectType*>(this->itk::ProcessObject::GetOutput(5));
107 }
108 
109 template <class TInputImage, class TOutputImage, class TInternalValueType>
112 {
113  return static_cast<RealMatrixObjectType*>(this->itk::ProcessObject::GetOutput(6));
114 }
115 
116 template <class TInputImage, class TOutputImage, class TInternalValueType>
119 {
120  return static_cast<const RealMatrixListObjectType*>(this->itk::ProcessObject::GetOutput(1));
121 }
122 
123 template <class TInputImage, class TOutputImage, class TInternalValueType>
126 {
127  return static_cast<const RealMatrixListObjectType*>(this->itk::ProcessObject::GetOutput(2));
128 }
129 
130 template <class TInputImage, class TOutputImage, class TInternalValueType>
133 {
134  return static_cast<const RealMatrixListObjectType*>(this->itk::ProcessObject::GetOutput(3));
135 }
136 
137 template <class TInputImage, class TOutputImage, class TInternalValueType>
140 {
141  return static_cast<const RealMatrixListObjectType*>(this->itk::ProcessObject::GetOutput(4));
142 }
143 
144 template <class TInputImage, class TOutputImage, class TInternalValueType>
147 {
148  return static_cast<const RealMatrixListObjectType*>(this->itk::ProcessObject::GetOutput(5));
149 }
150 
151 template <class TInputImage, class TOutputImage, class TInternalValueType>
154 {
155  return static_cast<const RealMatrixObjectType*>(this->itk::ProcessObject::GetOutput(6));
156 }
157 
161 template <class TInputImage, class TOutputImage, class TInternalValueType>
163 {
164  itkDebugMacro(<< "Entering Reset()");
165 
166  Superclass::GenerateOutputInformation();
167 
168  // Prepare threads result
169  const unsigned int numberOfThreads = this->GetNumberOfThreads();
170  const unsigned int nBands = this->GetNumberOfBands();
171  const unsigned int nbImages = this->GetNumberOfInputImages();
172 
173  itkDebugMacro(<< "\nN threads: " << numberOfThreads << "\nN bands: " << nBands << "\nN images: " << nbImages);
174 
175  m_InternalThreadResults.clear();
176  for (unsigned int threadId = 0; threadId < numberOfThreads; threadId++)
177  {
178  // Create a clean empty container for each thread
179  ThreadResultsContainer threadResult(nBands, nbImages * nbImages);
180  m_InternalThreadResults.push_back(threadResult);
181  }
182 }
183 
184 template <class TInputImage, class TOutputImage, class TInternalValueType>
186 {
187  itkDebugMacro(<< "Entering AllocateOutputs()");
188  // This is commented to prevent the streaming of the whole image for the first stream strip
189  // It shall not cause any problem because the output image of this filter is not intended to be used.
190  // InputImagePointer image = const_cast< TInputImage * >( this->GetInput() );
191  // this->GraftOutput( image );
192  // Nothing that needs to be allocated for the remaining outputs
193 }
194 
195 /*
196  * Synthetize() implementation
197  */
198 template <class TInputImage, class TOutputImage, class TInternalValueType>
200 {
201  itkDebugMacro(<< "Entering Synthetize()");
202 
203  const unsigned int nBands = Superclass::GetNumberOfBands();
204  const unsigned int nbImages = this->GetNumberOfInputImages();
205 
206  // Merge threads result
207  ThreadResultsContainer finalResults = ThreadResultsContainer(nBands, nbImages * nbImages);
208  for (const auto& res : m_InternalThreadResults)
209  {
210  finalResults.Update(res);
211  }
212 
213  // Compute final outputs
214  m_Means.clear();
215  m_Stds.clear();
216  m_ProdMeans.clear();
217  m_Mins.clear();
218  m_Maxs.clear();
219  m_Area = RealMatrixType(nbImages, nbImages, 0);
220 
221  for (unsigned int band = 0; band < nBands; band++)
222  {
223  RealMatrixType mean(nbImages, nbImages, 0);
224  RealMatrixType prodmean(nbImages, nbImages, 0);
225  RealMatrixType stdev(nbImages, nbImages, 0);
226  RealMatrixType min(nbImages, nbImages, itk::NumericTraits<InputImageInternalPixelType>::max());
227  RealMatrixType max(nbImages, nbImages, itk::NumericTraits<InputImageInternalPixelType>::NonpositiveMin());
228 
229  for (unsigned int i = 0; i < nbImages; i++)
230  {
231  for (unsigned int j = 0; j < nbImages; j++)
232  {
233 
234  const InternalValueType count = finalResults.m_count[i * nbImages + j];
235  const InternalValueType sum = finalResults.m_sum[band][i * nbImages + j];
236  const InternalValueType cosum = finalResults.m_cosum[band][i * nbImages + j];
237  const InternalValueType sqSum = finalResults.m_sqSum[band][i * nbImages + j];
238  const InternalValueType minVal = finalResults.m_min[band][i * nbImages + j];
239  const InternalValueType maxVal = finalResults.m_max[band][i * nbImages + j];
240 
241  // Update area
242  m_Area[i][j] = count;
243 
244  // Update Min and Max
245  if (minVal < min[i][j])
246  min[i][j] = minVal;
247  if (maxVal > max[i][j])
248  max[i][j] = maxVal;
249 
250  // Update Mean, Std and Mean of products
251  if (count > 0)
252  {
253  mean[i][j] = sum / (static_cast<InternalValueType>(count));
254  prodmean[i][j] = cosum / (static_cast<InternalValueType>(count));
255 
256  // Unbiased estimate
257  InternalValueType variance = (sqSum - (sum * sum / static_cast<InternalValueType>(count))) / (static_cast<InternalValueType>(count) - 1);
258  if (variance > 0)
259  {
260  stdev[i][j] = vcl_sqrt(variance);
261  }
262  }
263  }
264  }
265  m_Means.push_back(mean);
266  m_Stds.push_back(stdev);
267  m_ProdMeans.push_back(prodmean);
268  m_Mins.push_back(min);
269  m_Maxs.push_back(max);
270 
271  } // next band
272 
273  this->GetMeansOutput()->Set(m_Means);
274  this->GetStdsOutput()->Set(m_Stds);
275  this->GetMeansOfProductsOutput()->Set(m_ProdMeans);
276  this->GetMinsOutput()->Set(m_Mins);
277  this->GetMaxsOutput()->Set(m_Maxs);
278  this->GetAreasOutput()->Set(m_Area);
279 }
280 
284 template <class TInputImage, class TOutputImage, class TInternalValueType>
286  itk::ThreadIdType threadId)
287 {
288 
289  // Debug info
290  itkDebugMacro(<< "Actually executing thread " << threadId << " in region " << outputRegionForThread);
291 
292  // Support progress methods/callbacks
293  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
294 
295  // Get number of input images
296  const unsigned int nbOfInputImages = this->GetNumberOfInputImages();
297 
298  // Get number of used inputs
299  const unsigned int nbOfUsedInputImages = Superclass::GetNumberOfUsedInputImages();
300 
301  // Iterate through the thread region
302  IteratorType outputIt(this->GetOutput(), outputRegionForThread);
303 
304  // Prepare input pointers, interpolators, and valid regions (input images)
305  typename std::vector<InputImageType*> currentImage;
306  typename std::vector<InterpolatorPointerType> interp;
307  Superclass::PrepareImageAccessors(currentImage, interp);
308 
309  // temporary variables
310  OutputImagePointType geoPoint;
311 
312  for (outputIt.GoToBegin(); !outputIt.IsAtEnd(); ++outputIt)
313  {
314 
315  // Update progress
316  progress.CompletedPixel();
317 
318  // Overlap descriptor for the current pixel (yes/no + value)
319  std::vector<unsigned int> overlapImagesIndices;
320  std::vector<InputImagePixelType> overlapPixelValue;
321 
322  // Current pixel --> Geographical point
323  this->GetOutput()->TransformIndexToPhysicalPoint(outputIt.GetIndex(), geoPoint);
324 
325  // Loop on used input images
326  for (unsigned int i = 0; i < nbOfUsedInputImages; i++)
327  {
328 
329  // Check if the point is inside the transformed thread region
330  // (i.e. the region in the current input image which match the thread
331  // region)
332  if (interp[i]->IsInsideBuffer(geoPoint))
333  {
334 
335  // Compute the interpolated pixel value
336  InputImagePixelType interpolatedPixel = interp[i]->Evaluate(geoPoint);
337 
338  // Put image index + image pixel value into memory
339  if (Superclass::IsPixelNotEmpty(interpolatedPixel))
340  {
341  overlapImagesIndices.push_back(Superclass::GetUsedInputImageIndice(i));
342  overlapPixelValue.push_back(interpolatedPixel);
343  }
344 
345  } // point inside buffer
346  } // next image
347 
348  // Update thread result
349 
350  // Nb of overlaps at the current pixel
351  unsigned int nbOfOverlappingPixels = overlapImagesIndices.size();
352 
353  // Loop on overlapping pixels
354  for (unsigned int i = 0; i < nbOfOverlappingPixels; i++)
355  {
356  // Index of the image whose comes the current overlapping pixel
357  unsigned int imageIndex = overlapImagesIndices.at(i);
358 
359  // We need to sum this pixel to all overlaps ij
360  InputImagePixelType pixel = overlapPixelValue.at(i);
361 
362  for (unsigned int j = 0; j < nbOfOverlappingPixels; j++)
363  {
364  // if (i!=j)
365  {
366  // Index of the other image which share this overlapping pixel
367  unsigned int otherImageIndex = overlapImagesIndices.at(j);
368 
369  // Pixel value of the other image which share this overlapping pixel
370  InputImagePixelType otherPixel = overlapPixelValue.at(j);
371 
372  // Update
373  m_InternalThreadResults.at(threadId).Update(pixel, otherPixel, imageIndex * nbOfInputImages + otherImageIndex);
374  }
375  }
376  } // loop on overlapping pixels
377 
378  } // next output pixel
379 }
380 
381 } // end namespace gtb
382 
383 #endif
otb::PersistentStatisticsMosaicFilter::DataObjectPointerArraySizeType
itk::ProcessObject::DataObjectPointerArraySizeType DataObjectPointerArraySizeType
Definition: otbStreamingStatisticsMosaicFilter.h:96
otb::PersistentStatisticsMosaicFilter::GetMeansOfProductsOutput
RealMatrixListObjectType * GetMeansOfProductsOutput()
Definition: otbStreamingStatisticsMosaicFilter.hxx:90
otb::mean
Definition: otbParserXPlugins.h:261
otb::PersistentStatisticsMosaicFilter::Reset
void Reset() override
Definition: otbStreamingStatisticsMosaicFilter.hxx:162
otb::PersistentStatisticsMosaicFilter::InputImagePixelType
Superclass::InputImagePixelType InputImagePixelType
Definition: otbStreamingStatisticsMosaicFilter.h:73
otb::PersistentStatisticsMosaicFilter::RealMatrixListObjectType
itk::SimpleDataObjectDecorator< RealMatrixListType > RealMatrixListObjectType
Definition: otbStreamingStatisticsMosaicFilter.h:92
otb::PersistentStatisticsMosaicFilter::IteratorType
itk::ImageRegionConstIteratorWithOnlyIndex< OutputImageType > IteratorType
Definition: otbStreamingStatisticsMosaicFilter.h:85
otb::PersistentStatisticsMosaicFilter::AllocateOutputs
void AllocateOutputs() override
Definition: otbStreamingStatisticsMosaicFilter.hxx:185
otb::PersistentStatisticsMosaicFilter::OutputImagePointType
Superclass::OutputImagePointType OutputImagePointType
Definition: otbStreamingStatisticsMosaicFilter.h:78
otbStreamingStatisticsMosaicFilter.h
otb::PersistentStatisticsMosaicFilter::ThreadedGenerateData
void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, itk::ThreadIdType threadId) override
Definition: otbStreamingStatisticsMosaicFilter.hxx:285
otb::PersistentStatisticsMosaicFilter::Synthetize
void Synthetize() override
Definition: otbStreamingStatisticsMosaicFilter.hxx:199
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::PersistentStatisticsMosaicFilter::PersistentStatisticsMosaicFilter
PersistentStatisticsMosaicFilter()
Definition: otbStreamingStatisticsMosaicFilter.hxx:31
otb::PersistentStatisticsMosaicFilter::RealMatrixType
vnl_matrix< InternalValueType > RealMatrixType
Definition: otbStreamingStatisticsMosaicFilter.h:89
otb::PersistentStatisticsMosaicFilter::InternalValueType
Superclass::InternalValueType InternalValueType
Definition: otbStreamingStatisticsMosaicFilter.h:82
otb::PersistentStatisticsMosaicFilter::RealMatrixObjectType
itk::SimpleDataObjectDecorator< RealMatrixType > RealMatrixObjectType
Definition: otbStreamingStatisticsMosaicFilter.h:90
otb::PersistentStatisticsMosaicFilter::ThreadResultsContainer::m_min
RealMatrixType m_min
Definition: otbStreamingStatisticsMosaicFilter.h:280
otb::PersistentStatisticsMosaicFilter::ThreadResultsContainer::m_max
RealMatrixType m_max
Definition: otbStreamingStatisticsMosaicFilter.h:281
otb::PersistentStatisticsMosaicFilter::ThreadResultsContainer::m_sqSum
RealMatrixType m_sqSum
Definition: otbStreamingStatisticsMosaicFilter.h:278
otb::PersistentStatisticsMosaicFilter::ThreadResultsContainer::m_count
RealVectorType m_count
Definition: otbStreamingStatisticsMosaicFilter.h:282
otb::PersistentStatisticsMosaicFilter::ThreadResultsContainer::m_sum
RealMatrixType m_sum
Definition: otbStreamingStatisticsMosaicFilter.h:277
otb::PersistentStatisticsMosaicFilter::GetStdsOutput
RealMatrixListObjectType * GetStdsOutput()
Definition: otbStreamingStatisticsMosaicFilter.hxx:83
otb::PersistentStatisticsMosaicFilter::ThreadResultsContainer::Update
void Update(const InputImagePixelType &pixel, unsigned int sampleId)
Definition: otbStreamingStatisticsMosaicFilter.h:218
otb::PersistentStatisticsMosaicFilter::GetMaxsOutput
RealMatrixListObjectType * GetMaxsOutput()
Definition: otbStreamingStatisticsMosaicFilter.hxx:104
otb::PersistentStatisticsMosaicFilter::GetMinsOutput
RealMatrixListObjectType * GetMinsOutput()
Definition: otbStreamingStatisticsMosaicFilter.hxx:97
otb::PersistentStatisticsMosaicFilter::GetAreasOutput
RealMatrixObjectType * GetAreasOutput()
Definition: otbStreamingStatisticsMosaicFilter.hxx:111
otb::PersistentStatisticsMosaicFilter::MakeOutput
DataObjectPointer MakeOutput(DataObjectPointerArraySizeType idx) override
Definition: otbStreamingStatisticsMosaicFilter.hxx:60
otb::PersistentStatisticsMosaicFilter::ThreadResultsContainer
Definition: otbStreamingStatisticsMosaicFilter.h:176
otb::PersistentStatisticsMosaicFilter::GetMeansOutput
RealMatrixListObjectType * GetMeansOutput()
Definition: otbStreamingStatisticsMosaicFilter.hxx:76
otb::PersistentStatisticsMosaicFilter::ThreadResultsContainer::m_cosum
RealMatrixType m_cosum
Definition: otbStreamingStatisticsMosaicFilter.h:279
otb::PersistentStatisticsMosaicFilter::OutputImageRegionType
Superclass::OutputImageRegionType OutputImageRegionType
Definition: otbStreamingStatisticsMosaicFilter.h:79