Orfeo ToolBox  4.2
Orfeo ToolBox is not a black box
otbMorphologicalPyramidAnalysisFilter.txx
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: ORFEO Toolbox
4  Language: C++
5  Date: $Date$
6  Version: $Revision$
7 
8 
9  Copyright (c) Centre National d'Etudes Spatiales. All rights reserved.
10  See OTBCopyright.txt for details.
11 
12 
13  This software is distributed WITHOUT ANY WARRANTY; without even
14  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
15  PURPOSE. See the above copyright notices for more information.
16 
17 =========================================================================*/
18 #ifndef __otbMorphologicalPyramidAnalysisFilter_txx
19 #define __otbMorphologicalPyramidAnalysisFilter_txx
20 
22 
23 #include "itkSubtractImageFilter.h"
24 #include "itkMaximumImageFilter.h"
25 #include "itkImageDuplicator.h"
27 #include "itkProgressAccumulator.h"
28 #include "otbMacro.h"
29 
30 namespace otb
31 {
35 template <class TInputImage, class TOutputImage, class TMorphoFilter>
38 {
39  this->SetNumberOfRequiredOutputs(2);
40  m_DecimationRatio = 2.0;
41  m_NumberOfLevels = 4;
42  OutputImageListPointerType supFilter = OutputImageListType::New();
43  this->SetNthOutput(0, supFilter.GetPointer());
44  OutputImageListPointerType infFilter = OutputImageListType::New();
45  this->SetNthOutput(1, infFilter.GetPointer());
46  OutputImageListPointerType outputList = OutputImageListType::New();
47  this->SetNthOutput(2, outputList.GetPointer());
48  OutputImageListPointerType supDeci = OutputImageListType::New();
49  this->SetNthOutput(3, supDeci.GetPointer());
50  OutputImageListPointerType infDeci = OutputImageListType::New();
51  this->SetNthOutput(4, infDeci.GetPointer());
52 }
56 template <class TInputImage, class TOutputImage, class TMorphoFilter>
63 template <class TInputImage, class TOutputImage, class TMorphoFilter>
65 ::OutputImageListType*
68 {
69  return dynamic_cast<OutputImageListType*>(this->itk::ProcessObject::GetOutput(2));
70 }
75 template <class TInputImage, class TOutputImage, class TMorphoFilter>
77 ::OutputImageListType*
80 {
81  return dynamic_cast<OutputImageListType*>(this->itk::ProcessObject::GetOutput(0));
82 }
87 template <class TInputImage, class TOutputImage, class TMorphoFilter>
89 ::OutputImageListType*
92 {
93  return dynamic_cast<OutputImageListType*>(this->itk::ProcessObject::GetOutput(1));
94 }
99 template <class TInputImage, class TOutputImage, class TMorphoFilter>
101 ::OutputImageListType*
104 {
105  return dynamic_cast<OutputImageListType*>(this->itk::ProcessObject::GetOutput(3));
106 }
111 template <class TInputImage, class TOutputImage, class TMorphoFilter>
113 ::OutputImageListType*
116 {
117  return dynamic_cast<OutputImageListType*>(this->itk::ProcessObject::GetOutput(4));
118 }
122 template <class TInputImage, class TOutputImage, class TMorphoFilter>
123 void
126 {
127  // Input image pointer
128  OutputImageListType * OutputImageList = this->GetOutput();
129 
130  // Output images pointers
131  OutputImageListType * supFilter = this->GetSupFilter();
132  OutputImageListType * infFilter = this->GetInfFilter();
133  OutputImageListType * supDeci = this->GetSupDeci();
134  OutputImageListType * infDeci = this->GetInfDeci();
135 
136  // typedefs of the filters
139  typedef itk::ImageDuplicator<InputImageType> DuplicatorType;
141 
142  // Input Image duplication to the currentImage Pointer
143  typename DuplicatorType::Pointer duplicator = DuplicatorType::New();
144  duplicator->SetInputImage(this->GetInput());
145  duplicator->Update();
146  typename InputImageType::Pointer currentImage = duplicator->GetOutput();
147  typename InputImageType::Pointer upsampled;
148 
149  // Structuring element size computation
150  const int structElementDimension = static_cast<int>(vcl_ceil(this->GetDecimationRatio() / 2.));
151 
152  // Structuring element creation
153  KernelType structuringElement;
154  structuringElement.SetRadius(structElementDimension);
155  structuringElement.CreateStructuringElement();
156 
157  // Filters declarations
158  typename MorphoFilterType::Pointer morphoFilter;
159  typename MaxFilterType::Pointer max;
160  typename SubtractFilterType::Pointer subtract1, subtract2, subtract3, subtract4;
161  typename ResamplerType::Pointer resampler1, resampler2;
162 
163  // Size declaration
164  typename InputImageType::SizeType size;
165 
166  // local variables declarations and initializations
167  int i = 0;
168  int sizeTmp;
169  //--------------------------------------------------------//
170  // Main loop //
171  //--------------------------------------------------------//
172  // While the number of iterations is not reached
173  otbMsgDevMacro(<< "Entering main loop");
174  while (i < this->GetNumberOfLevels())
175  {
176 
177  // morphological filtering
178  morphoFilter = MorphoFilterType::New();
179  morphoFilter->SetKernel(structuringElement);
180  morphoFilter->SetInput(currentImage);
181  morphoFilter->Update();
182 
183  // Maximum between current and filtered image
184  max = MaxFilterType::New();
185  max->SetInput1(morphoFilter->GetOutput());
186  max->SetInput2(currentImage);
187  max->Update();
188 
189  // SupFilter detail image computation
190  subtract1 = SubtractFilterType::New();
191  subtract1->SetInput1(max->GetOutput());
192  subtract1->SetInput2(morphoFilter->GetOutput());
193  subtract1->Update();
195  << "MorphologicalPyramidAnalysisFilter: subtract1 OK " <<
196  subtract1->GetOutput()->GetLargestPossibleRegion().GetSize());
197  supFilter->PushBack(subtract1->GetOutput());
198  otbMsgDevMacro("MorphologicalPyramidAnalysisFilter: step " << i << " - Image appended to SupFilter");
199 
200  // InfFilter detail image computation
201  subtract2 = SubtractFilterType::New();
202  subtract2->SetInput1(max->GetOutput());
203  subtract2->SetInput2(currentImage);
204  subtract2->Update();
206  << "MorphologicalPyramidAnalysisFilter: subtract2 OK " <<
207  subtract2->GetOutput()->GetLargestPossibleRegion().GetSize());
208  infFilter->PushBack(subtract2->GetOutput());
209  otbMsgDevMacro("MorphologicalPyramidAnalysisFilter: step " << i << " - Image appended to InfFilter");
210 
211  // New Size
212  size = morphoFilter->GetOutput()->GetLargestPossibleRegion().GetSize();
213  for (int j = 0; j < InputImageType::ImageDimension; ++j)
214  {
215  sizeTmp = size[j];
216  // As we knwow that our values will always be positive ones, we can simulate round by ceil(value+0.5)
217  size[j] = static_cast<unsigned int>(vcl_ceil((static_cast<double>(sizeTmp) / this->GetDecimationRatio()) + 0.5));
218  }
219  otbMsgDevMacro(<< "New size: " << size);
220 
221  // Image subsampling
222  // Current image becomes the newly subsampled image
223  resampler1 = ResamplerType::New();
224  resampler1->SetInput(morphoFilter->GetOutput());
225  resampler1->SetSize(size);
226  resampler1->Update();
227  currentImage = resampler1->GetOutput();
228 
230  << "MorphologicalPyramidAnalysisFilter: DownSampling OK " << currentImage->GetLargestPossibleRegion().GetSize());
231  // New current image is appeneded to the output list
232  OutputImageList->PushBack(currentImage);
233 
234  // Image upsampling
235  resampler2 = ResamplerType::New();
236  resampler2->SetInput(resampler1->GetOutput());
237  resampler2->SetSize(morphoFilter->GetOutput()->GetLargestPossibleRegion().GetSize());
238  resampler2->Update();
239 
241  << "MorphologicalPyramidAnalysisFilter: UpSampling OK " <<
242  resampler2->GetOutput()->GetLargestPossibleRegion().GetSize());
243  // Computation of the details lost in the subsampling operation
244  max = MaxFilterType::New();
245  max->SetInput1(morphoFilter->GetOutput());
246  max->SetInput2(resampler2->GetOutput());
247  max->Update();
249  << "MorphologicalPyramidAnalysisFilter: Max OK " << max->GetOutput()->GetLargestPossibleRegion().GetSize());
250 
251  // InfDeci detail image computation
252  subtract4 = SubtractFilterType::New();
253  subtract4->SetInput1(max->GetOutput());
254  subtract4->SetInput2(morphoFilter->GetOutput());
255  subtract4->Update();
257  << "MorphologicalPyramidAnalysisFilter: subtract4 OK " <<
258  subtract4->GetOutput()->GetLargestPossibleRegion().GetSize());
259  infDeci->PushBack(subtract4->GetOutput());
260  otbMsgDevMacro("MorphologicalPyramidAnalysisFilter: step " << i << " - Image appended to InfDeci");
261 
262  // SupDeci detail image computation
263  subtract3 = SubtractFilterType::New();
264  subtract3->SetInput1(max->GetOutput());
265  subtract3->SetInput2(resampler2->GetOutput());
266  subtract3->Update();
268  << "MorphologicalPyramidAnalysisFilter: subtract3 OK " <<
269  subtract3->GetOutput()->GetLargestPossibleRegion().GetSize());
270  supDeci->PushBack(subtract3->GetOutput());
271  otbMsgDevMacro("MorphologicalPyramidAnalysisFilter: step " << i << " - Image appended to SupDeci");
272 
273  // Iteration ounter incrementation
274  ++i;
275  }
276  otbMsgDevMacro(<< "Exiting main loop");
277 }
281 template <class TInputImage, class TOutputImage, class TMorphoFilter>
282 void
284 ::PrintSelf(std::ostream& os, itk::Indent indent) const
285 {
286  Superclass::PrintSelf(os, indent);
287  os << indent << "DecimationRatio: " << m_DecimationRatio << std::endl;
288  os << indent << "NumberOfLevels: " << m_NumberOfLevels << std::endl;
289 }
290 } // End namespace otb
291 #endif
This class performs the resampling of the given image to the given size.
ObjectType * GetPointer() const
This class represent a list of images.
Definition: otbImageList.h:34
virtual void PrintSelf(std::ostream &os, itk::Indent indent) const
void PushBack(ObjectType *element)
Multiscale analysis filter using the morphological pyramid algorithm.
#define otbMsgDevMacro(x)
Definition: otbMacro.h:94