21 #ifndef otbSFSTexturesImageFilter_hxx
22 #define otbSFSTexturesImageFilter_hxx
26 #include "itkProgressReporter.h"
27 #include "itkImageRegionIterator.h"
28 #include "itkNeighborhoodAlgorithm.h"
34 template <
class TInputImage,
class TOutputImage>
37 this->DynamicMultiThreadingOff();
38 this->SetNumberOfRequiredInputs(1);
39 this->SetNumberOfRequiredInputs(1);
40 this->SetNumberOfRequiredOutputs(6);
41 this->SetNumberOfRequiredOutputs(1);
43 this->SetNthOutput(0, OutputImageType::New());
44 this->SetNthOutput(1, OutputImageType::New());
45 this->SetNthOutput(2, OutputImageType::New());
46 this->SetNthOutput(3, OutputImageType::New());
47 this->SetNthOutput(4, OutputImageType::New());
48 this->SetNthOutput(5, OutputImageType::New());
50 m_Radius = this->GetSpatialThreshold();
51 m_FunctorList.clear();
59 template <
class TInputImage,
class TOutputImage>
62 if (this->GetNumberOfOutputs() < 1)
66 if (this->GetTexturesStatus()[0] ==
false)
68 itkExceptionMacro(<<
"Impossible to create length image : texture not selected");
70 return static_cast<const OutputImageType*
>(this->itk::ProcessObject::GetOutput(0));
72 template <
class TInputImage,
class TOutputImage>
75 if (this->GetNumberOfOutputs() < 1)
79 if (this->GetTexturesStatus()[0] ==
false)
81 itkExceptionMacro(<<
"Impossible to create length image : texture not selected");
83 return static_cast<OutputImageType*
>(this->itk::ProcessObject::GetOutput(0));
88 template <
class TInputImage,
class TOutputImage>
91 if (this->GetNumberOfOutputs() < 2)
95 if (this->GetTexturesStatus()[1] ==
false)
97 itkExceptionMacro(<<
"Impossible to create width image : texture not selected");
99 return static_cast<const OutputImageType*
>(this->itk::ProcessObject::GetOutput(1));
101 template <
class TInputImage,
class TOutputImage>
104 if (this->GetNumberOfOutputs() < 2)
108 if (this->GetTexturesStatus()[1] ==
false)
110 itkExceptionMacro(<<
"Impossible to create width image : texture not selected");
112 return static_cast<OutputImageType*
>(this->itk::ProcessObject::GetOutput(1));
116 template <
class TInputImage,
class TOutputImage>
119 if (this->GetNumberOfOutputs() < 3)
123 if (this->GetTexturesStatus()[2] ==
false)
125 itkExceptionMacro(<<
"Impossible to create PSI image : texture not selected");
127 return static_cast<const OutputImageType*
>(this->itk::ProcessObject::GetOutput(2));
129 template <
class TInputImage,
class TOutputImage>
132 if (this->GetNumberOfOutputs() < 3)
136 if (this->GetTexturesStatus()[2] ==
false)
138 itkExceptionMacro(<<
"Impossible to create PSI image : texture not selected");
141 return static_cast<OutputImageType*
>(this->itk::ProcessObject::GetOutput(2));
145 template <
class TInputImage,
class TOutputImage>
148 if (this->GetNumberOfOutputs() < 4)
152 if (this->GetTexturesStatus()[3] ==
false)
154 itkExceptionMacro(<<
"Impossible to create W-Mean image : texture not selected");
156 return static_cast<const OutputImageType*
>(this->itk::ProcessObject::GetOutput(3));
158 template <
class TInputImage,
class TOutputImage>
161 if (this->GetNumberOfOutputs() < 4)
165 if (this->GetTexturesStatus()[3] ==
false)
167 itkExceptionMacro(<<
"Impossible to create W-Mean image : texture not selected");
169 return static_cast<OutputImageType*
>(this->itk::ProcessObject::GetOutput(3));
173 template <
class TInputImage,
class TOutputImage>
176 if (this->GetNumberOfOutputs() < 5)
180 if (this->GetTexturesStatus()[4] ==
false)
182 itkExceptionMacro(<<
"Impossible to create Ratio image : texture not selected");
184 return static_cast<const OutputImageType*
>(this->itk::ProcessObject::GetOutput(4));
186 template <
class TInputImage,
class TOutputImage>
189 if (this->GetNumberOfOutputs() < 5)
193 if (this->GetTexturesStatus()[4] ==
false)
195 itkExceptionMacro(<<
"Impossible to create Ratio image : texture not selected");
197 return static_cast<OutputImageType*
>(this->itk::ProcessObject::GetOutput(4));
201 template <
class TInputImage,
class TOutputImage>
204 if (this->GetNumberOfOutputs() < 6)
208 if (this->GetTexturesStatus()[5] ==
false)
210 itkExceptionMacro(<<
"Impossible to create SD image : texture not selected");
212 return static_cast<const OutputImageType*
>(this->itk::ProcessObject::GetOutput(5));
214 template <
class TInputImage,
class TOutputImage>
217 if (this->GetNumberOfOutputs() < 6)
221 if (this->GetTexturesStatus()[5] ==
false)
223 itkExceptionMacro(<<
"Impossible to create SD image : texture not selected");
226 return static_cast<OutputImageType*
>(this->itk::ProcessObject::GetOutput(5));
229 template <
class TInputImage,
class TOutputImage>
232 Superclass::BeforeThreadedGenerateData();
233 if (this->GetSpatialThreshold() < this->GetRatioMaxConsiderationNumber())
235 itkExceptionMacro(<<
"Spatial Threshold (" << this->GetSpatialThreshold() <<
") is lower than Ration Max Consideration Number ("
236 << this->GetRatioMaxConsiderationNumber() <<
") what is not allowed.");
238 for (
unsigned int i = 0; i < this->GetNumberOfWorkUnits(); ++i)
240 m_FunctorList.push_back(m_Functor);
242 this->InitFeatureStatus(
true);
245 template <
class TInputImage,
class TOutputImage>
249 Superclass::GenerateInputRequestedRegion();
252 typename Superclass::InputImagePointer inputPtr =
const_cast<TInputImage*
>(this->GetInput());
253 typename Superclass::OutputImagePointer outputPtr1 = this->GetOutput(0);
254 typename Superclass::OutputImagePointer outputPtr2 = this->GetOutput(1);
255 typename Superclass::OutputImagePointer outputPtr3 = this->GetOutput(2);
256 typename Superclass::OutputImagePointer outputPtr4 = this->GetOutput(3);
257 typename Superclass::OutputImagePointer outputPtr5 = this->GetOutput(4);
258 typename Superclass::OutputImagePointer outputPtr6 = this->GetOutput(5);
260 if (!inputPtr || !outputPtr1 || !outputPtr2 || !outputPtr3 || !outputPtr4 || !outputPtr5 || !outputPtr6)
266 typename TInputImage::RegionType inputRequestedRegion;
267 inputRequestedRegion = inputPtr->GetRequestedRegion();
273 inputRequestedRegion.PadByRadius(rad);
276 if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
278 inputPtr->SetRequestedRegion(inputRequestedRegion);
287 inputPtr->SetRequestedRegion(inputRequestedRegion);
290 itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
291 std::ostringstream msg;
292 msg << this->GetNameOfClass() <<
"::GenerateInputRequestedRegion()";
293 e.SetLocation(msg.str());
294 e.SetDescription(
"Requested region is (at least partially) outside the largest possible region.");
295 e.SetDataObject(inputPtr);
300 template <
class TInputImage,
class TOutputImage>
303 Superclass::GenerateOutputInformation();
307 template <
class TInputImage,
class TOutputImage>
310 itk::ZeroFluxNeumannBoundaryCondition<TInputImage> nbc;
324 r.Fill(this->GetRadius());
327 itk::ImageRegionIterator<TOutputImage> outputIt1, outputIt2, outputIt3, outputIt4, outputIt5, outputIt6;
331 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage>::FaceListType faceList;
332 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage> bC;
333 faceList = bC(inputPtr, outputRegionForThread, r);
335 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage>::FaceListType::iterator fit;
338 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels());
343 std::vector<bool> textStatus = this->GetTexturesStatus();
344 for (fit = faceList.begin(); fit != faceList.end(); ++fit)
346 neighInputIt = itk::ConstNeighborhoodIterator<TInputImage>(r, inputPtr, *fit);
348 outputIt1 = itk::ImageRegionIterator<TOutputImage>(outputPtr1, *fit);
349 outputIt2 = itk::ImageRegionIterator<TOutputImage>(outputPtr2, *fit);
350 outputIt3 = itk::ImageRegionIterator<TOutputImage>(outputPtr3, *fit);
351 outputIt4 = itk::ImageRegionIterator<TOutputImage>(outputPtr4, *fit);
352 outputIt5 = itk::ImageRegionIterator<TOutputImage>(outputPtr5, *fit);
353 outputIt6 = itk::ImageRegionIterator<TOutputImage>(outputPtr6, *fit);
355 std::vector<itk::ImageRegionIterator<TOutputImage>*> outItList;
356 outItList.push_back(&outputIt1);
357 outItList.push_back(&outputIt2);
358 outItList.push_back(&outputIt3);
359 outItList.push_back(&outputIt4);
360 outItList.push_back(&outputIt5);
361 outItList.push_back(&outputIt6);
363 neighInputIt.OverrideBoundaryCondition(&nbc);
364 neighInputIt.GoToBegin();
366 for (
unsigned int i = 0; i < outItList.size(); ++i)
368 (*outItList[i]).GoToBegin();
371 while (!outputIt1.IsAtEnd())
374 outputFunctor = m_FunctorList[threadId](neighInputIt);
375 for (
unsigned int i = 0; i < outItList.size(); ++i)
377 if (textStatus[i] ==
true)
378 (*outItList[i]).Set(outputFunctor[i]);
382 for (
unsigned int i = 0; i < outItList.size(); ++i)
387 progress.CompletedPixel();
392 template <
class TInputImage,
class TOutputImage>
395 for (
FeatureType id = LENGTH; id <= SD; id = static_cast<FeatureType>(
id + 1))
397 this->SetFeatureStatus(
static_cast<FeatureType>(
id), status);
404 template <
class TInputImage,
class TOutputImage>
407 Superclass::PrintSelf(os, indent);
void ThreadedGenerateData(const OutputImageRegionType &outputRegionForThread, itk::ThreadIdType threadId) override
const OutputImageType * GetLengthOutput() const
void BeforeThreadedGenerateData() override
void InitFeatureStatus(bool status)
FunctorType::OutputType FunctorOutputType
TOutputImage OutputImageType
const OutputImageType * GetWMeanOutput() const
InputImageType::SizeType InputImageSizeType
const OutputImageType * GetWidthOutput() const
NeighborhoodIteratorType::RadiusType RadiusType
OutputImageType::RegionType OutputImageRegionType
itk::ConstNeighborhoodIterator< TInputImage > NeighborhoodIteratorType
InputImageType::ConstPointer InputImagePointerType
OutputImageType::Pointer OutputImagePointerType
void GenerateOutputInformation() override
const OutputImageType * GetSDOutput() const
void GenerateInputRequestedRegion(void) override
void PrintSelf(std::ostream &os, itk::Indent indent) const override
const OutputImageType * GetRatioOutput() const
const OutputImageType * GetPSIOutput() const
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.