diff --git a/Modules/Applications/AppIndices/app/otbRadiometricIndices.cxx b/Modules/Applications/AppIndices/app/otbRadiometricIndices.cxx index 20d2ac2c3e6c5a9f6a32291d71cf365c83e1892c..6c4d6d60ef48c42374555011a968b2724b0e7202 100644 --- a/Modules/Applications/AppIndices/app/otbRadiometricIndices.cxx +++ b/Modules/Applications/AppIndices/app/otbRadiometricIndices.cxx @@ -26,7 +26,7 @@ #include "otbWaterIndicesFunctor.h" #include "otbBuiltUpIndicesFunctor.h" #include "otbSoilIndicesFunctor.h" -#include "otbCompositeIndicesFunctor.h" +#include "otbIndicesStackFunctor.h" #include "otbFunctorImageFilter.h" namespace otb @@ -52,7 +52,7 @@ public: using OutputType = FloatImageType::PixelType; using RadiometricIndiceType = otb::Functor::RadiometricIndice<InputType, OutputType>; - using CompositeIndicesFunctorType = otb::Functor::CompositeIndicesFunctor<InputType,OutputType>; + using IndicesStackFunctorType = otb::Functor::IndicesStackFunctor<RadiometricIndiceType>; class indiceSpec { @@ -240,7 +240,7 @@ private: // Build a composite indices functor to compute all indices at // once - auto compositeFunctor = CompositeIndicesFunctorType(indices); + auto compositeFunctor = IndicesStackFunctorType(indices); // Build and plug functor filter auto filter = NewFunctorFilter(compositeFunctor); diff --git a/Modules/Radiometry/Indices/include/otbBuiltUpIndicesFunctor.h b/Modules/Radiometry/Indices/include/otbBuiltUpIndicesFunctor.h index fb901b3d67398258aac18c857419ce3b4a56aa73..3ea54e5b8b4b51031f4e1367dc18e8891e6534f3 100644 --- a/Modules/Radiometry/Indices/include/otbBuiltUpIndicesFunctor.h +++ b/Modules/Radiometry/Indices/include/otbBuiltUpIndicesFunctor.h @@ -49,14 +49,14 @@ template <class TInput, class TOutput> class NDBI : public RadiometricIndice<TInput,TOutput> { public: - NDBI() : RadiometricIndice<TInput,TOutput>("NDBI",{CommonBandNames::RED, CommonBandNames::NIR}) {} + NDBI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { auto red = this->Value(CommonBandNames::RED,input); auto nir = this->Value(CommonBandNames::NIR,input); - if (std::abs(red+nir) < EpsilonToBeConsideredAsZero) + if (std::abs(red+nir) < RadiometricIndice<TInput,TOutput>::Epsilon) { return static_cast<TOutput>(0.); } @@ -80,7 +80,7 @@ template <class TInput, class TOutput> class ISU : public RadiometricIndice<TInput,TOutput> { public: - ISU() : RadiometricIndice<TInput,TOutput>("ISU",{CommonBandNames::RED, CommonBandNames::NIR}) {} + ISU() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { diff --git a/Modules/Radiometry/Indices/include/otbCompositeIndicesFunctor.h b/Modules/Radiometry/Indices/include/otbCompositeIndicesFunctor.h deleted file mode 100644 index cb3f2ce4ac1a0f86a6dec3d0a25d6fe01b48a431..0000000000000000000000000000000000000000 --- a/Modules/Radiometry/Indices/include/otbCompositeIndicesFunctor.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright (C) 2005-2019 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 otbCompositeIndicesFunctor_h -#define otbCompositeIndicesFunctor_h - -#include "otbWaterIndicesFunctor.h" -#include "otbBuiltUpIndicesFunctor.h" -#include "otbSoilIndicesFunctor.h" - -#include <vector> -#include <stdexcept> - -namespace otb { - -namespace Functor { - -template <typename TInput, typename TOuput> -class CompositeIndicesFunctor -{ -public: - using InputType = itk::VariableLengthVector<TInput>; - using OutputType = itk::VariableLengthVector<TOuput>; - using IndiceType = RadiometricIndice<TInput,TOuput>; - - CompositeIndicesFunctor(std::vector<IndiceType*> & indices) - : m_Indices(indices) - {} - - void operator()(OutputType & out, const InputType & in) const - { - size_t idx = 0; - for(auto indice : m_Indices) - { - out[idx] = (*indice)(in); - } - } - - size_t OutputSize(...) const - { - return m_Indices.size(); - } - -private: - std::vector<IndiceType*> m_Indices; -}; - -} // End namespace Functor - -} // End namespace otb - - - - -#endif diff --git a/Modules/Radiometry/Indices/include/otbIndicesStackFunctor.h b/Modules/Radiometry/Indices/include/otbIndicesStackFunctor.h new file mode 100644 index 0000000000000000000000000000000000000000..01fbef724888f84df31d3775c9a68aa6c9391d2e --- /dev/null +++ b/Modules/Radiometry/Indices/include/otbIndicesStackFunctor.h @@ -0,0 +1,97 @@ +/* + * Copyright (C) 2005-2019 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 otbIndicesStackFunctor_h +#define otbIndicesStackFunctor_h + +#include <vector> +#include <stdexcept> + +namespace otb { + +namespace Functor { +/** + * \class IndicesStackFunctor + * \brief A class to compute a stack of radiometric indices + * + * This functor can be built from a vector of TIndice*. its operator() + * will apply each functor of this vector to the input pixel, and + * return a VariableLengthVector containing the list resulting + * values. It can be used with otb::FunctorImageFilter + * \sa FunctorImageFilter + * \ingroup Indices + */ +template <typename TIndice> +class IndicesStackFunctor +{ +public: + /// Read input / output types from TIndice + using IndiceType = TIndice; + using PixelType = typename IndiceType::PixelType; + // Output will be a VariableLengthVector of values return by + // radiometric indices + using OutputType = itk::VariableLengthVector<typename IndiceType::OutputType>; + + /** + * \param indices A std::vector<IndiceType*> for indices to compute + * the indice stack + * \throw std::runtime_error if indices is empty + */ + IndicesStackFunctor(const std::vector<IndiceType*> & indices) + : m_Indices(indices) + { + if(indices.empty()) + { + throw std::runtime_error("Can not build IndicesStackFunctor from an empty list of indices."); + } + } + + /** + * \param input A itk::VariableLengthVector<TInput> holding the + * pixel values for each band + * \return A VariableLengthVector<TInput::OutputType> holding all + * the indices values + */ + void operator()(OutputType & out, const PixelType & in) const + { + size_t idx = 0; + for(auto indice : m_Indices) + { + out[idx] = (*indice)(in); + } + } + /** + * \return the size of the indices list (to be used by FunctorImgeFilter) + */ + size_t OutputSize(...) const + { + return m_Indices.size(); + } + +private: + /// The list of indices to use + std::vector<IndiceType*> m_Indices; +}; + +} // End namespace Functor + +} // End namespace otb + +#endif diff --git a/Modules/Radiometry/Indices/include/otbLandsatTMIndices.h b/Modules/Radiometry/Indices/include/otbLandsatTMIndices.h index 8dfa9cb4649682049b04f36f20fe789c739724de..e375136a982551382602aaf0d0c2d53c1978c26e 100644 --- a/Modules/Radiometry/Indices/include/otbLandsatTMIndices.h +++ b/Modules/Radiometry/Indices/include/otbLandsatTMIndices.h @@ -23,7 +23,7 @@ #include "otbMath.h" #include "itkVariableLengthVector.h" -#include "otbBandName.h" +#include "otbRadiometricIndice.h" #include "otbFuzzyVariable.h" #include <vector> #include <algorithm> diff --git a/Modules/Radiometry/Indices/include/otbRadiometricIndice.h b/Modules/Radiometry/Indices/include/otbRadiometricIndice.h index 9a7eaa02e3cdfb285d671f2ec0efa8089e6ac8e6..4de485bad8b918008a8ee33a83da082e2ec4e89a 100644 --- a/Modules/Radiometry/Indices/include/otbRadiometricIndice.h +++ b/Modules/Radiometry/Indices/include/otbRadiometricIndice.h @@ -27,6 +27,7 @@ #include <set> #include <string> #include <map> +#include <stdexcept> using namespace otb::BandName; @@ -34,20 +35,59 @@ namespace otb { namespace Functor { -constexpr double EpsilonToBeConsideredAsZero = 0.0000001; - +/** + * \class RadiometricIndice + * \brief Base class for all radiometric indices + * + * This class is the base class for all radiometric indices. + * + * It offers services to: + * - Indicate which band are required among the list provided by + * TBandNameEnum + * - Set indices of each required band + * - Compute the indice response to a pixel by subclassing the pure + * virtual operator() + * + * This class is designed for performance on the critical path. For + * best performances use the Value() method when implementing + * operator() to avoid branches. + * + * TBandName enum should end with a MAX value that will be used to + * derive the number of bands. + * + * \ingroup Indices + */ template <typename TInput, typename TOutput, typename TBandNameEnum = CommonBandNames> class RadiometricIndice { public: + /// Types for input/output + using InputType = TInput; + using PixelType = itk::VariableLengthVector<InputType>; + using OutputType = TOutput; + + /// Enum Among which bands are used using BandNameType = TBandNameEnum; + + /// The number of bands, derived from the Enum MAX value static constexpr size_t NumberOfBands = static_cast<size_t>(BandNameType::MAX); - RadiometricIndice(const std::string & name, const std::set<BandNameType>& requiredBands) + static constexpr double Epsilon = 0.0000001; + + /** + * \param requiredBands the set<TBandNameEnum> of required bands + * \throw runtime_error if requiredBands contains TBandNameEnum::MAX + */ + RadiometricIndice(const std::set<BandNameType>& requiredBands) : m_RequiredBands(), - m_BandIndices(), - m_Name(name) + m_BandIndices() { + if(requiredBands.find(BandNameType::MAX) != requiredBands.end()) + { + throw std::runtime_error("TBandNameEnum::MAX can not be used as a required band"); + } + + // Fill the required bands array m_RequiredBands.fill(false); m_BandIndices.fill(0); @@ -56,9 +96,11 @@ public: m_RequiredBands[static_cast<size_t>(b)]=true; } } - - ~RadiometricIndice() = default; - + + /** + * \return a set<TBandNameEnum> containing the required bands for + * this indice. + */ std::set<BandNameType> GetRequiredBands() const { std::set<BandNameType> resp; @@ -70,11 +112,25 @@ public: return resp; } + /** + * \param band The band to set (value in TBandNameEnum) + * \param index The index of the band to set + * \throw runtime_error if band is TBandNameEnum::MAX + */ void SetBandIndex(const BandNameType & band, const size_t & index) { + if(band == BandNameType::MAX) + { + throw std::runtime_error("Can not set index for TBandNameEnum::MAX"); + } m_BandIndices[static_cast<size_t>(band)]=index; } + /** + * \param indicesMap a std::map<TBandNameEnum,size_t> containing all + * bands indices to set + * \throw runtime_error if indicesMap contains TBandNameEnum::MAX + */ void SetBandsIndices(const std::map<BandNameType,size_t> & indicesMap) { for(auto it: indicesMap) @@ -83,40 +139,79 @@ public: } } + /** + * \param band The band for which to retrieve indice + * \return The indices of the band + * \throw runtime_error if band is TBandNameEnum::MAX + */ size_t GetBandIndex(const BandNameType & band) const { + if(band == BandNameType::MAX) + { + throw std::runtime_error("Can not get index for TBandNameEnum::MAX"); + } return m_BandIndices[static_cast<size_t>(band)]; } - const std::string & GetName() const - { - return m_Name; - } - + /** + * Astract method which will compute the radiometric indice + * \param input A itk::VariableLengthVector<TInput> holding the + * pixel values for each band + * \return The indice value as TOutput + */ virtual TOutput operator()(const itk::VariableLengthVector<TInput> & input) const = 0; - protected: - size_t BandIndex(const BandNameType & band) const + /** + * Helper method to retrieve index for band name. With respect to + * the public method, this method will not throw an exception if + * TBandNameEnum::MAX is used as a parameter. Since it is meant for + * internal use in the critical path and not for client code, it + * will only assert that band is not TBandNameEnum::MAX in debug + * mode. + * + * \param band The band for which to retrieve indice + * \return The indices of the band + */ + size_t UncheckedBandIndex(const BandNameType & band) const { - // TODO: Assert if this band is really mandatory for this functor + assert(band != BandNameType::MAX && "Can not retrieve index for band TBandNameEnum::MAX"); return m_BandIndices[static_cast<size_t>(band)]; } + /** + * Helper method to parse input itk::VariableLengthVector<TInput> + * and get the corresponding band value. + * For instance: + * \snippet auto red = this->Value(CommonBandNames::RED,input); + * + * As this function is on the critical performance path, no checks + * are made to see wether this band is really required for this + * indice. However an assertion will be raised in debug mode. + * + * \param band The band for which to retrieve the value + * \param input A itk::VariableLengthVector<TInput> holding the + * pixel values for each band + * \return The value of the band as double + * + */ double Value(const BandNameType & band, const itk::VariableLengthVector<TInput> & input) const { - return static_cast<double>(input[BandIndex(band)]); + assert(m_RequiredBands[band] && "Retrieving value for a band that is not in the required bands list"); + return static_cast<double>(input[UncheckedBandIndex(band)]); } private: - using RequiredBandsContainer = std::array<bool,NumberOfBands>; - using BandIndicesContainer = std::array<size_t,NumberOfBands>; - + // Explicitely disable default constructor RadiometricIndice() = delete; + /// An array storing the required status for each band + using RequiredBandsContainer = std::array<bool,NumberOfBands>; RequiredBandsContainer m_RequiredBands; + + /// An array storing the indice for each band + using BandIndicesContainer = std::array<size_t,NumberOfBands>; BandIndicesContainer m_BandIndices; - std::string m_Name; }; } // End namespace Indices diff --git a/Modules/Radiometry/Indices/include/otbSoilIndicesFunctor.h b/Modules/Radiometry/Indices/include/otbSoilIndicesFunctor.h index c9f71ccb7e8af17cfa656ee2c115da78e3d567ab..5744cac7ed14d3660d61cd8c96d6645895dcad45 100644 --- a/Modules/Radiometry/Indices/include/otbSoilIndicesFunctor.h +++ b/Modules/Radiometry/Indices/include/otbSoilIndicesFunctor.h @@ -46,14 +46,14 @@ template <class TInput, class TOutput> class RI : public RadiometricIndice<TInput,TOutput> { public: - RI() : RadiometricIndice<TInput,TOutput>("RI",{CommonBandNames::RED, CommonBandNames::GREEN}) {} + RI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::GREEN}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { auto green = this->Value(CommonBandNames::GREEN,input); auto red = this->Value(CommonBandNames::RED,input); - if (std::abs(green) < EpsilonToBeConsideredAsZero) + if (std::abs(green) < RadiometricIndice<TInput,TOutput>::Epsilon) { return static_cast<TOutput>(0.); } @@ -80,14 +80,14 @@ template <class TInput, class TOutput> class CI : public RadiometricIndice<TInput,TOutput> { public: - CI() : RadiometricIndice<TInput,TOutput>("CI",{CommonBandNames::RED, CommonBandNames::GREEN}) {} + CI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::GREEN}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { auto green = this->Value(CommonBandNames::GREEN,input); auto red = this->Value(CommonBandNames::RED,input); - if (std::abs(green + red) < EpsilonToBeConsideredAsZero) + if (std::abs(green + red) < RadiometricIndice<TInput,TOutput>::Epsilon) { return static_cast<TOutput>(0.); } @@ -110,7 +110,7 @@ template <class TInput, class TOutput> class BI : public RadiometricIndice<TInput,TOutput> { public: - BI() : RadiometricIndice<TInput,TOutput>("BI",{CommonBandNames::RED, CommonBandNames::GREEN}) {} + BI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::GREEN}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { @@ -136,7 +136,7 @@ class BI2 : public RadiometricIndice<TInput,TOutput> { public: - BI2() : RadiometricIndice<TInput,TOutput>("BI2",{CommonBandNames::RED, CommonBandNames::GREEN, CommonBandNames::NIR}) {} + BI2() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::GREEN, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { diff --git a/Modules/Radiometry/Indices/include/otbVegetationIndicesFunctor.h b/Modules/Radiometry/Indices/include/otbVegetationIndicesFunctor.h index fcd1a15f0f2d10c6ae7d7ea4736c35d2f3c77f06..d2d2edf277a8b2ebdb19e5a008b682f5632ea2c9 100644 --- a/Modules/Radiometry/Indices/include/otbVegetationIndicesFunctor.h +++ b/Modules/Radiometry/Indices/include/otbVegetationIndicesFunctor.h @@ -43,7 +43,7 @@ template <class TInput, class TOutput> class NDVI : public RadiometricIndice<TInput,TOutput> { public: - NDVI() : RadiometricIndice<TInput,TOutput>("NDVI",{CommonBandNames::RED, CommonBandNames::NIR}) {} + NDVI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { @@ -56,7 +56,7 @@ public: // This static compute will be used in indices derived from NDVI static double Compute(const double & red, const double & nir) { - if (std::abs(nir + red) < EpsilonToBeConsideredAsZero) + if (std::abs(nir + red) < RadiometricIndice<TInput,TOutput>::Epsilon) { return 0.; } @@ -80,14 +80,14 @@ template <class TInput, class TOutput> class RVI : public RadiometricIndice<TInput,TOutput> { public: - RVI() : RadiometricIndice<TInput,TOutput>("RVI",{CommonBandNames::RED, CommonBandNames::NIR}) {} + RVI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { auto red = this->Value(CommonBandNames::RED,input); auto nir = this->Value(CommonBandNames::NIR,input); - if (std::abs(red) < EpsilonToBeConsideredAsZero) + if (std::abs(red) < RadiometricIndice<TInput,TOutput>::Epsilon) { return static_cast<TOutput>(0.); } @@ -113,7 +113,7 @@ template <class TInput, class TOutput> class PVI : public RadiometricIndice<TInput,TOutput> { public: - PVI() : RadiometricIndice<TInput,TOutput>("PVI",{CommonBandNames::RED, CommonBandNames::NIR}) {} + PVI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { @@ -144,14 +144,14 @@ template <class TInput, class TOutput> class SAVI : public RadiometricIndice<TInput,TOutput> { public: - SAVI() : RadiometricIndice<TInput,TOutput>("SAVI",{CommonBandNames::RED, CommonBandNames::NIR}) {} + SAVI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { auto red = this->Value(CommonBandNames::RED,input); auto nir = this->Value(CommonBandNames::NIR,input); - if (std::abs(nir + red + L) < EpsilonToBeConsideredAsZero) + if (std::abs(nir + red + L) < RadiometricIndice<TInput,TOutput>::Epsilon) { return static_cast<TOutput>(0.); } @@ -177,7 +177,7 @@ template <class TInput, class TOutput> class TSAVI : public RadiometricIndice<TInput,TOutput> { public: - TSAVI() : RadiometricIndice<TInput,TOutput>("TSAVI",{CommonBandNames::RED, CommonBandNames::NIR}) {} + TSAVI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { @@ -186,7 +186,7 @@ public: double denominator = A * nir + red + X * (1. + A * A); - if (std::abs(denominator) < EpsilonToBeConsideredAsZero) + if (std::abs(denominator) < RadiometricIndice<TInput,TOutput>::Epsilon) { return static_cast<TOutput>(0.); } @@ -215,7 +215,7 @@ class WDVI : public RadiometricIndice<TInput,TOutput> { public: /// Constructor - WDVI() : RadiometricIndice<TInput,TOutput>("WDVI",{CommonBandNames::RED, CommonBandNames::NIR}) {} + WDVI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { @@ -249,7 +249,7 @@ template <class TInput, class TOutput> class MSAVI : public RadiometricIndice<TInput,TOutput> { public: - MSAVI() : RadiometricIndice<TInput,TOutput>("MSAVI",{CommonBandNames::RED, CommonBandNames::NIR}) {} + MSAVI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { @@ -263,7 +263,7 @@ public: double denominator = nir + red + L; - if (std::abs(denominator) < EpsilonToBeConsideredAsZero) + if (std::abs(denominator) < RadiometricIndice<TInput,TOutput>::Epsilon) { return static_cast<TOutput>(0.); } @@ -291,7 +291,7 @@ class MSAVI2 : public RadiometricIndice<TInput,TOutput> { public: - MSAVI2() : RadiometricIndice<TInput,TOutput>("MSAVI2",{CommonBandNames::RED, CommonBandNames::NIR}) {} + MSAVI2() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { @@ -322,7 +322,7 @@ template <class TInput, class TOutput> class GEMI : public RadiometricIndice<TInput,TOutput> { public: - GEMI() : RadiometricIndice<TInput,TOutput>("GEMI",{CommonBandNames::RED, CommonBandNames::NIR}) {} + GEMI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { @@ -333,7 +333,7 @@ public: double num_nu; double denom_nu = nir + red + 0.5; - if (std::abs(denom_nu) < EpsilonToBeConsideredAsZero) + if (std::abs(denom_nu) < RadiometricIndice<TInput,TOutput>::Epsilon) { nu = 0; } @@ -344,7 +344,7 @@ public: } double denom_GEMI = 1 - red; - if (std::abs(denom_GEMI) < EpsilonToBeConsideredAsZero) + if (std::abs(denom_GEMI) < RadiometricIndice<TInput,TOutput>::Epsilon) { return static_cast<TOutput>(0.); } @@ -369,7 +369,7 @@ template <class TInput, class TOutput> class AVI: public RadiometricIndice<TInput,TOutput> { public: - AVI() : RadiometricIndice<TInput,TOutput>("AVI",{CommonBandNames::GREEN, CommonBandNames::RED, CommonBandNames::NIR}) {} + AVI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::GREEN, CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { @@ -381,7 +381,7 @@ public: constexpr double dfact2 = (LambdaR - LambdaG) / LambdaR; double dterm1; double dterm2; - if (std::abs(nir - red) < EpsilonToBeConsideredAsZero) + if (std::abs(nir - red) < RadiometricIndice<TInput,TOutput>::Epsilon) { dterm1 = 0; } @@ -390,7 +390,7 @@ public: dterm1 = std::atan(dfact1 / (nir - red)); } - if (std::abs(green - red) < EpsilonToBeConsideredAsZero) + if (std::abs(green - red) < RadiometricIndice<TInput,TOutput>::Epsilon) { dterm2 = 0; } @@ -430,7 +430,7 @@ class ARVI : public RadiometricIndice<TInput,TOutput> { public: - ARVI(): RadiometricIndice<TInput,TOutput>("ARVI",{CommonBandNames::BLUE, CommonBandNames::RED, CommonBandNames::NIR}) {} + ARVI(): RadiometricIndice<TInput,TOutput>({CommonBandNames::BLUE, CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { @@ -440,7 +440,7 @@ public: double RHOrb = red - Gamma * (blue - red); double denominator = nir + RHOrb; - if (std::abs(denominator) < EpsilonToBeConsideredAsZero) + if (std::abs(denominator) < RadiometricIndice<TInput,TOutput>::Epsilon) { return static_cast<TOutput>(0.); } @@ -466,7 +466,7 @@ class TSARVI : public RadiometricIndice<TInput,TOutput> { public: - TSARVI() : RadiometricIndice<TInput,TOutput>("TSARVI",{CommonBandNames::BLUE, CommonBandNames::RED, CommonBandNames::NIR}) {} + TSARVI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::BLUE, CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { @@ -476,7 +476,7 @@ public: double dRB = red - Gamma * (blue - red); double denominator = dRB + A * nir - A * B + X * (1. + A * A); - if (std::abs(denominator) < EpsilonToBeConsideredAsZero) + if (std::abs(denominator) < RadiometricIndice<TInput,TOutput>::Epsilon) { return static_cast<TOutput>(0.); } @@ -510,7 +510,7 @@ class EVI : public RadiometricIndice<TInput,TOutput> { public: - EVI() : RadiometricIndice<TInput,TOutput>("EVI",{CommonBandNames::BLUE, CommonBandNames::RED, CommonBandNames::NIR}) {} + EVI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::BLUE, CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { @@ -519,7 +519,7 @@ public: auto nir = this->Value(CommonBandNames::NIR,input); double denominator = nir + C1 * red - C2 * blue + L; - if (std::abs(denominator) < EpsilonToBeConsideredAsZero) + if (std::abs(denominator) < RadiometricIndice<TInput,TOutput>::Epsilon) { return (static_cast<TOutput>(0.)); } @@ -553,14 +553,14 @@ template <class TInput, class TOutput> class IPVI : public RadiometricIndice<TInput,TOutput> { public: - IPVI() : RadiometricIndice<TInput,TOutput>("IPVI",{CommonBandNames::RED, CommonBandNames::NIR}) {} + IPVI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { auto red = this->Value(CommonBandNames::RED,input); auto nir = this->Value(CommonBandNames::NIR,input); - if (std::abs(nir + red) < EpsilonToBeConsideredAsZero) + if (std::abs(nir + red) < RadiometricIndice<TInput,TOutput>::Epsilon) { return static_cast<TOutput>(0.); } @@ -585,7 +585,7 @@ template <class TInput, class TOutput> class TNDVI : public RadiometricIndice<TInput,TOutput> { public: - TNDVI() : RadiometricIndice<TInput,TOutput>("TNDVI",{CommonBandNames::RED, CommonBandNames::NIR}) {} + TNDVI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { @@ -625,7 +625,7 @@ template <class TInput, class TOutput> class LAIFromNDVILogarithmic : public RadiometricIndice<TInput,TOutput> { public: - LAIFromNDVILogarithmic() : RadiometricIndice<TInput,TOutput>("LAIFromNDVILogarithmic",{CommonBandNames::RED, CommonBandNames::NIR}), + LAIFromNDVILogarithmic() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}), m_NdviSoil(0.1), m_NdviInf(0.89), m_ExtinctionCoefficient(0.71) {} @@ -707,7 +707,7 @@ class LAIFromReflectancesLinear : public RadiometricIndice<TInput,TOutput> public: - LAIFromReflectancesLinear() : RadiometricIndice<TInput,TOutput>("LAIFromReflectanceLinear",{CommonBandNames::RED, CommonBandNames::NIR}), + LAIFromReflectancesLinear() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}), m_RedCoef(-17.91), m_NirCoef(12.26) {} @@ -768,14 +768,14 @@ public: { public: - LAIFromNDVIFormosat2Functor(): RadiometricIndice<TInput,TOutput>("LAIFromNDVIFormosat2",{CommonBandNames::RED, CommonBandNames::NIR}) {} + LAIFromNDVIFormosat2Functor(): RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::NIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { auto red = this->Value(CommonBandNames::RED,input); auto nir = this->Value(CommonBandNames::NIR,input); - if (std::abs(nir + red) < EpsilonToBeConsideredAsZero) + if (std::abs(nir + red) < RadiometricIndice<TInput,TOutput>::Epsilon) { return static_cast<TOutput>(0.); } diff --git a/Modules/Radiometry/Indices/include/otbWaterIndicesFunctor.h b/Modules/Radiometry/Indices/include/otbWaterIndicesFunctor.h index efd780d91a1425195a76e2fcaae5f87ce80b20c1..7d94f9525014eacef5dabd5475b46dcb56e60bcb 100644 --- a/Modules/Radiometry/Indices/include/otbWaterIndicesFunctor.h +++ b/Modules/Radiometry/Indices/include/otbWaterIndicesFunctor.h @@ -45,13 +45,13 @@ class SRWI : public RadiometricIndice<TInput,TOutput,ModisBandNames> { public: - SRWI() : RadiometricIndice<TInput,TOutput>("SRWI",{ModisBandNames::M860, ModisBandNames::M1240}) {} + SRWI() : RadiometricIndice<TInput,TOutput>({ModisBandNames::M860, ModisBandNames::M1240}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { double rho860 = this->Value(ModisBandNames::M860,input); double rho1240 = this->Value(ModisBandNames::M1240,input); - if (std::abs(rho1240) < EpsilonToBeConsideredAsZero) + if (std::abs(rho1240) < RadiometricIndice<TInput,TOutput>::Epsilon) { return static_cast<TOutput>(0.); } @@ -78,14 +78,14 @@ class NDWI : public RadiometricIndice<TInput,TOutput> { public: - NDWI(): RadiometricIndice<TInput,TOutput>("NDWI",{CommonBandNames::NIR, CommonBandNames::MIR}) {} + NDWI(): RadiometricIndice<TInput,TOutput>({CommonBandNames::NIR, CommonBandNames::MIR}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { auto mir = this->Value(CommonBandNames::MIR,input); auto nir = this->Value(CommonBandNames::NIR,input); - if (std::abs(nir + mir) < EpsilonToBeConsideredAsZero) + if (std::abs(nir + mir) < RadiometricIndice<TInput,TOutput>::Epsilon) { return 0.; } @@ -109,14 +109,14 @@ class NDWI2 : public RadiometricIndice<TInput,TOutput> { public: - NDWI2() : RadiometricIndice<TInput,TOutput>("NDWI2",{CommonBandNames::NIR, CommonBandNames::GREEN}) {} + NDWI2() : RadiometricIndice<TInput,TOutput>({CommonBandNames::NIR, CommonBandNames::GREEN}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { auto green = this->Value(CommonBandNames::GREEN,input); auto nir = this->Value(CommonBandNames::NIR,input); - if (std::abs(nir + green) < EpsilonToBeConsideredAsZero) + if (std::abs(nir + green) < RadiometricIndice<TInput,TOutput>::Epsilon) { return 0.; } @@ -139,14 +139,14 @@ template <class TInput, class TOutput> class MNDWI : public RadiometricIndice<TInput,TOutput> { public: - MNDWI() : RadiometricIndice<TInput,TOutput>("MNDWI",{CommonBandNames::MIR, CommonBandNames::GREEN}) {} + MNDWI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::MIR, CommonBandNames::GREEN}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { auto green = this->Value(CommonBandNames::GREEN,input); auto mir = this->Value(CommonBandNames::MIR,input); - if (std::abs(mir + green) < EpsilonToBeConsideredAsZero) + if (std::abs(mir + green) < RadiometricIndice<TInput,TOutput>::Epsilon) { return 0.; } @@ -169,14 +169,14 @@ template <class TInput, class TOutput> class NDPI : public RadiometricIndice<TInput,TOutput> { public: - NDPI() : RadiometricIndice<TInput,TOutput>("NDPI",{CommonBandNames::MIR, CommonBandNames::GREEN}) {} + NDPI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::MIR, CommonBandNames::GREEN}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { auto green = this->Value(CommonBandNames::GREEN,input); auto mir = this->Value(CommonBandNames::MIR,input); - if (std::abs(mir + green) < EpsilonToBeConsideredAsZero) + if (std::abs(mir + green) < RadiometricIndice<TInput,TOutput>::Epsilon) { return 0.; } @@ -200,14 +200,14 @@ class NDTI : public RadiometricIndice<TInput,TOutput> { public: - NDTI() : RadiometricIndice<TInput,TOutput>("NDPI",{CommonBandNames::RED, CommonBandNames::GREEN}) {} + NDTI() : RadiometricIndice<TInput,TOutput>({CommonBandNames::RED, CommonBandNames::GREEN}) {} TOutput operator()(const itk::VariableLengthVector<TInput> & input) const override { auto green = this->Value(CommonBandNames::GREEN,input); auto red = this->Value(CommonBandNames::RED,input); - if (std::abs(red + green) < EpsilonToBeConsideredAsZero) + if (std::abs(red + green) < RadiometricIndice<TInput,TOutput>::Epsilon) { return 0.; }