OTB  5.0.0
Orfeo Toolbox
otbSFSTexturesImageFilter.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 __otbSFSTexturesImageFilter_txx
19 #define __otbSFSTexturesImageFilter_txx
20 
22 
23 #include "itkProgressReporter.h"
24 #include "itkImageRegionIterator.h"
26 #include "otbMath.h"
27 
28 namespace otb
29 {
30 
31 template <class TInputImage, class TOutputImage>
34 {
35  this->SetNumberOfRequiredInputs(1);
36  this->SetNumberOfRequiredInputs(1);
37  this->SetNumberOfRequiredOutputs(6);
38  this->SetNumberOfRequiredOutputs(1);
39 
40  this->SetNthOutput(0, OutputImageType::New());
41  this->SetNthOutput(1, OutputImageType::New());
42  this->SetNthOutput(2, OutputImageType::New());
43  this->SetNthOutput(3, OutputImageType::New());
44  this->SetNthOutput(4, OutputImageType::New());
45  this->SetNthOutput(5, OutputImageType::New());
46 
47  m_Radius = this->GetSpatialThreshold();
48  m_FunctorList.clear();
49 
50 }
56 // Return output length image
57 template <class TInputImage, class TOutputImage>
61 {
62  if (this->GetNumberOfOutputs() < 1)
63  {
64  return 0;
65  }
66  if (this->GetTexturesStatus()[0] == false)
67  {
68  itkExceptionMacro(<< "Impossible to create length image : texture not selected");
69  }
70  return static_cast<const OutputImageType *> (this->itk::ProcessObject::GetOutput(0));
71 }
72 template <class TInputImage, class TOutputImage>
76 {
77  if (this->GetNumberOfOutputs() < 1)
78  {
79  return 0;
80  }
81  if (this->GetTexturesStatus()[0] == false)
82  {
83  itkExceptionMacro(<< "Impossible to create length image : texture not selected");
84  }
85  return static_cast<OutputImageType *>(this->itk::ProcessObject::GetOutput(0));
86 }
88 
89 // Return output width image
90 template <class TInputImage, class TOutputImage>
94 {
95  if (this->GetNumberOfOutputs() < 2)
96  {
97  return 0;
98  }
99  if (this->GetTexturesStatus()[1] == false)
100  {
101  itkExceptionMacro(<< "Impossible to create width image : texture not selected");
102  }
103  return static_cast<const OutputImageType *> (this->itk::ProcessObject::GetOutput(1));
104 }
105 template <class TInputImage, class TOutputImage>
109 {
110  if (this->GetNumberOfOutputs() < 2)
111  {
112  return 0;
113  }
114  if (this->GetTexturesStatus()[1] == false)
115  {
116  itkExceptionMacro(<< "Impossible to create width image : texture not selected");
117  }
118  return static_cast<OutputImageType *>(this->itk::ProcessObject::GetOutput(1));
119 }
120 
121 //Return output PSI image
122 template <class TInputImage, class TOutputImage>
126 {
127  if (this->GetNumberOfOutputs() < 3)
128  {
129  return 0;
130  }
131  if (this->GetTexturesStatus()[2] == false)
132  {
133  itkExceptionMacro(<< "Impossible to create PSI image : texture not selected");
134  }
135  return static_cast<const OutputImageType *> (this->itk::ProcessObject::GetOutput(2));
136 }
137 template <class TInputImage, class TOutputImage>
141 {
142  if (this->GetNumberOfOutputs() < 3)
143  {
144  return 0;
145  }
146  if (this->GetTexturesStatus()[2] == false)
147  {
148  itkExceptionMacro(<< "Impossible to create PSI image : texture not selected");
149  }
150 
151  return static_cast<OutputImageType *>(this->itk::ProcessObject::GetOutput(2));
152 }
153 
154 // Return output WMean image
155 template <class TInputImage, class TOutputImage>
159 {
160  if (this->GetNumberOfOutputs() < 4)
161  {
162  return 0;
163  }
164  if (this->GetTexturesStatus()[3] == false)
165  {
166  itkExceptionMacro(<< "Impossible to create W-Mean image : texture not selected");
167  }
168  return static_cast<const OutputImageType *> (this->itk::ProcessObject::GetOutput(3));
169 }
170 template <class TInputImage, class TOutputImage>
174 {
175  if (this->GetNumberOfOutputs() < 4)
176  {
177  return 0;
178  }
179  if (this->GetTexturesStatus()[3] == false)
180  {
181  itkExceptionMacro(<< "Impossible to create W-Mean image : texture not selected");
182  }
183  return static_cast<OutputImageType *>(this->itk::ProcessObject::GetOutput(3));
184 }
185 
186 // Return output ratio image
187 template <class TInputImage, class TOutputImage>
191 {
192  if (this->GetNumberOfOutputs() < 5)
193  {
194  return 0;
195  }
196  if (this->GetTexturesStatus()[4] == false)
197  {
198  itkExceptionMacro(<< "Impossible to create Ratio image : texture not selected");
199  }
200  return static_cast<const OutputImageType *> (this->itk::ProcessObject::GetOutput(4));
201 }
202 template <class TInputImage, class TOutputImage>
206 {
207  if (this->GetNumberOfOutputs() < 5)
208  {
209  return 0;
210  }
211  if (this->GetTexturesStatus()[4] == false)
212  {
213  itkExceptionMacro(<< "Impossible to create Ratio image : texture not selected");
214  }
215  return static_cast<OutputImageType *>(this->itk::ProcessObject::GetOutput(4));
216 }
217 
218 // Return output SD image
219 template <class TInputImage, class TOutputImage>
223 {
224  if (this->GetNumberOfOutputs() < 6)
225  {
226  return 0;
227  }
228  if (this->GetTexturesStatus()[5] == false)
229  {
230  itkExceptionMacro(<< "Impossible to create SD image : texture not selected");
231  }
232  return static_cast<const OutputImageType *> (this->itk::ProcessObject::GetOutput(5));
233 }
234 template <class TInputImage, class TOutputImage>
238 {
239  if (this->GetNumberOfOutputs() < 6)
240  {
241  return 0;
242  }
243  if (this->GetTexturesStatus()[5] == false)
244  {
245  itkExceptionMacro(<< "Impossible to create SD image : texture not selected");
246  }
247 
248  return static_cast<OutputImageType *>(this->itk::ProcessObject::GetOutput(5));
249 }
250 
251 template <class TInputImage, class TOutputImage>
252 void
255 {
256  Superclass::BeforeThreadedGenerateData();
257  if (this->GetSpatialThreshold() < this->GetRatioMaxConsiderationNumber())
258  {
259  itkExceptionMacro(<< "Spatial Threshold (" << this->GetSpatialThreshold()
260  << ") is lower than Ration Max Consideration Number ("
261  << this->GetRatioMaxConsiderationNumber() << ") what is not allowed.");
262  }
263  for (unsigned int i = 0; i < this->GetNumberOfThreads(); ++i)
264  {
265  m_FunctorList.push_back(m_Functor);
266  }
267  this->InitFeatureStatus(true);
268 }
269 
270 template <class TInputImage, class TOutputImage>
271 void
274 {
275  // call the superclass' implementation of this method
276  Superclass::GenerateInputRequestedRegion();
277 
278  // get pointers to the input and output
279  typename Superclass::InputImagePointer inputPtr = const_cast<TInputImage *>(this->GetInput());
280  typename Superclass::OutputImagePointer outputPtr1 = this->GetOutput(0); //this->GetLengthOutput();
281  typename Superclass::OutputImagePointer outputPtr2 = this->GetOutput(1); //this->GetWidthOutput();
282  typename Superclass::OutputImagePointer outputPtr3 = this->GetOutput(2); //this->GetPSIOutput();
283  typename Superclass::OutputImagePointer outputPtr4 = this->GetOutput(3); //this->GetWMeanOutput();
284  typename Superclass::OutputImagePointer outputPtr5 = this->GetOutput(4); //this->GetRatioOutput();
285  typename Superclass::OutputImagePointer outputPtr6 = this->GetOutput(5); //this->GetSDOutput();
286 
287  if (!inputPtr || !outputPtr1 || !outputPtr2 || !outputPtr3 || !outputPtr4 || !outputPtr5 || !outputPtr6)
288  {
289  return;
290  }
291  // get a copy of the input requested region (should equal the output
292  // requested region)
293  typename TInputImage::RegionType inputRequestedRegion;
294  inputRequestedRegion = inputPtr->GetRequestedRegion();
295 
296  // pad the input requested region by the operator radius
297  InputImageSizeType rad;
298  rad[0] = m_Radius;
299  rad[1] = m_Radius;
300  inputRequestedRegion.PadByRadius(rad);
301 
302  // crop the input requested region at the input's largest possible region
303  if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
304  {
305  inputPtr->SetRequestedRegion(inputRequestedRegion);
306  return;
307  }
308  else
309  {
310  // Couldn't crop the region (requested region is outside the largest
311  // possible region). Throw an exception.
312 
313  // store what we tried to request (prior to trying to crop)
314  inputPtr->SetRequestedRegion(inputRequestedRegion);
315 
316  // build an exception
317  itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
318  std::ostringstream msg;
319  msg << this->GetNameOfClass()
320  << "::GenerateInputRequestedRegion()";
321  e.SetLocation(msg.str().c_str());
322  e.SetDescription("Requested region is (at least partially) outside the largest possible region.");
323  e.SetDataObject(inputPtr);
324  throw e;
325  }
326 }
327 
328 template <class TInputImage, class TOutputImage>
329 void
332 {
333  Superclass::GenerateOutputInformation();
334  //this->GetOutput()->SetNumberOfComponentsPerPixel(6);
335 }
336 
337 template <class TInputImage, class TOutputImage>
338 void
340 ::ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId)
341 {
343 
344 // We use dynamic_cast since inputs are stored as DataObjects. The
345 // ImageToImageFilter::GetInput(int) always returns a pointer to a
346 // TInputImage so it cannot be used for the second input.
347  InputImagePointerType inputPtr = dynamic_cast<const TInputImage*>(ProcessObjectType::GetInput(0));
348  OutputImagePointerType outputPtr1 = this->GetOutput(0);
349  OutputImagePointerType outputPtr2 = this->GetOutput(1);
350  OutputImagePointerType outputPtr3 = this->GetOutput(2);
351  OutputImagePointerType outputPtr4 = this->GetOutput(3);
352  OutputImagePointerType outputPtr5 = this->GetOutput(4);
353  OutputImagePointerType outputPtr6 = this->GetOutput(5);
354 
355  RadiusType r;
356  r.Fill(this->GetRadius());
357  NeighborhoodIteratorType neighInputIt;
358 
359  itk::ImageRegionIterator<TOutputImage> outputIt1, outputIt2, outputIt3, outputIt4, outputIt5, outputIt6;
360  FunctorOutputType outputFunctor;
361 
362  // Find the data-set boundary "faces"
365  faceList = bC(inputPtr, outputRegionForThread, r);
366 
368 
369  // support progress methods/callbacks
370  itk::ProgressReporter progress(this, threadId, outputRegionForThread.GetNumberOfPixels());
371 
372  // Process each of the boundary faces. These are N-d regions which border
373  // the edge of the buffer.
374 
375  std::vector<bool> textStatus = this->GetTexturesStatus();
376  for (fit = faceList.begin(); fit != faceList.end(); ++fit)
377  {
378  neighInputIt = itk::ConstNeighborhoodIterator<TInputImage>(r, inputPtr, *fit);
379 
380  outputIt1 = itk::ImageRegionIterator<TOutputImage>(outputPtr1, *fit);
381  outputIt2 = itk::ImageRegionIterator<TOutputImage>(outputPtr2, *fit);
382  outputIt3 = itk::ImageRegionIterator<TOutputImage>(outputPtr3, *fit);
383  outputIt4 = itk::ImageRegionIterator<TOutputImage>(outputPtr4, *fit);
384  outputIt5 = itk::ImageRegionIterator<TOutputImage>(outputPtr5, *fit);
385  outputIt6 = itk::ImageRegionIterator<TOutputImage>(outputPtr6, *fit);
386 
387  std::vector<itk::ImageRegionIterator<TOutputImage> *> outItList;
388  outItList.push_back(&outputIt1);
389  outItList.push_back(&outputIt2);
390  outItList.push_back(&outputIt3);
391  outItList.push_back(&outputIt4);
392  outItList.push_back(&outputIt5);
393  outItList.push_back(&outputIt6);
394 
395  neighInputIt.OverrideBoundaryCondition(&nbc);
396  neighInputIt.GoToBegin();
397 
398  for (unsigned int i = 0; i < outItList.size(); ++i)
399  {
400  (*outItList[i]).GoToBegin();
401  }
402 
403  while (!outputIt1.IsAtEnd())
404  {
405 
406  outputFunctor = m_FunctorList[threadId](neighInputIt);
407  for (unsigned int i = 0; i < outItList.size(); ++i)
408  {
409  if (textStatus[i] == true) (*outItList[i]).Set(outputFunctor[i]);
410  }
411 
412  ++neighInputIt;
413  for (unsigned int i = 0; i < outItList.size(); ++i)
414  {
415  ++(*outItList[i]);
416  }
417 
418  progress.CompletedPixel();
419  }
420  }
421 }
422 
423 template <class TInputImage, class TOutputImage>
424 void
427 {
428  for (FeatureType id = LENGTH; id <= SD;
429  id = static_cast<FeatureType>(id + 1))
430  {
431  this->SetFeatureStatus(static_cast<FeatureType>(id), status);
432  }
433 }
434 
438 template <class TInputImage, class TOutputImage>
439 void
441 ::PrintSelf(std::ostream& os, itk::Indent indent) const
442 {
443  Superclass::PrintSelf(os, indent);
444 
445  //os << indent << "Spatial Threshold : " << this->GetSpatialThreshold() << std::endl;
446  //os << indent << "Spectral Threshold : " << this->GetSpectralThreshold() << std::endl;
447  //os << indent << "Ratio Max Consideration Number: " << this->GetRatioMaxConsiderationNumber() << std::endl;
448  //os << indent << "Alpha : " << this->GetAlpha() << std::endl;
449  //os << indent << "Number Of Directions : " << this->GetNumberOfDirections() << std::endl;
450 
451 }
452 
453 } // end namespace otb
454 
455 #endif
virtual bool IsAtEnd() const
FunctorType::OutputType FunctorOutputType
const OutputImageType * GetWMeanOutput() const
void SetDataObject(DataObject *dobj)
virtual void SetDescription(const std::string &s)
virtual void SetLocation(const std::string &s)
virtual void OverrideBoundaryCondition(const ImageBoundaryConditionPointerType i)
void PrintSelf(std::ostream &os, itk::Indent indent) const
OutputImageType::Pointer OutputImagePointerType
const OutputImageType * GetSDOutput() const
virtual void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, itk::ThreadIdType threadId)
const OutputImageType * GetRatioOutput() const
InputImageType::ConstPointer InputImagePointerType
NeighborhoodIteratorType::RadiusType RadiusType
const OutputImageType * GetWidthOutput() const
OutputImageType::RegionType OutputImageRegionType
const OutputImageType * GetPSIOutput() const
TOutputImage OutputImageType
InputImageType::SizeType InputImageSizeType
const OutputImageType * GetLengthOutput() const
unsigned int ThreadIdType
DataObject * GetOutput(const DataObjectIdentifierType &key)