OTB  6.1.0
Orfeo Toolbox
otbMorphologicalPyramidAnalysisFilter.txx
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2017 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 otbMorphologicalPyramidAnalysisFilter_txx
22 #define otbMorphologicalPyramidAnalysisFilter_txx
23 
25 
26 #include "itkSubtractImageFilter.h"
27 #include "itkMaximumImageFilter.h"
28 #include "itkImageDuplicator.h"
30 #include "itkProgressAccumulator.h"
31 #include "otbMacro.h"
32 
33 namespace otb
34 {
38 template <class TInputImage, class TOutputImage, class TMorphoFilter>
41 {
42  this->SetNumberOfRequiredOutputs(2);
43  m_DecimationRatio = 2.0;
44  m_NumberOfLevels = 4;
45  OutputImageListPointerType supFilter = OutputImageListType::New();
46  this->SetNthOutput(0, supFilter.GetPointer());
47  OutputImageListPointerType infFilter = OutputImageListType::New();
48  this->SetNthOutput(1, infFilter.GetPointer());
49  OutputImageListPointerType outputList = OutputImageListType::New();
50  this->SetNthOutput(2, outputList.GetPointer());
51  OutputImageListPointerType supDeci = OutputImageListType::New();
52  this->SetNthOutput(3, supDeci.GetPointer());
53  OutputImageListPointerType infDeci = OutputImageListType::New();
54  this->SetNthOutput(4, infDeci.GetPointer());
55 }
56 
60 template <class TInputImage, class TOutputImage, class TMorphoFilter>
63 
68 template <class TInputImage, class TOutputImage, class TMorphoFilter>
69 typename MorphologicalPyramidAnalysisFilter<TInputImage, TOutputImage, TMorphoFilter>
70 ::OutputImageListType*
72 ::GetOutput(void)
73 {
74  return dynamic_cast<OutputImageListType*>(this->itk::ProcessObject::GetOutput(2));
75 }
76 
81 template <class TInputImage, class TOutputImage, class TMorphoFilter>
82 typename MorphologicalPyramidAnalysisFilter<TInputImage, TOutputImage, TMorphoFilter>
83 ::OutputImageListType*
85 ::GetSupFilter(void)
86 {
87  return dynamic_cast<OutputImageListType*>(this->itk::ProcessObject::GetOutput(0));
88 }
89 
94 template <class TInputImage, class TOutputImage, class TMorphoFilter>
95 typename MorphologicalPyramidAnalysisFilter<TInputImage, TOutputImage, TMorphoFilter>
96 ::OutputImageListType*
98 ::GetInfFilter(void)
99 {
100  return dynamic_cast<OutputImageListType*>(this->itk::ProcessObject::GetOutput(1));
101 }
102 
107 template <class TInputImage, class TOutputImage, class TMorphoFilter>
108 typename MorphologicalPyramidAnalysisFilter<TInputImage, TOutputImage, TMorphoFilter>
109 ::OutputImageListType*
111 ::GetSupDeci(void)
112 {
113  return dynamic_cast<OutputImageListType*>(this->itk::ProcessObject::GetOutput(3));
114 }
115 
120 template <class TInputImage, class TOutputImage, class TMorphoFilter>
121 typename MorphologicalPyramidAnalysisFilter<TInputImage, TOutputImage, TMorphoFilter>
122 ::OutputImageListType*
124 ::GetInfDeci(void)
125 {
126  return dynamic_cast<OutputImageListType*>(this->itk::ProcessObject::GetOutput(4));
127 }
128 
132 template <class TInputImage, class TOutputImage, class TMorphoFilter>
133 void
135 ::GenerateData(void)
136 {
137  // Input image pointer
138  OutputImageListType * OutputImageList = this->GetOutput();
139 
140  // Output images pointers
141  OutputImageListType * supFilter = this->GetSupFilter();
142  OutputImageListType * infFilter = this->GetInfFilter();
143  OutputImageListType * supDeci = this->GetSupDeci();
144  OutputImageListType * infDeci = this->GetInfDeci();
145 
146  // typedefs of the filters
149  typedef itk::ImageDuplicator<InputImageType> DuplicatorType;
151 
152  // Input Image duplication to the currentImage Pointer
153  typename DuplicatorType::Pointer duplicator = DuplicatorType::New();
154  duplicator->SetInputImage(this->GetInput());
155  duplicator->Update();
156  typename InputImageType::Pointer currentImage = duplicator->GetOutput();
157  typename InputImageType::Pointer upsampled;
158 
159  // Structuring element size computation
160  const int structElementDimension = static_cast<int>(vcl_ceil(this->GetDecimationRatio() / 2.));
161 
162  // Structuring element creation
163  KernelType structuringElement;
164  structuringElement.SetRadius(structElementDimension);
165  structuringElement.CreateStructuringElement();
166 
167  // Filters declarations
168  typename MorphoFilterType::Pointer morphoFilter;
169  typename MaxFilterType::Pointer max;
170  typename SubtractFilterType::Pointer subtract1, subtract2, subtract3, subtract4;
171  typename ResamplerType::Pointer resampler1, resampler2;
172 
173  // Size declaration
174  typename InputImageType::SizeType size;
175 
176  // local variables declarations and initializations
177  int i = 0;
178  int sizeTmp;
179  //--------------------------------------------------------//
180  // Main loop //
181  //--------------------------------------------------------//
182  // While the number of iterations is not reached
183  otbMsgDevMacro(<< "Entering main loop");
184  while (i < this->GetNumberOfLevels())
185  {
186 
187  // morphological filtering
188  morphoFilter = MorphoFilterType::New();
189  morphoFilter->SetKernel(structuringElement);
190  morphoFilter->SetInput(currentImage);
191  morphoFilter->Update();
192 
193  // Maximum between current and filtered image
194  max = MaxFilterType::New();
195  max->SetInput1(morphoFilter->GetOutput());
196  max->SetInput2(currentImage);
197  max->Update();
198 
199  // SupFilter detail image computation
200  subtract1 = SubtractFilterType::New();
201  subtract1->SetInput1(max->GetOutput());
202  subtract1->SetInput2(morphoFilter->GetOutput());
203  subtract1->Update();
205  << "MorphologicalPyramidAnalysisFilter: subtract1 OK " <<
206  subtract1->GetOutput()->GetLargestPossibleRegion().GetSize());
207  supFilter->PushBack(subtract1->GetOutput());
208  otbMsgDevMacro("MorphologicalPyramidAnalysisFilter: step " << i << " - Image appended to SupFilter");
209 
210  // InfFilter detail image computation
211  subtract2 = SubtractFilterType::New();
212  subtract2->SetInput1(max->GetOutput());
213  subtract2->SetInput2(currentImage);
214  subtract2->Update();
216  << "MorphologicalPyramidAnalysisFilter: subtract2 OK " <<
217  subtract2->GetOutput()->GetLargestPossibleRegion().GetSize());
218  infFilter->PushBack(subtract2->GetOutput());
219  otbMsgDevMacro("MorphologicalPyramidAnalysisFilter: step " << i << " - Image appended to InfFilter");
220 
221  // New Size
222  size = morphoFilter->GetOutput()->GetLargestPossibleRegion().GetSize();
223  for (unsigned int j = 0; j < InputImageType::ImageDimension; ++j)
224  {
225  sizeTmp = size[j];
226  // As we knwow that our values will always be positive ones, we can simulate round by ceil(value+0.5)
227  size[j] = static_cast<unsigned int>(vcl_ceil((static_cast<double>(sizeTmp) / this->GetDecimationRatio()) + 0.5));
228  }
229  otbMsgDevMacro(<< "New size: " << size);
230 
231  // Image subsampling
232  // Current image becomes the newly subsampled image
233  resampler1 = ResamplerType::New();
234  resampler1->SetInput(morphoFilter->GetOutput());
235  resampler1->SetSize(size);
236  resampler1->Update();
237  currentImage = resampler1->GetOutput();
238 
240  << "MorphologicalPyramidAnalysisFilter: DownSampling OK " << currentImage->GetLargestPossibleRegion().GetSize());
241  // New current image is appended to the output list
242  OutputImageList->PushBack(currentImage);
243 
244  // Image upsampling
245  resampler2 = ResamplerType::New();
246  resampler2->SetInput(resampler1->GetOutput());
247  resampler2->SetSize(morphoFilter->GetOutput()->GetLargestPossibleRegion().GetSize());
248  resampler2->Update();
249 
251  << "MorphologicalPyramidAnalysisFilter: UpSampling OK " <<
252  resampler2->GetOutput()->GetLargestPossibleRegion().GetSize());
253  // Computation of the details lost in the subsampling operation
254  max = MaxFilterType::New();
255  max->SetInput1(morphoFilter->GetOutput());
256  max->SetInput2(resampler2->GetOutput());
257  max->Update();
259  << "MorphologicalPyramidAnalysisFilter: Max OK " << max->GetOutput()->GetLargestPossibleRegion().GetSize());
260 
261  // InfDeci detail image computation
262  subtract4 = SubtractFilterType::New();
263  subtract4->SetInput1(max->GetOutput());
264  subtract4->SetInput2(morphoFilter->GetOutput());
265  subtract4->Update();
267  << "MorphologicalPyramidAnalysisFilter: subtract4 OK " <<
268  subtract4->GetOutput()->GetLargestPossibleRegion().GetSize());
269  infDeci->PushBack(subtract4->GetOutput());
270  otbMsgDevMacro("MorphologicalPyramidAnalysisFilter: step " << i << " - Image appended to InfDeci");
271 
272  // SupDeci detail image computation
273  subtract3 = SubtractFilterType::New();
274  subtract3->SetInput1(max->GetOutput());
275  subtract3->SetInput2(resampler2->GetOutput());
276  subtract3->Update();
278  << "MorphologicalPyramidAnalysisFilter: subtract3 OK " <<
279  subtract3->GetOutput()->GetLargestPossibleRegion().GetSize());
280  supDeci->PushBack(subtract3->GetOutput());
281  otbMsgDevMacro("MorphologicalPyramidAnalysisFilter: step " << i << " - Image appended to SupDeci");
282 
283  // Iteration ounter incrementation
284  ++i;
285  }
286  otbMsgDevMacro(<< "Exiting main loop");
287 }
itk::Size< Monteverdi_DIMENSION > SizeType
Definition: mvdTypes.h:146
OutputImageListType * GetOutput(void) ITK_OVERRIDE
This class performs the resampling of the given image to the given size.
OutputImageListType * GetSupFilter(void)
OutputImageListType * GetInfFilter(void)
OutputImageListType * GetSupDeci(void)
OutputImageListType * GetInfDeci(void)
#define otbMsgDevMacro(x)
Definition: otbMacro.h:98
DataObject * GetOutput(const DataObjectIdentifierType &key)