OTB  5.0.0
Orfeo Toolbox
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 }
53 
57 template <class TInputImage, class TOutputImage, class TMorphoFilter>
60 
65 template <class TInputImage, class TOutputImage, class TMorphoFilter>
66 typename MorphologicalPyramidAnalysisFilter<TInputImage, TOutputImage, TMorphoFilter>
67 ::OutputImageListType*
69 ::GetOutput(void)
70 {
71  return dynamic_cast<OutputImageListType*>(this->itk::ProcessObject::GetOutput(2));
72 }
73 
78 template <class TInputImage, class TOutputImage, class TMorphoFilter>
79 typename MorphologicalPyramidAnalysisFilter<TInputImage, TOutputImage, TMorphoFilter>
80 ::OutputImageListType*
82 ::GetSupFilter(void)
83 {
84  return dynamic_cast<OutputImageListType*>(this->itk::ProcessObject::GetOutput(0));
85 }
86 
91 template <class TInputImage, class TOutputImage, class TMorphoFilter>
92 typename MorphologicalPyramidAnalysisFilter<TInputImage, TOutputImage, TMorphoFilter>
93 ::OutputImageListType*
95 ::GetInfFilter(void)
96 {
97  return dynamic_cast<OutputImageListType*>(this->itk::ProcessObject::GetOutput(1));
98 }
99 
104 template <class TInputImage, class TOutputImage, class TMorphoFilter>
105 typename MorphologicalPyramidAnalysisFilter<TInputImage, TOutputImage, TMorphoFilter>
106 ::OutputImageListType*
108 ::GetSupDeci(void)
109 {
110  return dynamic_cast<OutputImageListType*>(this->itk::ProcessObject::GetOutput(3));
111 }
112 
117 template <class TInputImage, class TOutputImage, class TMorphoFilter>
118 typename MorphologicalPyramidAnalysisFilter<TInputImage, TOutputImage, TMorphoFilter>
119 ::OutputImageListType*
121 ::GetInfDeci(void)
122 {
123  return dynamic_cast<OutputImageListType*>(this->itk::ProcessObject::GetOutput(4));
124 }
125 
129 template <class TInputImage, class TOutputImage, class TMorphoFilter>
130 void
132 ::GenerateData(void)
133 {
134  // Input image pointer
135  OutputImageListType * OutputImageList = this->GetOutput();
136 
137  // Output images pointers
138  OutputImageListType * supFilter = this->GetSupFilter();
139  OutputImageListType * infFilter = this->GetInfFilter();
140  OutputImageListType * supDeci = this->GetSupDeci();
141  OutputImageListType * infDeci = this->GetInfDeci();
142 
143  // typedefs of the filters
146  typedef itk::ImageDuplicator<InputImageType> DuplicatorType;
148 
149  // Input Image duplication to the currentImage Pointer
150  typename DuplicatorType::Pointer duplicator = DuplicatorType::New();
151  duplicator->SetInputImage(this->GetInput());
152  duplicator->Update();
153  typename InputImageType::Pointer currentImage = duplicator->GetOutput();
154  typename InputImageType::Pointer upsampled;
155 
156  // Structuring element size computation
157  const int structElementDimension = static_cast<int>(vcl_ceil(this->GetDecimationRatio() / 2.));
158 
159  // Structuring element creation
160  KernelType structuringElement;
161  structuringElement.SetRadius(structElementDimension);
162  structuringElement.CreateStructuringElement();
163 
164  // Filters declarations
165  typename MorphoFilterType::Pointer morphoFilter;
166  typename MaxFilterType::Pointer max;
167  typename SubtractFilterType::Pointer subtract1, subtract2, subtract3, subtract4;
168  typename ResamplerType::Pointer resampler1, resampler2;
169 
170  // Size declaration
171  typename InputImageType::SizeType size;
172 
173  // local variables declarations and initializations
174  int i = 0;
175  int sizeTmp;
176  //--------------------------------------------------------//
177  // Main loop //
178  //--------------------------------------------------------//
179  // While the number of iterations is not reached
180  otbMsgDevMacro(<< "Entering main loop");
181  while (i < this->GetNumberOfLevels())
182  {
183 
184  // morphological filtering
185  morphoFilter = MorphoFilterType::New();
186  morphoFilter->SetKernel(structuringElement);
187  morphoFilter->SetInput(currentImage);
188  morphoFilter->Update();
189 
190  // Maximum between current and filtered image
191  max = MaxFilterType::New();
192  max->SetInput1(morphoFilter->GetOutput());
193  max->SetInput2(currentImage);
194  max->Update();
195 
196  // SupFilter detail image computation
197  subtract1 = SubtractFilterType::New();
198  subtract1->SetInput1(max->GetOutput());
199  subtract1->SetInput2(morphoFilter->GetOutput());
200  subtract1->Update();
202  << "MorphologicalPyramidAnalysisFilter: subtract1 OK " <<
203  subtract1->GetOutput()->GetLargestPossibleRegion().GetSize());
204  supFilter->PushBack(subtract1->GetOutput());
205  otbMsgDevMacro("MorphologicalPyramidAnalysisFilter: step " << i << " - Image appended to SupFilter");
206 
207  // InfFilter detail image computation
208  subtract2 = SubtractFilterType::New();
209  subtract2->SetInput1(max->GetOutput());
210  subtract2->SetInput2(currentImage);
211  subtract2->Update();
213  << "MorphologicalPyramidAnalysisFilter: subtract2 OK " <<
214  subtract2->GetOutput()->GetLargestPossibleRegion().GetSize());
215  infFilter->PushBack(subtract2->GetOutput());
216  otbMsgDevMacro("MorphologicalPyramidAnalysisFilter: step " << i << " - Image appended to InfFilter");
217 
218  // New Size
219  size = morphoFilter->GetOutput()->GetLargestPossibleRegion().GetSize();
220  for (int j = 0; j < InputImageType::ImageDimension; ++j)
221  {
222  sizeTmp = size[j];
223  // As we knwow that our values will always be positive ones, we can simulate round by ceil(value+0.5)
224  size[j] = static_cast<unsigned int>(vcl_ceil((static_cast<double>(sizeTmp) / this->GetDecimationRatio()) + 0.5));
225  }
226  otbMsgDevMacro(<< "New size: " << size);
227 
228  // Image subsampling
229  // Current image becomes the newly subsampled image
230  resampler1 = ResamplerType::New();
231  resampler1->SetInput(morphoFilter->GetOutput());
232  resampler1->SetSize(size);
233  resampler1->Update();
234  currentImage = resampler1->GetOutput();
235 
237  << "MorphologicalPyramidAnalysisFilter: DownSampling OK " << currentImage->GetLargestPossibleRegion().GetSize());
238  // New current image is appeneded to the output list
239  OutputImageList->PushBack(currentImage);
240 
241  // Image upsampling
242  resampler2 = ResamplerType::New();
243  resampler2->SetInput(resampler1->GetOutput());
244  resampler2->SetSize(morphoFilter->GetOutput()->GetLargestPossibleRegion().GetSize());
245  resampler2->Update();
246 
248  << "MorphologicalPyramidAnalysisFilter: UpSampling OK " <<
249  resampler2->GetOutput()->GetLargestPossibleRegion().GetSize());
250  // Computation of the details lost in the subsampling operation
251  max = MaxFilterType::New();
252  max->SetInput1(morphoFilter->GetOutput());
253  max->SetInput2(resampler2->GetOutput());
254  max->Update();
256  << "MorphologicalPyramidAnalysisFilter: Max OK " << max->GetOutput()->GetLargestPossibleRegion().GetSize());
257 
258  // InfDeci detail image computation
259  subtract4 = SubtractFilterType::New();
260  subtract4->SetInput1(max->GetOutput());
261  subtract4->SetInput2(morphoFilter->GetOutput());
262  subtract4->Update();
264  << "MorphologicalPyramidAnalysisFilter: subtract4 OK " <<
265  subtract4->GetOutput()->GetLargestPossibleRegion().GetSize());
266  infDeci->PushBack(subtract4->GetOutput());
267  otbMsgDevMacro("MorphologicalPyramidAnalysisFilter: step " << i << " - Image appended to InfDeci");
268 
269  // SupDeci detail image computation
270  subtract3 = SubtractFilterType::New();
271  subtract3->SetInput1(max->GetOutput());
272  subtract3->SetInput2(resampler2->GetOutput());
273  subtract3->Update();
275  << "MorphologicalPyramidAnalysisFilter: subtract3 OK " <<
276  subtract3->GetOutput()->GetLargestPossibleRegion().GetSize());
277  supDeci->PushBack(subtract3->GetOutput());
278  otbMsgDevMacro("MorphologicalPyramidAnalysisFilter: step " << i << " - Image appended to SupDeci");
279 
280  // Iteration ounter incrementation
281  ++i;
282  }
283  otbMsgDevMacro(<< "Exiting main loop");
284 }
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)
OutputImageListType * GetOutput(void)
#define otbMsgDevMacro(x)
Definition: otbMacro.h:95
DataObject * GetOutput(const DataObjectIdentifierType &key)