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->SetNumberOfRequiredInputs(1);
38 this->SetNumberOfRequiredInputs(1);
39 this->SetNumberOfRequiredOutputs(6);
40 this->SetNumberOfRequiredOutputs(1);
42 this->SetNthOutput(0, OutputImageType::New());
43 this->SetNthOutput(1, OutputImageType::New());
44 this->SetNthOutput(2, OutputImageType::New());
45 this->SetNthOutput(3, OutputImageType::New());
46 this->SetNthOutput(4, OutputImageType::New());
47 this->SetNthOutput(5, OutputImageType::New());
49 m_Radius = this->GetSpatialThreshold();
50 m_FunctorList.clear();
58 template <
class TInputImage,
class TOutputImage>
61 if (this->GetNumberOfOutputs() < 1)
65 if (this->GetTexturesStatus()[0] ==
false)
67 itkExceptionMacro(<<
"Impossible to create length image : texture not selected");
69 return static_cast<const OutputImageType*
>(this->itk::ProcessObject::GetOutput(0));
71 template <
class TInputImage,
class TOutputImage>
74 if (this->GetNumberOfOutputs() < 1)
78 if (this->GetTexturesStatus()[0] ==
false)
80 itkExceptionMacro(<<
"Impossible to create length image : texture not selected");
82 return static_cast<OutputImageType*
>(this->itk::ProcessObject::GetOutput(0));
87 template <
class TInputImage,
class TOutputImage>
90 if (this->GetNumberOfOutputs() < 2)
94 if (this->GetTexturesStatus()[1] ==
false)
96 itkExceptionMacro(<<
"Impossible to create width image : texture not selected");
98 return static_cast<const OutputImageType*
>(this->itk::ProcessObject::GetOutput(1));
100 template <
class TInputImage,
class TOutputImage>
103 if (this->GetNumberOfOutputs() < 2)
107 if (this->GetTexturesStatus()[1] ==
false)
109 itkExceptionMacro(<<
"Impossible to create width image : texture not selected");
111 return static_cast<OutputImageType*
>(this->itk::ProcessObject::GetOutput(1));
115 template <
class TInputImage,
class TOutputImage>
118 if (this->GetNumberOfOutputs() < 3)
122 if (this->GetTexturesStatus()[2] ==
false)
124 itkExceptionMacro(<<
"Impossible to create PSI image : texture not selected");
126 return static_cast<const OutputImageType*
>(this->itk::ProcessObject::GetOutput(2));
128 template <
class TInputImage,
class TOutputImage>
131 if (this->GetNumberOfOutputs() < 3)
135 if (this->GetTexturesStatus()[2] ==
false)
137 itkExceptionMacro(<<
"Impossible to create PSI image : texture not selected");
140 return static_cast<OutputImageType*
>(this->itk::ProcessObject::GetOutput(2));
144 template <
class TInputImage,
class TOutputImage>
147 if (this->GetNumberOfOutputs() < 4)
151 if (this->GetTexturesStatus()[3] ==
false)
153 itkExceptionMacro(<<
"Impossible to create W-Mean image : texture not selected");
155 return static_cast<const OutputImageType*
>(this->itk::ProcessObject::GetOutput(3));
157 template <
class TInputImage,
class TOutputImage>
160 if (this->GetNumberOfOutputs() < 4)
164 if (this->GetTexturesStatus()[3] ==
false)
166 itkExceptionMacro(<<
"Impossible to create W-Mean image : texture not selected");
168 return static_cast<OutputImageType*
>(this->itk::ProcessObject::GetOutput(3));
172 template <
class TInputImage,
class TOutputImage>
175 if (this->GetNumberOfOutputs() < 5)
179 if (this->GetTexturesStatus()[4] ==
false)
181 itkExceptionMacro(<<
"Impossible to create Ratio image : texture not selected");
183 return static_cast<const OutputImageType*
>(this->itk::ProcessObject::GetOutput(4));
185 template <
class TInputImage,
class TOutputImage>
188 if (this->GetNumberOfOutputs() < 5)
192 if (this->GetTexturesStatus()[4] ==
false)
194 itkExceptionMacro(<<
"Impossible to create Ratio image : texture not selected");
196 return static_cast<OutputImageType*
>(this->itk::ProcessObject::GetOutput(4));
200 template <
class TInputImage,
class TOutputImage>
203 if (this->GetNumberOfOutputs() < 6)
207 if (this->GetTexturesStatus()[5] ==
false)
209 itkExceptionMacro(<<
"Impossible to create SD image : texture not selected");
211 return static_cast<const OutputImageType*
>(this->itk::ProcessObject::GetOutput(5));
213 template <
class TInputImage,
class TOutputImage>
216 if (this->GetNumberOfOutputs() < 6)
220 if (this->GetTexturesStatus()[5] ==
false)
222 itkExceptionMacro(<<
"Impossible to create SD image : texture not selected");
225 return static_cast<OutputImageType*
>(this->itk::ProcessObject::GetOutput(5));
228 template <
class TInputImage,
class TOutputImage>
231 Superclass::BeforeThreadedGenerateData();
232 if (this->GetSpatialThreshold() < this->GetRatioMaxConsiderationNumber())
234 itkExceptionMacro(<<
"Spatial Threshold (" << this->GetSpatialThreshold() <<
") is lower than Ration Max Consideration Number ("
235 << this->GetRatioMaxConsiderationNumber() <<
") what is not allowed.");
237 for (
unsigned int i = 0; i < this->GetNumberOfThreads(); ++i)
239 m_FunctorList.push_back(m_Functor);
241 this->InitFeatureStatus(
true);
244 template <
class TInputImage,
class TOutputImage>
248 Superclass::GenerateInputRequestedRegion();
251 typename Superclass::InputImagePointer inputPtr =
const_cast<TInputImage*
>(this->GetInput());
252 typename Superclass::OutputImagePointer outputPtr1 = this->GetOutput(0);
253 typename Superclass::OutputImagePointer outputPtr2 = this->GetOutput(1);
254 typename Superclass::OutputImagePointer outputPtr3 = this->GetOutput(2);
255 typename Superclass::OutputImagePointer outputPtr4 = this->GetOutput(3);
256 typename Superclass::OutputImagePointer outputPtr5 = this->GetOutput(4);
257 typename Superclass::OutputImagePointer outputPtr6 = this->GetOutput(5);
259 if (!inputPtr || !outputPtr1 || !outputPtr2 || !outputPtr3 || !outputPtr4 || !outputPtr5 || !outputPtr6)
265 typename TInputImage::RegionType inputRequestedRegion;
266 inputRequestedRegion = inputPtr->GetRequestedRegion();
272 inputRequestedRegion.PadByRadius(rad);
275 if (inputRequestedRegion.Crop(inputPtr->GetLargestPossibleRegion()))
277 inputPtr->SetRequestedRegion(inputRequestedRegion);
286 inputPtr->SetRequestedRegion(inputRequestedRegion);
289 itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
290 std::ostringstream msg;
291 msg << this->GetNameOfClass() <<
"::GenerateInputRequestedRegion()";
292 e.SetLocation(msg.str());
293 e.SetDescription(
"Requested region is (at least partially) outside the largest possible region.");
294 e.SetDataObject(inputPtr);
299 template <
class TInputImage,
class TOutputImage>
302 Superclass::GenerateOutputInformation();
306 template <
class TInputImage,
class TOutputImage>
309 itk::ZeroFluxNeumannBoundaryCondition<TInputImage> nbc;
323 r.Fill(this->GetRadius());
326 itk::ImageRegionIterator<TOutputImage> outputIt1, outputIt2, outputIt3, outputIt4, outputIt5, outputIt6;
330 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage>::FaceListType faceList;
331 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage> bC;
332 faceList = bC(inputPtr, outputRegionForThread, r);
334 typename itk::NeighborhoodAlgorithm::ImageBoundaryFacesCalculator<TInputImage>::FaceListType::iterator fit;
337 itk::ProgressReporter progress(
this, threadId, outputRegionForThread.GetNumberOfPixels());
342 std::vector<bool> textStatus = this->GetTexturesStatus();
343 for (fit = faceList.begin(); fit != faceList.end(); ++fit)
345 neighInputIt = itk::ConstNeighborhoodIterator<TInputImage>(r, inputPtr, *fit);
347 outputIt1 = itk::ImageRegionIterator<TOutputImage>(outputPtr1, *fit);
348 outputIt2 = itk::ImageRegionIterator<TOutputImage>(outputPtr2, *fit);
349 outputIt3 = itk::ImageRegionIterator<TOutputImage>(outputPtr3, *fit);
350 outputIt4 = itk::ImageRegionIterator<TOutputImage>(outputPtr4, *fit);
351 outputIt5 = itk::ImageRegionIterator<TOutputImage>(outputPtr5, *fit);
352 outputIt6 = itk::ImageRegionIterator<TOutputImage>(outputPtr6, *fit);
354 std::vector<itk::ImageRegionIterator<TOutputImage>*> outItList;
355 outItList.push_back(&outputIt1);
356 outItList.push_back(&outputIt2);
357 outItList.push_back(&outputIt3);
358 outItList.push_back(&outputIt4);
359 outItList.push_back(&outputIt5);
360 outItList.push_back(&outputIt6);
362 neighInputIt.OverrideBoundaryCondition(&nbc);
363 neighInputIt.GoToBegin();
365 for (
unsigned int i = 0; i < outItList.size(); ++i)
367 (*outItList[i]).GoToBegin();
370 while (!outputIt1.IsAtEnd())
373 outputFunctor = m_FunctorList[threadId](neighInputIt);
374 for (
unsigned int i = 0; i < outItList.size(); ++i)
376 if (textStatus[i] ==
true)
377 (*outItList[i]).Set(outputFunctor[i]);
381 for (
unsigned int i = 0; i < outItList.size(); ++i)
386 progress.CompletedPixel();
391 template <
class TInputImage,
class TOutputImage>
394 for (
FeatureType id = LENGTH; id <= SD; id = static_cast<FeatureType>(
id + 1))
396 this->SetFeatureStatus(
static_cast<FeatureType>(
id), status);
403 template <
class TInputImage,
class TOutputImage>
406 Superclass::PrintSelf(os, indent);