OTB  9.0.0
Orfeo Toolbox
otbWaveletPacketTransform.hxx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2022 Centre National d'Etudes Spatiales (CNES)
3  * Copyright (C) 2007-2012 Institut Mines Telecom / Telecom Bretagne
4  *
5  * This file is part of Orfeo Toolbox
6  *
7  * https://www.orfeo-toolbox.org/
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */
21 
22 
23 #ifndef otbWaveletPacketTransform_hxx
24 #define otbWaveletPacketTransform_hxx
26 #include "otbMacro.h"
27 
28 namespace otb
29 {
30 
35 template <class TInputImage, class TOutputImage, class TFilter, class TCost>
37  : m_SubsampleImageFactor(2), m_NumberOfFilters(0), m_DepthOfDecomposition(0)
38 {
39  this->SetNumberOfRequiredInputs(1);
40  this->SetNumberOfRequiredOutputs(1);
41  this->SetNthOutput(0, OutputImageListType::New());
42 
43  m_FilterList = FilterListType::New();
44  m_Cost = CostType::New();
45 }
46 
47 template <class TInputImage, class TOutputImage, class TFilter, class TCost>
49 {
50  /*
51  * Start with a decomposition
52  */
53 
54  m_WaveletPacketRule.clear();
55 
56  m_NumberOfFilters = 0;
57  m_DepthOfDecomposition = 0;
58 
59  itk::ProgressAccumulator::Pointer progress = itk::ProgressAccumulator::New();
60  progress->SetMiniPipelineFilter(this);
61 
62  GenerateData(0, this->GetInput(), progress);
63 }
64 
65 template <class TInputImage, class TOutputImage, class TFilter, class TCost>
67  itk::ProgressAccumulator* progress)
68 {
69  // We cannot know in advance the nomber of filters in this mini-pipeline
70  // So we decrease the weight of each filter in order to tend to 1... slowly...
71  static float accumulatorWeight = 1.;
72 
73  if (this->GetCost()->Evaluate(depth, outputPtr))
74  {
75  if (m_DepthOfDecomposition < depth)
76  m_DepthOfDecomposition = depth;
77 
78  m_WaveletPacketRule.push_back(true);
79 
80  this->GetFilterList()->PushBack(FilterType::New());
81  FilterPointerType filter = this->GetFilterList()->GetNthElement(m_NumberOfFilters);
82 
83  m_NumberOfFilters++;
84 
85  filter->SetSubsampleImageFactor(GetSubsampleImageFactor());
86  if (GetSubsampleImageFactor() == 1)
87  filter->SetUpSampleFilterFactor(depth);
88 
89  accumulatorWeight /= 2.;
90  progress->RegisterInternalFilter(filter, accumulatorWeight);
91  filter->SetInput(outputPtr);
92 
93  filter->Update();
94 
95  for (unsigned int idx = 0; idx < filter->GetNumberOfOutputs(); ++idx)
96  {
97  GenerateData(depth + 1, filter->GetOutput(idx), progress);
98  }
99  }
100  else
101  {
102  m_WaveletPacketRule.push_back(false);
103  this->GetOutput()->PushBack(outputPtr);
104  }
105 }
106 
111 template <class TInputImage, class TOutputImage, class TFilter>
113  : m_SubsampleImageFactor(2), m_NumberOfFilters(0), m_DepthOfDecomposition(0)
114 {
115  this->SetNumberOfRequiredInputs(1);
116  this->SetNumberOfRequiredOutputs(1);
117  this->SetNthOutput(0, OutputImageType::New());
118 
119  m_FilterList = FilterListType::New();
120 }
121 
122 template <class TInputImage, class TOutputImage, class TFilter>
124 {
125  if (m_NumberOfFilters == 0)
126  InterpretRule();
127 
128  this->GetOutput()->CopyInformation(this->GetInput()->GetNthElement(0));
129 
130  InputImageRegionType inputRegion = this->GetInput()->GetNthElement(0)->GetLargestPossibleRegion();
131  SizeType inputSize = inputRegion.GetSize();
132  IndexType inputIndex = inputRegion.GetIndex();
133 
134  OutputImageSizeType outputSize;
135  OutputImageIndexType outputIndex;
136 
137  for (unsigned int i = 0; i < InputImageDimension; ++i)
138  {
139  outputIndex[i] = inputIndex[i] * GetSubsampleImageFactor() * GetDepthOfDecomposition();
140  outputSize[i] = inputSize[i] * GetSubsampleImageFactor() * GetDepthOfDecomposition();
141  }
142 
143  otbMsgDevMacro(<< "Output Size [" << outputSize[0] << "," << outputSize[1] << "]");
144 
145  OutputImageRegionType outputRegion;
146  outputRegion.SetIndex(outputIndex);
147  outputRegion.SetSize(outputSize);
148  this->GetOutput()->SetRegions(outputRegion);
149 }
150 
151 template <class TInputImage, class TOutputImage, class TFilter>
153 {
154  if (m_WaveletPacketRule[0] != true)
155  {
156  throw itk::ExceptionObject(__FILE__, __LINE__, "No decomposition to perform in Generic data... Check WaveletPacketRule tab", ITK_LOCATION);
157  }
158 
159  if (m_NumberOfFilters == 0)
160  InterpretRule();
161 
162  otbMsgDevMacro(<< "nbFilter = " << m_NumberOfFilters);
163  otbMsgDevMacro(<< "depth = " << m_DepthOfDecomposition);
164  otbMsgDevMacro(<< "rule size = " << m_WaveletPacketRule.size());
165 
166  if (m_NumberOfFilters == 0)
167  {
168  throw itk::ExceptionObject(__FILE__, __LINE__, "No filter found in the decomposition tree... Check WaveletPacketRule tab", ITK_LOCATION);
169  }
170 
171  InputImageIterator inputIterator = this->GetInput()->Begin();
172 
173  unsigned int pos = 1;
174  SetInputFilters(pos, inputIterator, 0);
175 
176  if (pos != m_WaveletPacketRule.size() || inputIterator != this->GetInput()->End())
177  {
178  throw itk::ExceptionObject(__FILE__, __LINE__, "Bad decomposition tree implementation...", ITK_LOCATION);
179  }
180 
181  m_FilterList->GetNthElement(0)->GraftOutput(this->GetOutput());
182 
183  itk::ProgressAccumulator::Pointer progress = itk::ProgressAccumulator::New();
184  progress->SetMiniPipelineFilter(this);
185 
186  for (pos = m_NumberOfFilters; pos > 0; pos--)
187  {
188  FilterPointerType filter = m_FilterList->GetNthElement(pos - 1);
189  progress->RegisterInternalFilter(filter, 1.f / static_cast<float>(m_NumberOfFilters));
190  filter->Update();
191  }
192 
193  this->GraftOutput(m_FilterList->GetNthElement(0)->GetOutput());
194 }
195 
196 template <class TInputImage, class TOutputImage, class TFilter>
198  unsigned int& ruleID, InputImageIterator& imgIt, unsigned int filterID)
199 {
200  unsigned int nextFilterID = filterID + 1;
201 
202  if (ruleID == m_WaveletPacketRule.size())
203  return m_FilterList->Size();
204 
205  const unsigned int filterBankInputSize = 1 << InputImageDimension;
206 
207  for (unsigned int i = 0; i < filterBankInputSize; ++i)
208  {
209  if (m_WaveletPacketRule[ruleID++] == true)
210  {
211  m_FilterList->GetNthElement(filterID)->SetInput(i, m_FilterList->GetNthElement(nextFilterID)->GetOutput());
212  nextFilterID = SetInputFilters(ruleID, imgIt, nextFilterID);
213  }
214  else
215  {
216  m_FilterList->GetNthElement(filterID)->SetInput(i, imgIt.Get());
217  ++imgIt;
218  }
219  }
220 
221  return nextFilterID;
222 }
223 
224 template <class TInputImage, class TOutputImage, class TFilter>
226 {
227  if (m_FilterList && m_FilterList->Size() != 0)
228  {
229  if (m_NumberOfFilters != 0)
230  itkExceptionMacro(<< "Incoherency between member value");
231  }
232 
233  m_NumberOfFilters = 0;
234  m_DepthOfDecomposition = 0;
235 
236  for (unsigned int posRule = 0; posRule < m_WaveletPacketRule.size(); posRule++)
237  InterpretRule(posRule, 0);
238 }
239 
240 template <class TInputImage, class TOutputImage, class TFilter>
242  unsigned int& ruleID, unsigned int curDepth)
243 {
244  if (curDepth > m_DepthOfDecomposition)
245  m_DepthOfDecomposition = curDepth;
246 
247  if (m_WaveletPacketRule[ruleID] == true)
248  {
249  m_FilterList->PushBack(FilterType::New());
250 
251  FilterPointerType filter = m_FilterList->GetNthElement(m_NumberOfFilters);
252  filter->SetSubsampleImageFactor(GetSubsampleImageFactor());
253  if (GetSubsampleImageFactor() == 1)
254  filter->SetUpSampleFilterFactor(curDepth);
255 
256  m_NumberOfFilters++;
257 
258  const unsigned int filterBankInputSize = 1 << InputImageDimension;
259 
260  for (unsigned int i = 0; i < filterBankInputSize; ++i)
261  {
262  ruleID++;
263  InterpretRule(ruleID, curDepth + 1);
264  }
265  }
266 }
267 
268 } // end of namespace otb
269 
270 #endif
otb::WaveletPacketTransform< TInputImage, TOutputImage, TFilter, Wavelet::INVERSE, FullyDecomposedWaveletPacketCost< TInputImage > >::InputImageIterator
InputImageListType::Iterator InputImageIterator
Definition: otbWaveletPacketTransform.h:278
otb::WaveletPacketTransform< TInputImage, TOutputImage, TFilter, Wavelet::FORWARD, TCost >::FilterPointerType
FilterType::Pointer FilterPointerType
Definition: otbWaveletPacketTransform.h:148
otb
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
Definition: otbJoinContainer.h:32
otb::WaveletPacketTransform< TInputImage, TOutputImage, TFilter, Wavelet::INVERSE, FullyDecomposedWaveletPacketCost< TInputImage > >::IndexType
InputImageType::IndexType IndexType
Definition: otbWaveletPacketTransform.h:273
otb::WaveletPacketTransform< TInputImage, TOutputImage, TFilter, Wavelet::INVERSE, FullyDecomposedWaveletPacketCost< TInputImage > >::OutputImageRegionType
OutputImageType::RegionType OutputImageRegionType
Definition: otbWaveletPacketTransform.h:282
otbMacro.h
otb::ImageListSource::OutputImageType
TOutputImage OutputImageType
Definition: otbImageListSource.h:59
otb::WaveletPacketTransform::WaveletPacketTransform
WaveletPacketTransform()
otb::WaveletPacketTransform
Wavelet packet transformation framework.
Definition: otbWaveletPacketTransform.h:64
otb::ImageListToImageFilter::InputImageRegionType
InputImageType::RegionType InputImageRegionType
Definition: otbImageListToImageFilter.h:58
otb::ImageListToImageFilter::SizeType
InputImageType::SizeType SizeType
Definition: otbImageListToImageFilter.h:60
otb::WaveletPacketTransform< TInputImage, TOutputImage, TFilter, Wavelet::INVERSE, FullyDecomposedWaveletPacketCost< TInputImage > >::FilterPointerType
FilterType::Pointer FilterPointerType
Definition: otbWaveletPacketTransform.h:287
otbMsgDevMacro
#define otbMsgDevMacro(x)
Definition: otbMacro.h:64
otbWaveletPacketTransform.h
otb::WaveletPacketTransform< TInputImage, TOutputImage, TFilter, Wavelet::INVERSE, FullyDecomposedWaveletPacketCost< TInputImage > >::OutputImageIndexType
OutputImageType::IndexType OutputImageIndexType
Definition: otbWaveletPacketTransform.h:284
otb::WaveletPacketTransform< TInputImage, TOutputImage, TFilter, Wavelet::INVERSE, FullyDecomposedWaveletPacketCost< TInputImage > >::OutputImageSizeType
OutputImageType::SizeType OutputImageSizeType
Definition: otbWaveletPacketTransform.h:283