21 #ifndef otbFunctorImageFilter_hxx
22 #define otbFunctorImageFilter_hxx
25 #include "itkProgressReporter.h"
26 #include "itkConstNeighborhoodIterator.h"
27 #include "itkImageRegionConstIterator.h"
28 #include "itkImageScanlineIterator.h"
33 namespace functor_filter_details
41 assert(img &&
"Input image is a nullptr");
43 auto currentRegion = region;
47 currentRegion.PadByRadius(radius);
50 T* nonConstImg =
const_cast<T*
>(img);
52 if (currentRegion.GetNumberOfPixels()==0 || currentRegion.Crop(img->GetLargestPossibleRegion()))
54 nonConstImg->SetRequestedRegion(currentRegion);
59 nonConstImg->SetRequestedRegion(currentRegion);
62 itk::InvalidRequestedRegionError e(__FILE__, __LINE__);
63 e.SetLocation(
"::SetInputRequestedRegion<>()");
64 e.SetDescription(
"Requested region is (at least partially) outside the largest possible region.");
65 e.SetDataObject(nonConstImg);
71 template <
typename HasNeighborhood,
class Tuple,
size_t... Is>
74 return std::make_tuple(
SetInputRequestedRegion(std::get<Is>(t), region, radius,
typename std::tuple_element<Is, HasNeighborhood>::type::value_type())...);
78 template <
typename HasNeighborhood,
typename... T>
81 return SetInputRequestedRegionsImpl<HasNeighborhood>(t, region, std::make_index_sequence<
sizeof...(T)>{}, radius);
85 template <
class Tuple,
size_t... Is>
88 return std::array<size_t,
sizeof...(Is)>{{std::get<Is>(t)->GetNumberOfComponentsPerPixel()...}};
92 template <
typename... T>
107 static auto Make(
const T* img,
const itk::ImageRegion<2>& region,
const itk::Size<2>&)
109 itk::ImageRegionConstIterator<T> it(img, region);
118 static auto Make(
const T* img,
const itk::ImageRegion<2>& region,
const itk::Size<2>& radius)
120 itk::ConstNeighborhoodIterator<T> it(radius, img, region);
126 template <
class TNeigh,
class Tuple,
size_t... Is>
127 auto MakeIteratorsImpl(
const Tuple& t,
const itk::ImageRegion<2>& region,
const itk::Size<2>& radius, std::index_sequence<Is...>, TNeigh)
129 return std::make_tuple(
MakeIterator<
typename std::tuple_element<Is, TNeigh>::type>::Make(std::get<Is>(t), region, radius)...);
133 template <
class TNeigh,
typename... T>
134 auto MakeIterators(std::tuple<T...>&& t,
const itk::ImageRegion<2>& region,
const itk::Size<2>& radius, TNeigh n)
136 return MakeIteratorsImpl(t, region, radius, std::make_index_sequence<
sizeof...(T)>{}, n);
140 template <
typename T>
146 template <
typename T>
149 static decltype(
auto) Get(const
itk::ImageRegionConstIterator<T>& t)
155 template <
typename T>
158 static decltype(
auto) Get(const
itk::ConstNeighborhoodIterator<T>& t)
166 template <
class Oper>
171 template <
class Out,
class... In>
174 template <
class Oper>
175 static void Compute(Oper& oper, Out& out,
const In&... in)
181 template <
class C,
class Out,
class... In>
184 template <
class Oper>
185 static void Compute(Oper& oper, Out& out,
const In&... in)
191 template <
class C,
class Out,
class... In>
194 template <
class Oper>
195 static void Compute(Oper& oper, Out& out,
const In&... in)
201 template <
class Out,
class... In>
204 template <
class Oper>
205 static void Compute(Oper& oper, Out& out,
const In&... in)
211 template <
class C,
class Out,
class... In>
214 template <
class Oper>
215 static void Compute(Oper& oper, Out& out,
const In&... in)
221 template <
class C,
class Out,
class... In>
224 template <
class Oper>
225 static void Compute(Oper& oper, Out& out,
const In&... in)
233 template <
class Tuple,
class Out,
class Oper,
size_t... Is>
240 template <
class Out,
class Oper,
typename... Args>
243 CallOperatorImpl(t, out, oper, std::make_index_sequence<
sizeof...(Args)>{});
248 template <
class Tuple,
size_t... Is>
251 return std::make_tuple(++(std::get<Is>(t))...);
254 template <
typename... Args>
262 template <
class F,
class O,
size_t N>
267 template <
class F,
class T,
size_t N>
277 template <
class F,
class T,
size_t N>
288 template <
class TFunction,
class TNameMap>
292 typename Superclass::OutputImagePointer outputPtr = this->GetOutput();
293 auto requestedRegion = outputPtr->GetRequestedRegion();
298 functor_filter_details::SetInputRequestedRegions<InputHasNeighborhood>(this->GetInputs(), requestedRegion, m_Radius);
301 template <
class TFunction,
class TNameMap>
305 Superclass::GenerateOutputInformation();
308 auto inputs = this->GetInputs();
320 template <
class TFunction,
class TNameMap>
323 const auto& regionSize = outputRegionForThread.GetSize();
325 if (regionSize[0] == 0)
329 const auto numberOfLinesToProcess = outputRegionForThread.GetNumberOfPixels() / regionSize[0];
330 itk::ProgressReporter p(
this, threadId, numberOfLinesToProcess);
333 itk::ImageScanlineIterator<OutputImageType> outIt(this->GetOutput(), outputRegionForThread);
339 typename OutputImageType::PixelType outputValueHolder;
340 itk::NumericTraits<typename OutputImageType::PixelType>::SetLength(outputValueHolder, this->GetOutput()->GetNumberOfComponentsPerPixel());
342 while (!outIt.IsAtEnd())
350 outIt.Set(outputValueHolder);