OTB  6.7.0
Orfeo Toolbox
otbFunctorImageFilter.h
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2005-2019 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"
31 #include <type_traits>
33 #include "otbImage.h"
34 
35 namespace otb
36 {
45 template <class T> struct IsNeighborhood : std::false_type {};
46 
48 template <class T> struct IsNeighborhood<const itk::ConstNeighborhoodIterator<Image<T>>&> : std::true_type {};
49 
51 template <class T> struct IsNeighborhood<const itk::ConstNeighborhoodIterator<VectorImage<T>>&> : std::true_type {};
52 
59 template <class T> struct IsSuitableType : std::is_scalar<T>::type {};
60 
62 template <class T> struct IsSuitableType<std::complex<T>> : IsSuitableType<T>::type {};
63 
65 template <class T> struct IsSuitableType<itk::VariableLengthVector<T>> : IsSuitableType<T>::type {};
66 
68 template <class T, unsigned int N> struct IsSuitableType<itk::FixedArray<T,N>> : IsSuitableType<T>::type {};
69 
71 template <class T> struct IsSuitableType<itk::RGBPixel<T>> : IsSuitableType<T>::type {};
72 
74 template <class T> struct IsSuitableType<itk::RGBAPixel<T>> : IsSuitableType<T>::type {};
75 
84 template <class T> struct PixelTypeDeduction
85 {
86  static_assert(IsSuitableType<T>::value,
87  "T can not be used as a template parameter for Image or VectorImage classes.");
88  using PixelType = T;
89 };
90 
92 template <class T> struct PixelTypeDeduction<itk::ConstNeighborhoodIterator<Image<T>>>
93 {
94  static_assert(IsSuitableType<T>::value,
95  "T can not be used as a template parameter for Image or VectorImage classes.");
96  using PixelType = T;
97 };
98 
100 template <class T> struct PixelTypeDeduction<itk::ConstNeighborhoodIterator<VectorImage<T>>>
101 {
102  static_assert(IsSuitableType<T>::value,
103  "T can not be used as a template parameter for Image or VectorImage classes.");
105 };
106 
115 template <class T> struct ImageTypeDeduction
116 {
118 };
119 
121 template <class T> struct ImageTypeDeduction<itk::VariableLengthVector<T>>
122 {
124 };
125 
126 // Helper to remove const, volatite and Ref qualifier (until c++20
128 template <typename T> using RemoveCVRef = typename std::remove_cv<typename std::remove_reference<T>::type>::type;
129 
138 template <typename T> struct RetrieveOperator
139 {
140  static_assert(std::is_class<T>::value || std::is_function<T>::value, "T is not a class or function");
141  using Type = decltype(&T::operator());
142 };
144 
157 template <typename T, typename TNameMap> struct FunctorFilterSuperclassHelper : public FunctorFilterSuperclassHelper<typename RetrieveOperator<T>::Type,TNameMap> {};
158 
159 namespace functor_filter_details
160 {
161 template <typename R, typename TNameMap, typename...T> struct FunctorFilterSuperclassHelperImpl
162 {
163  // OutputImageType is derived from return type R
165  // InputImageType is derived using pixel type deduction and image
166  // type deduction
167  template <typename V> using InputImageType = typename ImageTypeDeduction<typename PixelTypeDeduction<RemoveCVRef<V>>::PixelType>::ImageType;
168 
169  // Filter type is either VariadicInputsImageFilter or
170  // VariadicNamedInputsImageFilter depending on if there is a
171  // TNameMap or not
172  using FilterType = typename std::conditional<std::is_void<TNameMap>::value,
175 
176  // InputHasNeighborhood is derived from IsNeighborhood
177  using InputHasNeighborhood = std::tuple<typename IsNeighborhood<T>::type...>;
178 };
179 } // End namespace functor_filter_details
180 
182 template <typename R, typename... T, typename TNameMap> struct FunctorFilterSuperclassHelper<R(*)(T...),TNameMap>
183 {
187 };
188 
190 template <typename C, typename R, typename... T, typename TNameMap> struct FunctorFilterSuperclassHelper<R(C::*)(T...) const, TNameMap>
191 {
195 
196 };
197 
199 template <typename C, typename R, typename... T, typename TNameMap> struct FunctorFilterSuperclassHelper<R(C::*)(T...), TNameMap>
200 {
204 
205 };
206 
208 template <typename R, typename... T, typename TNameMap> struct FunctorFilterSuperclassHelper<void(*)(R&, T...), TNameMap>
209 {
213 
214 };
215 
217 template <typename C, typename R, typename... T, typename TNameMap> struct FunctorFilterSuperclassHelper<void(C::*)(R&,T...) const, TNameMap>
218 {
222 
223 };
224 
226 template <typename C, typename R, typename... T, typename TNameMap> struct FunctorFilterSuperclassHelper<void(C::*)(R&,T...), TNameMap>
227 {
231 };
232 
233 
234 
261 template <typename Functor, typename TNameMap = void> auto NewFunctorFilter(Functor f, itk::Size<2> radius = {{0,0}});
262 
263 
284 template <class TFunction, class TNameMap = void>
285  class ITK_EXPORT FunctorImageFilter
286  : public FunctorFilterSuperclassHelper<TFunction, TNameMap>::FilterType
287 {
288 
289 public:
290  // Standard typedefs
292  using FunctorType = TFunction;
295 
296  // Superclass through the helper struct
298  using Superclass = typename SuperclassHelper::FilterType;
299  using OutputImageType = typename Superclass::OutputImageType;
300  using OutputImageRegionType = typename OutputImageType::RegionType;
301 
302  // A tuple of bool of the same size as the number of arguments in
303  // the functor
304  using InputHasNeighborhood = typename SuperclassHelper::InputHasNeighborhood;
305  using InputTypesTupleType = typename Superclass::InputTypesTupleType;
306  template<size_t I> using InputImageType = typename Superclass::template InputImageType<I>;
307  using Superclass::NumberOfInputs;
308 
311 
313  template <typename F = TFunction> static std::enable_if_t<std::is_default_constructible<F>::value, Pointer> New()
314  {
315  // Explicit default construct
316  FunctorType f;
317 
318  // Create a filter out of it
319  Pointer p = new Self(f, {{0,0}});
320  p->UnRegister();
321  return p;
322  }
323 
326  template <typename F = TFunction> static std::enable_if_t<!std::is_default_constructible<F>::value, Pointer> New()
327  {
328  static_assert(std::is_default_constructible<F>::value,"Cannot call New() "
329  "function as the functor used for the filter creation is not default "
330  "constructible");
331 
332  return nullptr;
333  }
334 
343  {
344  this->Modified();
345  return m_Functor;
346  }
348 
354  const FunctorType& GetFunctor() const
355  {
356  return m_Functor;
357  }
358 
359 protected:
361  FunctorImageFilter(const FunctorType& f, itk::Size<2> radius) : m_Functor(f), m_Radius(radius) {};
362  FunctorImageFilter(const Self &) = delete;
363  void operator =(const Self&) = delete;
364  ~FunctorImageFilter() = default;
365 
366 private:
368  friend auto NewFunctorFilter<TFunction,TNameMap>(TFunction f, itk::Size<2> radius);
369 
371  void ThreadedGenerateData(const OutputImageRegionType& outputRegionForThread, itk::ThreadIdType threadId) override;
372 
376  void GenerateInputRequestedRegion(void) override;
377 
381  void GenerateOutputInformation() override;
382 
383 
384  // The functor member
386 
387  // Radius if needed
389 };
390 
391 // Actual implementation of NewFunctorFilter free function
392 template <typename Functor, typename TNameMap> auto NewFunctorFilter(Functor f, itk::Size<2> radius)
393 {
394  using FilterType = FunctorImageFilter<Functor,TNameMap>;
395  using PointerType = typename FilterType::Pointer;
396 
397  PointerType p = new FilterType(f,radius);
398  p->UnRegister();
399  return p;
400 }
401 
413 template <typename F> struct NumberOfOutputBandsDecorator : public F
414 {
415 public:
416  constexpr NumberOfOutputBandsDecorator(F t, unsigned int nbComp) : F(t), m_NumberOfOutputBands(nbComp) {}
417 
418  constexpr size_t OutputSize(...) const
419  {
420  return m_NumberOfOutputBands;
421  }
422 
423 private:
424  unsigned int m_NumberOfOutputBands;
425 };
426 
447 template <typename Functor, typename TNameMap = void> auto NewFunctorFilter(Functor f, unsigned int numberOfOutputBands, itk::Size<2> radius)
448 {
449  using FunctorType = NumberOfOutputBandsDecorator<Functor>;
450  FunctorType decoratedF(f,numberOfOutputBands);
451  return NewFunctorFilter<FunctorType,TNameMap>(decoratedF,radius);
452 }
453 
454 }// namespace otb
455 
456 #ifndef OTB_MANUAL_INSTANTIATION
457 #include "otbFunctorImageFilter.hxx"
458 #endif
459 
460 #endif
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T...>::OutputImageType OutputImageType
std::tuple< typename IsNeighborhood< T >::type...> InputHasNeighborhood
FunctorType & GetModifiableFunctor()
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T...>::OutputImageType OutputImageType
Creation of an "otb" vector image which contains metadata.
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T...>::OutputImageType OutputImageType
typename ImageTypeDeduction< typename PixelTypeDeduction< RemoveCVRef< V >>::PixelType >::ImageType InputImageType
This struct allows to forward the operator of template parameter, while adding number of ouptut compo...
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T...>::FilterType FilterType
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T...>::InputHasNeighborhood InputHasNeighborhood
Struct testing if T is a neighborhood.
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T...>::OutputImageType OutputImageType
Struct to retrieve the operator type.
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T...>::InputHasNeighborhood InputHasNeighborhood
static std::enable_if_t< std::is_default_constructible< F >::value, Pointer > New()
constexpr NumberOfOutputBandsDecorator(F t, unsigned int nbComp)
Helper struct to derive ImageType from template parameter.
Helper struct to check if a type can be used as pixel type.
void UnRegister() ITK_SP_NOEXCEPT
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T...>::OutputImageType OutputImageType
Helper struct to derive PixelType from template parameter.
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...>::FilterType FilterType
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T...>::InputHasNeighborhood InputHasNeighborhood
Creation of an "otb" image which contains metadata.
Definition: otbImage.h:89
Adds tagged versions for Get/SetInput to otb::VariadicInputsImageFilter.
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T...>::FilterType FilterType
typename ImageTypeDeduction< R >::ImageType OutputImageType
typename std::conditional< std::is_void< TNameMap >::value, VariadicInputsImageFilter< OutputImageType, InputImageType< T >...>, VariadicNamedInputsImageFilter< OutputImageType, TNameMap, InputImageType< T >...>>::type FilterType
Base class for image filter with variadic inputs.
unsigned int ThreadIdType
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T...>::FilterType FilterType
FunctorImageFilter(const FunctorType &f, itk::Size< 2 > radius)
Constructor of functor filter, will copy the functor.
const FunctorType & GetFunctor() const
A generic functor filter templated by its functor.
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T...>::FilterType FilterType
auto NewFunctorFilter(Functor f, itk::Size< 2 > radius={{0, 0}})
This helper method builds a fully functional FunctorImageFilter from a functor instance.
constexpr vcl_size_t OutputSize(...) const
static std::enable_if_t<!std::is_default_constructible< F >::value, Pointer > New()
typename std::remove_cv< typename std::remove_reference< T >::type >::type RemoveCVRef
that has std::remove_cvref)
decltype(&T::operator()) Type
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T...>::InputHasNeighborhood InputHasNeighborhood
typename functor_filter_details::FunctorFilterSuperclassHelperImpl< R, TNameMap, T...>::InputHasNeighborhood InputHasNeighborhood
Struct allowing to derive the superclass prototype for the FunctorImageFilter class.