OTB  10.0.0
Orfeo Toolbox
otbWaveletsBandsListToWaveletsSynopsisImageFilter.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2024 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbWaveletsBandsListToWaveletsSynopsisImageFilter_hxx
22 #define otbWaveletsBandsListToWaveletsSynopsisImageFilter_hxx
23 
25 #include "itkImageRegionIterator.h"
26 #include "itkImageRegionConstIterator.h"
27 
28 namespace otb
29 {
31 template <class TImageList, class TImage>
33 {
34 }
35 
37 template <class TImageList, class TImage>
38 WaveletsBandsListToWaveletsSynopsisImageFilter<TImageList, TImage>::~WaveletsBandsListToWaveletsSynopsisImageFilter()
39 {
40 }
41 
45 template <class TImageList, class TImage>
46 void WaveletsBandsListToWaveletsSynopsisImageFilter<TImageList, TImage>::GenerateOutputInformation(void)
47 {
48  // We must set the size of the output image to be twice the size of the last image
49  // of the image list, which is the first band.
50  if (this->GetOutput())
51  {
52  if (this->GetInput()->Size() > 0)
53  {
54  // Retrieve the largest band
55  typename InputImageType::Pointer lastBand = this->GetInput()->Back();
56 
57  // Retrieve the region of the largest band
58  RegionType largestBandRegion = lastBand->GetLargestPossibleRegion();
59 
60  // Retrieve the size of the largest region
61  typename RegionType::SizeType outputSize = largestBandRegion.GetSize();
62 
63  // Multiply this size by two
64  outputSize[0] *= m_DecimationRatio;
65  outputSize[1] *= m_DecimationRatio;
66 
67  // Build the output region
68  RegionType outputLargestRegion;
69  outputLargestRegion.SetSize(outputSize);
70 
71  // Copy information to the output image
72  this->GetOutput()->CopyInformation(lastBand);
73  this->GetOutput()->SetLargestPossibleRegion(outputLargestRegion);
74  }
75  }
76 }
80 template <class TImageList, class TImage>
81 void WaveletsBandsListToWaveletsSynopsisImageFilter<TImageList, TImage>::GenerateInputRequestedRegion(void)
82 {
83  typename InputImageListType::Pointer inputPtr = this->GetInput();
84  typename InputImageListType::ConstIterator inputListIt = inputPtr->Begin();
85  while (inputListIt != inputPtr->End())
86  {
87  inputListIt.Get()->SetRequestedRegionToLargestPossibleRegion();
88  ++inputListIt;
89  }
90 }
92 
96 template <class TImageList, class TImage>
97 void WaveletsBandsListToWaveletsSynopsisImageFilter<TImageList, TImage>::DynamicThreadedGenerateData(const RegionType& outputRegionForThread)
98 {
99  // Retrieve input and output pointers
100  typename InputImageListType::Pointer inputPtr = this->GetInput();
101  typename OutputImageType::Pointer outputPtr = this->GetOutput();
103 
104  // defines input and output iterators
105  typedef itk::ImageRegionConstIterator<InputImageType> InputIteratorType;
106  typedef itk::ImageRegionIterator<OutputImageType> OutputIteratorType;
107 
108  // Set up an iterator on the input wavelets band
109  typename InputImageListType::ConstIterator inputListIt = inputPtr->Begin();
110  unsigned int bandIndex = 0;
111 
112  // Compute number of decomposition levels
113  unsigned int numberOfDecompositionLevels = (inputPtr->Size() - 1) / 3;
114 
115  // Retrieve the largest possible region size
116  typename RegionType::SizeType largestSize = outputPtr->GetLargestPossibleRegion().GetSize();
117 
118  // Iterate on each band
119  for (; inputListIt != inputPtr->End(); ++inputListIt, ++bandIndex)
120  {
121  // Build a band offset
122  typename RegionType::OffsetType currentOffset;
123  currentOffset.Fill(0);
124 
125  // Initialise Current level
126  unsigned int currentLevel = 0;
127  unsigned int currentSubBand = 0;
128 
129  if (bandIndex > 0)
130  {
131  // Compute current level and sub band
132  currentLevel = 1 + (bandIndex - 1) / 3;
133  currentSubBand = (bandIndex - 1) % 3;
134 
135  // Compute potential offset in x and y
136  unsigned int offsetX = largestSize[0] / (unsigned int)std::pow((double)m_DecimationRatio, (double)1 + numberOfDecompositionLevels - currentLevel);
137  unsigned int offsetY = largestSize[1] / (unsigned int)std::pow((double)m_DecimationRatio, (double)1 + numberOfDecompositionLevels - currentLevel);
138 
139  // Compute final offset according to the subband index
140  if (currentSubBand == 0)
141  {
142  currentOffset[0] += offsetX;
143  }
144  else if (currentSubBand == 1)
145  {
146  currentOffset[1] += offsetY;
147  }
148  else
149  {
150  currentOffset[0] += offsetX;
151  currentOffset[1] += offsetY;
152  }
153  }
154  // Retrieve current band region
155  RegionType currentBandRegion = inputListIt.Get()->GetLargestPossibleRegion();
156 
157  // Apply offset to get the current output region
158  RegionType currentOutputRegion = currentBandRegion;
159  typename RegionType::IndexType currentOutputIndex = currentBandRegion.GetIndex();
160  currentOutputIndex += currentOffset;
161  currentOutputRegion.SetIndex(currentOutputIndex);
162 
163  // Crop with the outputRegionForThread. If the crop fails,
164  // it means that currentOutputRegion is outside of outputRegionForThread,
165  // and in this case we skip to the next image in the list.
166  if (currentOutputRegion.Crop(outputRegionForThread))
167  {
168  // Compute the corresponding input region
169  RegionType currentInputRegion = currentBandRegion;
170  currentOutputIndex = currentOutputRegion.GetIndex();
171  typename RegionType::IndexType currentInputIndex = currentBandRegion.GetIndex();
172 
173  for (unsigned int i = 0; i < InputImageType::ImageDimension; ++i)
174  {
175  currentInputIndex[i] += currentOutputIndex[i];
176  currentInputIndex[i] -= currentOffset[i];
177  }
178  currentInputRegion.SetSize(currentOutputRegion.GetSize());
179  currentInputRegion.SetIndex(currentInputIndex);
180 
181  InputIteratorType inIt(inputListIt.Get(), currentInputRegion);
182  OutputIteratorType outIt(outputPtr, currentOutputRegion);
183 
184  // Go to begin
185  inIt.GoToBegin();
186  outIt.GoToBegin();
187 
188  // Copy pixels
189  while (!inIt.IsAtEnd() && !outIt.IsAtEnd())
190  {
191  // Copy pixel value
192  outIt.Set(static_cast<typename OutputImageType::InternalPixelType>(inIt.Get()));
193  // Step forward
194  ++inIt;
195  ++outIt;
196  }
197  }
198  }
199 }
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.