Commit 1d746451 authored by Julien Michel's avatar Julien Michel

Merge branch 'functorfilter-take2' into 'develop'

Add Functor module with FunctorImageFilter

See merge request !299
parents 827ed710 5f46ddbd
#
# Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
#
# This file is part of Orfeo Toolbox
#
# https://www.orfeo-toolbox.org/
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
project(OTBFunctor)
otb_module_impl()
This diff is collapsed.
This diff is collapsed.
/*
* Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otb_VariadicAddFunctor_h
#define otb_VariadicAddFunctor_h
#include <numeric>
#include <array>
namespace otb
{
namespace Functor
{
/**
* \class VariadicAdd
* \brief This functor adds any number of compile time scalar inputs
* \ingroup OTBFunctor
*/
template <typename TOut, typename ...TIns> struct VariadicAdd
{
auto operator()(TIns... ins) const
{
std::array<TOut, sizeof...(TIns)> outArray = {{static_cast<TOut>(ins)...}};
return std::accumulate(outArray.begin(), outArray.end(),TOut{});
}
};
} // end namespace Functor
} // end namespace otb
#endif
/*
* Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otb_VariadicConcatenateFunctor_h
#define otb_VariadicConcatenateFunctor_h
#include "itkVariableLengthVector.h"
#include <vector>
#include <numeric>
#include <array>
namespace otb
{
namespace Functor
{
namespace variadic_concatenate_details
{
template <typename T> size_t NumberOfElements(const T &)
{
static_assert(std::is_scalar<T>::value,"variadic_concatenate_details::NumberOfElements<T> only works for T and itk::VariableLengthVector<T> where T is a scalar type.");
return 1;
}
template <typename T> size_t NumberOfElements(const itk::VariableLengthVector<T> & v)
{
static_assert(std::is_scalar<T>::value,"variadic_concatenate_details::NumberOfElements<T> only works for T and itk::VariableLengthVector<T> where T is a scalar type.");
return v.GetSize();
}
template <typename ...T> size_t NumberOfElements(const T&...t)
{
std::array<size_t,sizeof...(T)> sizes = {{NumberOfElements(t)...}};
return std::accumulate(sizes.begin(),sizes.end(),0);
}
template <typename Out, typename T> size_t fillVector(itk::VariableLengthVector<Out> & out, size_t idx, const T & t)
{
assert(idx<out.GetSize());
out[idx] = static_cast<Out>(t);
return idx+1;
}
template <typename Out, typename T> size_t fillVector(itk::VariableLengthVector<Out> & out, size_t idx, const itk::VariableLengthVector<T> & t)
{
assert(idx+t.GetSize()<=out.GetSize());
for(auto it = 0UL; it<t.GetSize(); ++it)
out[idx+it] = static_cast<Out>(t[it]);
return idx+t.GetSize();
}
template <typename Out, typename Current, typename ...T> size_t fillVector(itk::VariableLengthVector<Out> & out, size_t idx, const Current& current, const T&...t)
{
size_t newIdx = fillVector(out,idx,current);
return fillVector(out,newIdx,t...);
}
} // end namespace variadic_concatenate_details
// N images (all types) -> vector image
// This functor concatenates N images (N = variadic) of type
// VectorImage and or Image, into a single VectorImage
/**
* \class VariadicConcatenate
* \brief This functor concatenates any number of input of scalar type
* or VariableLengthVector.
* \ingroup OTBFunctor
*/
template<typename TOut, typename ...TIns> struct VariadicConcatenate
{
auto operator()(const TIns &... ins) const
{
const size_t numberOfElements = variadic_concatenate_details::NumberOfElements(ins...);
itk::VariableLengthVector<TOut> out(numberOfElements);
variadic_concatenate_details::fillVector(out,0,ins...);
return out;
}
// Must define OutputSize because output pixel is vector
constexpr size_t OutputSize(const std::array<size_t, sizeof...(TIns)> inputsNbBands) const
{
return std::accumulate(inputsNbBands.begin(),inputsNbBands.end(),0);
}
};
} // end namespace Functor
} // end namespace otb
#endif
/*
* Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otb_VariadicInputsImageFilter_h
#define otb_VariadicInputsImageFilter_h
#include "itkImageSource.h"
namespace otb {
/**
* \brief Base class for image filter with variadic inputs.
*
* This filter act as a base class for all filters that will take
* several input images with different types and produce an output
* image.
*
* Type for each input is taken from the variadic template parameter
* TInputs.
*
* Inputs get be set/get with SetVariadicInput<N>() and
* GetVariadicInput<N>(), when N is the index (first input is 0) of
* the input. This is resolved at compile time: you can not call
* SetVariadicInput<N>() with an argument not matching the Nth input
* type (it will lead to type mismatch compilation error).
*
* Alternatively, you can call SetVariadicInputs() with all the input
* image in the same order as in the template parameters.
*
* Last, there is a macro that generates SetInput1() ... SetInput10()
* (iff the number of varidic input types is large enough) for
* backward compatibility.
*
*/
template<class TOuptut, class ... TInputs> class VariadicInputsImageFilter : public itk::ImageSource<TOuptut>
{
public:
using Self = VariadicInputsImageFilter<TOuptut, TInputs...>;
using Pointer = itk::SmartPointer<Self>;
using ConstPointer = itk::SmartPointer<const Self>;
using Superclass = itk::ImageSource<TOuptut>;
using InputTypesTupleType = std::tuple<TInputs...>;
template <size_t I> using InputImageType = typename std::tuple_element<I,InputTypesTupleType>::type;
static constexpr size_t NumberOfInputs = std::tuple_size<InputTypesTupleType>::value;
// Good old new macro
itkNewMacro(Self);
/**
* \param Set the Ith input
*/
template <std::size_t I> void SetVariadicInput(const typename std::tuple_element<I,InputTypesTupleType>::type * inputPtr)
{
static_assert(std::tuple_size<InputTypesTupleType>::value>I,"Template value I is out of range.");
this->SetNthInput(I,const_cast<typename std::tuple_element<I,InputTypesTupleType>::type *>(inputPtr));
}
#define DefineLegacySetInputMacro(n) \
template<typename Tuple = InputTypesTupleType, typename Check = typename std::enable_if<n<=std::tuple_size<Tuple>::value >::type> \
void SetInput ## n(const typename std::tuple_element<n-1,Tuple>::type * img) \
{ \
this->template SetVariadicInput<n-1>(img); \
}
// The following defines legacy setters SetInput1()
// ... SetInput10(), only if the number of input type is sufficient
DefineLegacySetInputMacro(1);
DefineLegacySetInputMacro(2);
DefineLegacySetInputMacro(3);
DefineLegacySetInputMacro(4);
DefineLegacySetInputMacro(5);
DefineLegacySetInputMacro(6);
DefineLegacySetInputMacro(7);
DefineLegacySetInputMacro(8);
DefineLegacySetInputMacro(9);
DefineLegacySetInputMacro(10);
#undef DefineLegacySetInputMacro
/**
* \return the Ith variadic input
*/
template <std::size_t I> const typename std::tuple_element<I,InputTypesTupleType>::type * GetVariadicInput()
{
static_assert(std::tuple_size<InputTypesTupleType>::value>I,"Template value I is out of range.");
using ImageType = typename std::tuple_element<I,InputTypesTupleType>::type;
return dynamic_cast<const ImageType *>(this->GetInput(I));
}
/**
* \param inputs A vararg list of inputs
*/
void SetVariadicInputs(TInputs*... inputs)
{
auto inTuple = std::make_tuple(inputs...);
SetInputsImpl(inTuple,std::make_index_sequence<sizeof...(inputs)>{});
}
/**
* \return A tuple with all inputs
*/
auto GetVariadicInputs()
{
return GetInputsImpl(std::make_index_sequence<sizeof...(TInputs)>{});
}
protected:
VariadicInputsImageFilter()
{
this->SetNumberOfRequiredInputs(sizeof...(TInputs));
};
~VariadicInputsImageFilter() = default;
private:
template<class Tuple, size_t...Is> auto SetInputsImpl(Tuple& t, std::index_sequence<Is...>)
{
return std::initializer_list<int>{(this->SetVariadicInput<Is>(std::get<Is>(t)),0)...};
}
template <size_t...Is> auto GetInputsImpl(std::index_sequence<Is...>)
{
return std::make_tuple(this->GetVariadicInput<Is>()...);
}
VariadicInputsImageFilter(const Self&) = delete;
void operator=(const Self&) = delete;
};
}
#endif
/*
* Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef otb_VariadicNamedInputsImageFilter_h
#define otb_VariadicNamedInputsImageFilter_h
#include "otbVariadicInputsImageFilter.h"
namespace otb {
/// TODO: Documentation
namespace internal
{
template<typename Arg, typename Tuple> struct tuple_index;
template<typename Arg, typename...Args> struct tuple_index<Arg, std::tuple<Arg,Args...> >
{
static constexpr std::size_t value = 0;
};
template<typename Arg, typename NotMatching, typename...Args> struct tuple_index<Arg, std::tuple<NotMatching,Args...>>
{
static_assert(sizeof...(Args)>0,"Could not find requested type in tuple");
static constexpr std::size_t value = 1 + tuple_index<Arg,std::tuple<Args...>>::value;
};
}
template<class TOuptut, class TInputNameMap, class ... TInputs> class VariadicNamedInputsImageFilter : public VariadicInputsImageFilter<TOuptut,TInputs...>
{
public:
using Self = VariadicNamedInputsImageFilter<TOuptut,TInputNameMap, TInputs...>;
using Pointer = itk::SmartPointer<Self>;
using ConstPointer = itk::SmartPointer<const Self>;
using Superclass = VariadicInputsImageFilter<TOuptut, TInputs...>;;
using InputTypesTupleType = typename Superclass::InputTypesTupleType;
template <size_t I> using InputImageType = typename Superclass::template InputImageType<I>;
static constexpr size_t NumberOfInputs = Superclass::NumberOfInputs;
static_assert(std::tuple_size<TInputNameMap>::value == NumberOfInputs,"Tuple for input name does not match the size of ... TInputs");
itkNewMacro(Self);
template <typename Tag> void SetVariadicNamedInput(const InputImageType<internal::tuple_index<Tag, TInputNameMap>::value> * inputPtr)
{
constexpr size_t idx = internal::tuple_index<Tag, TInputNameMap>::value;
this->SetNthInput(idx,const_cast<InputImageType<idx> *>(inputPtr));
}
template <typename Tag> void SetVariadicNamedInput(Tag,const InputImageType<internal::tuple_index<Tag, TInputNameMap>::value> * inputPtr)
{
SetVariadicNamedInput<Tag>(inputPtr);
}
template <typename Tag> const InputImageType<internal::tuple_index<Tag,TInputNameMap>::value> * GetVariadicNamedInput()
{
constexpr size_t idx = internal::tuple_index<Tag, TInputNameMap>::value;
return dynamic_cast<const InputImageType<idx> *>(this->GetInput(idx));
}
template <typename Tag> const InputImageType<internal::tuple_index<Tag,TInputNameMap>::value> * GetVariadicNamedInput(Tag)
{
return GetVariadicNamedInput<Tag>();
}
protected:
VariadicNamedInputsImageFilter() = default;
~VariadicNamedInputsImageFilter() = default;
private:
VariadicNamedInputsImageFilter(const Self&) = delete;
void operator=(const Self&) = delete;
};
}
#endif
#
# Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
#
# This file is part of Orfeo Toolbox
#
# https://www.orfeo-toolbox.org/
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
set(DOCUMENTATION "This module contains a generic functor filter
implementation, that can deal with functor, std::function or lambdas
with any number of parameters including VariableLengthVector,
FixedArray, RGBPixel, and Neighborhood of those.")
otb_module(OTBFunctor
DEPENDS
OTBITK
OTBCommon
OTBImageBase
TEST_DEPENDS
OTBTestKernel
DESCRIPTION
"${DOCUMENTATION}"
)
#
# Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
#
# This file is part of Orfeo Toolbox
#
# https://www.orfeo-toolbox.org/
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
otb_module_test()
set(OTBFunctorTests
otbFunctorTestDriver.cxx
otbFunctorImageFilter.cxx
)
add_executable(otbFunctorTestDriver ${OTBFunctorTests})
target_link_libraries(otbFunctorTestDriver ${OTBFunctor-Test_LIBRARIES})
otb_module_target_label(otbFunctorTestDriver)
otb_add_test(NAME bfTvFunctorImageFilter COMMAND otbFunctorTestDriver
otbFunctorImageFilter)
This diff is collapsed.
/*
* Copyright (C) 2005-2017 Centre National d'Etudes Spatiales (CNES)
*
* This file is part of Orfeo Toolbox
*
* https://www.orfeo-toolbox.org/
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "otbTestMain.h"
void RegisterTests()
{
REGISTER_TEST(otbFunctorImageFilter);
}
......@@ -40,7 +40,6 @@ set(OTBImageBaseTests
otbImageTest.cxx
otbImageFunctionAdaptor.cxx
otbMetaImageFunction.cxx
)
add_executable(otbImageBaseTestDriver ${OTBImageBaseTests})
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment