OTB  10.0.0
Orfeo Toolbox
otbFunctorImageFilter.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2024 Centre National d'Etudes Spatiales (CNES)
3  *
4  * This file is part of Orfeo Toolbox
5  *
6  * https://www.orfeo-toolbox.org/
7  *
8  * Licensed under the Apache License, Version 2.0 (the "License");
9  * you may not use this file except in compliance with the License.
10  * You may obtain a copy of the License at
11  *
12  * http://www.apache.org/licenses/LICENSE-2.0
13  *
14  * Unless required by applicable law or agreed to in writing, software
15  * distributed under the License is distributed on an "AS IS" BASIS,
16  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17  * See the License for the specific language governing permissions and
18  * limitations under the License.
19  */
20 
21 #ifndef otbFunctorImageFilter_h
22 #define otbFunctorImageFilter_h
23 
25 #include "otbImage.h"
26 #include "otbVectorImage.h"
27 #include "itkRGBPixel.h"
28 #include "itkRGBAPixel.h"
29 #include "itkFixedArray.h"
30 #include "itkDefaultConvertPixelTraits.h"
31 #include <type_traits>
32 #include "itkConstNeighborhoodIterator.h"
33 #include "otbImage.h"
34 
35 namespace otb
36 {
45 template <class T>
46 struct IsNeighborhood : std::false_type
47 {
48 };
49 
51 template <class T>
52 struct IsNeighborhood<const itk::ConstNeighborhoodIterator<Image<T>>&> : std::true_type
53 {
54 };
55 
57 template <class T>
58 struct IsNeighborhood<const itk::ConstNeighborhoodIterator<VectorImage<T>>&> : std::true_type
59 {
60 };
61 
68 template <class T>
69 struct IsSuitableType : std::is_scalar<T>::type
70 {
71 };
72 
74 template <class T>
75 struct IsSuitableType<std::complex<T>> : IsSuitableType<T>::type
76 {
77 };
78 
80 template <class T>
81 struct IsSuitableType<itk::VariableLengthVector<T>> : IsSuitableType<T>::type
82 {
83 };
84 
86 template <class T, unsigned int N>
87 struct IsSuitableType<itk::FixedArray<T, N>> : IsSuitableType<T>::type
88 {
89 };
90 
92 template <class T>
93 struct IsSuitableType<itk::RGBPixel<T>> : IsSuitableType<T>::type
94 {
95 };
96 
98 template <class T>
99 struct IsSuitableType<itk::RGBAPixel<T>> : IsSuitableType<T>::type
100 {
101 };
102 
111 template <class T>
113 {
114  static_assert(IsSuitableType<T>::value, "T can not be used as a template parameter for Image or VectorImage classes.");
115  using PixelType = T;
116 };
117 
119 template <class T>
120 struct PixelTypeDeduction<itk::ConstNeighborhoodIterator<Image<T>>>
121 {
122  static_assert(IsSuitableType<T>::value, "T can not be used as a template parameter for Image or VectorImage classes.");
123  using PixelType = T;
124 };
125 
127 template <class T>
128 struct PixelTypeDeduction<itk::ConstNeighborhoodIterator<VectorImage<T>>>
129 {
130  static_assert(IsSuitableType<T>::value, "T can not be used as a template parameter for Image or VectorImage classes.");
131  using PixelType = itk::VariableLengthVector<T>;
132 };
133 
142 template <class T>
144 {
146 };
147 
149 template <class T>
150 struct ImageTypeDeduction<itk::VariableLengthVector<T>>
151 {
153 };
154 
155 // Helper to remove const, volatite and Ref qualifier (until c++20
157 template <typename T>
158 using RemoveCVRef = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
159 
168 template <typename T>
170 {
171  static_assert(std::is_class<T>::value || std::is_function<T>::value, "T is not a class or function");
172  using Type = decltype(&T::operator());
173 };
175 
188 template <typename T, typename TNameMap>
189 struct FunctorFilterSuperclassHelper : public FunctorFilterSuperclassHelper<typename RetrieveOperator<T>::Type, TNameMap>
190 {
191 };
192 
193 namespace functor_filter_details
194 {
195 template <typename R, typename TNameMap, typename... T>
197 {
198  // OutputImageType is derived from return type R
200  // InputImageType is derived using pixel type deduction and image
201  // type deduction
202  template <typename V>
204 
205  // Filter type is either VariadicInputsImageFilter or
206  // VariadicNamedInputsImageFilter depending on if there is a
207  // TNameMap or not
208  using FilterType = typename std::conditional<std::is_void<TNameMap>::value, VariadicInputsImageFilter<OutputImageType, InputImageType<T>...>,
210 
211  // InputHasNeighborhood is derived from IsNeighborhood
212  using InputHasNeighborhood = std::tuple<typename IsNeighborhood<T>::type...>;
213 };
214 } // End namespace functor_filter_details
215 
217 template <typename R, typename... T, typename TNameMap>
218 struct FunctorFilterSuperclassHelper<R (*)(T...), TNameMap>
219 {
223 };
224 
226 template <typename C, typename R, typename... T, typename TNameMap>
227 struct FunctorFilterSuperclassHelper<R (C::*)(T...) const, TNameMap>
228 {
232 };
233 
235 template <typename C, typename R, typename... T, typename TNameMap>
236 struct FunctorFilterSuperclassHelper<R (C::*)(T...), TNameMap>
237 {
241 };
242 
244 template <typename R, typename... T, typename TNameMap>
245 struct FunctorFilterSuperclassHelper<void (*)(R&, T...), TNameMap>
246 {
250 };
251 
253 template <typename C, typename R, typename... T, typename TNameMap>
254 struct FunctorFilterSuperclassHelper<void (C::*)(R&, T...) const, TNameMap>
255 {
259 };
260 
262 template <typename C, typename R, typename... T, typename TNameMap>
263 struct FunctorFilterSuperclassHelper<void (C::*)(R&, T...), TNameMap>
264 {
268 };
269 
270 
297 template <typename Functor, typename TNameMap = void>
298 auto NewFunctorFilter(Functor f, itk::Size<2> radius = {{0, 0}});
299 
300 
321 template <class TFunction, class TNameMap = void>
322 class ITK_EXPORT FunctorImageFilter : public FunctorFilterSuperclassHelper<TFunction, TNameMap>::FilterType
323 {
324 
325 public:
326  // Standard typedefs
328  using FunctorType = TFunction;
329  using Pointer = itk::SmartPointer<Self>;
330  using ConstPointer = itk::SmartPointer<const Self>;
331 
332  // Superclass through the helper struct
334  using Superclass = typename SuperclassHelper::FilterType;
335  using OutputImageType = typename Superclass::OutputImageType;
336  using OutputImageRegionType = typename OutputImageType::RegionType;
337 
338  // A tuple of bool of the same size as the number of arguments in
339  // the functor
340  using InputHasNeighborhood = typename SuperclassHelper::InputHasNeighborhood;
341  using InputTypesTupleType = typename Superclass::InputTypesTupleType;
342  template <size_t I>
343  using InputImageType = typename Superclass::template InputImageType<I>;
344  using Superclass::NumberOfInputs;
345 
348 
350  template <typename F = TFunction>
351  static std::enable_if_t<std::is_default_constructible<F>::value, Pointer> New()
352  {
353  // Explicit default construct
354  FunctorType f;
355 
356  // Create a filter out of it
357  Pointer p = new Self(f, {{0, 0}});
358  p->UnRegister();
359  return p;
360  }
361 
364  template <typename F = TFunction>
365  static std::enable_if_t<!std::is_default_constructible<F>::value, Pointer> New()
366  {
367  static_assert(std::is_default_constructible<F>::value,
368  "Cannot call New() "
369  "function as the functor used for the filter creation is not default "
370  "constructible");
371 
372  return nullptr;
373  }
374 
383  {
384  this->Modified();
385  return m_Functor;
386  }
388 
394  const FunctorType& GetFunctor() const
395  {
396  return m_Functor;
397  }
398 
399 protected:
401  FunctorImageFilter(const FunctorType& f, itk::Size<2> radius) : m_Functor(f), m_Radius(radius){this->DynamicMultiThreadingOn();};
402  FunctorImageFilter(const Self&) = delete;
403  void operator=(const Self&) = delete;
404  ~FunctorImageFilter() = default;
405 
406 private:
408  friend auto NewFunctorFilter<TFunction, TNameMap>(TFunction f, itk::Size<2> radius);
409 
411  void DynamicThreadedGenerateData(const OutputImageRegionType& outputRegionForThread) override;
412 
416  void GenerateInputRequestedRegion(void) override;
417 
421  void GenerateOutputInformation() override;
422 
423 
424  // The functor member
426 
427  // Radius if needed
428  itk::Size<2> m_Radius;
429 };
430 
431 // Actual implementation of NewFunctorFilter free function
432 template <typename Functor, typename TNameMap>
433 auto NewFunctorFilter(Functor f, itk::Size<2> radius)
434 {
435  using FilterType = FunctorImageFilter<Functor, TNameMap>;
436  using PointerType = typename FilterType::Pointer;
437 
438  PointerType p = new FilterType(f, radius);
439  p->UnRegister();
440  return p;
441 }
442 
454 template <typename F>
456 {
457 public:
458  constexpr NumberOfOutputBandsDecorator(F t, unsigned int nbComp) : F(t), m_NumberOfOutputBands(nbComp)
459  {
460  }
461 
462  constexpr size_t OutputSize(...) const
463  {
464  return m_NumberOfOutputBands;
465  }
466 
467 private:
468  unsigned int m_NumberOfOutputBands;
469 };
470 
491 template <typename Functor, typename TNameMap = void>
492 auto NewFunctorFilter(Functor f, unsigned int numberOfOutputBands, itk::Size<2> radius = {{0, 0}})
493 {
494  using FunctorType = NumberOfOutputBandsDecorator<Functor>;
495  FunctorType decoratedF(f, numberOfOutputBands);
496  return NewFunctorFilter<FunctorType, TNameMap>(decoratedF, radius);
497 }
498 
499 } // namespace otb
500 
501 #ifndef OTB_MANUAL_INSTANTIATION
502 #include "otbFunctorImageFilter.hxx"
503 #endif
504 
505 #endif
A generic functor filter templated by its functor.
FunctorImageFilter(const FunctorType &f, itk::Size< 2 > radius)
Constructor of functor filter, will copy the functor.
typename SuperclassHelper::InputHasNeighborhood InputHasNeighborhood
const FunctorType & GetFunctor() const
FunctorType & GetModifiableFunctor()
void operator=(const Self &)=delete
typename Superclass::OutputImageType OutputImageType
FunctorImageFilter(const Self &)=delete
itk::SmartPointer< const Self > ConstPointer
typename SuperclassHelper::FilterType Superclass
static std::enable_if_t<!std::is_default_constructible< F >::value, Pointer > New()
static std::enable_if_t< std::is_default_constructible< F >::value, Pointer > New()
typename Superclass::InputTypesTupleType InputTypesTupleType
typename Superclass::template InputImageType< I > InputImageType
typename OutputImageType::RegionType OutputImageRegionType
itk::SmartPointer< Self > Pointer
Creation of an "otb" image which contains metadata.
Definition: otbImage.h:92
Base class for image filter with variadic inputs.
Adds tagged versions for Get/SetInput to otb::VariadicInputsImageFilter.
Creation of an "otb" vector image which contains metadata.
The "otb" namespace contains all Orfeo Toolbox (OTB) classes.
auto NewFunctorFilter(Functor f, itk::Size< 2 > radius={{0, 0}})
This helper method builds a fully functional FunctorImageFilter from a functor instance.
typename std::remove_cv< typename std::remove_reference< T >::type >::type RemoveCVRef
that has std::remove_cvref)
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::FilterType FilterType
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::InputHasNeighborhood InputHasNeighborhood
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::OutputImageType OutputImageType
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::InputHasNeighborhood InputHasNeighborhood
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::FilterType FilterType
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::OutputImageType OutputImageType
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::InputHasNeighborhood InputHasNeighborhood
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::FilterType FilterType
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::OutputImageType OutputImageType
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::FilterType FilterType
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::InputHasNeighborhood InputHasNeighborhood
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::OutputImageType OutputImageType
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::InputHasNeighborhood InputHasNeighborhood
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::OutputImageType OutputImageType
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::FilterType FilterType
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::OutputImageType OutputImageType
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::InputHasNeighborhood InputHasNeighborhood
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T... >::FilterType FilterType
Struct allowing to derive the superclass prototype for the FunctorImageFilter class.
Helper struct to derive ImageType from template parameter.
Struct testing if T is a neighborhood.
Helper struct to check if a type can be used as pixel type.
This struct allows forwarding the operator of template parameter, while adding number of output compo...
constexpr NumberOfOutputBandsDecorator(F t, unsigned int nbComp)
constexpr vcl_size_t OutputSize(...) const
Helper struct to derive PixelType from template parameter.
Struct to retrieve the operator type.
decltype(&T::operator()) Type
std::tuple< typename IsNeighborhood< T >::type... > InputHasNeighborhood
typename std::conditional< std::is_void< TNameMap >::value, VariadicInputsImageFilter< OutputImageType, InputImageType< T >... >, VariadicNamedInputsImageFilter< OutputImageType, TNameMap, InputImageType< T >... > >::type FilterType
typename ImageTypeDeduction< R >::ImageType OutputImageType
typename ImageTypeDeduction< typename PixelTypeDeduction< RemoveCVRef< V > >::PixelType >::ImageType InputImageType