diff --git a/Code/Radiometry/otbVegetationIndex.h b/Code/Radiometry/otbVegetationIndex.h index 2dc621a2800f5e74e4fc286a8363fc7058fb5559..9304da4f3a9db43063f2c0484fbed068bd609175 100644 --- a/Code/Radiometry/otbVegetationIndex.h +++ b/Code/Radiometry/otbVegetationIndex.h @@ -256,7 +256,7 @@ public: * * This vegetation index use three inputs channels * - * [Yoram J. Kaufman and Didier Tanré, 1992] + * [Yoram J. Kaufman and Didier Tanr�, 1992] * * \ingroup Functor */ @@ -295,6 +295,85 @@ private: double m_Gamma; }; +/** \class EVI + * \brief This functor calculate the Enhanced Vegetation Index (EVI) + * + * This vegetation index use three inputs channels + * + * [Huete, Justice, & Liu, 1994; Huete, Liu, Batchily, & van Leeuwen, 1997] + * + * \ingroup Functor + */ +template <class TInput1, class TInput2, class TInput3, class TOutput> +class EVI +{ +public: + EVI() : m_G(2.5), m_C1(6.0), m_C2(7.5), m_L(1.0) {}; + ~EVI() {}; + inline TOutput operator()(const TInput1 &r, const TInput2 &b, const TInput3 &nir) + { + double dr = static_cast<double>(r); + double db = static_cast<double>(b); + double dnir = static_cast<double>(nir); + double denominator = dnir + m_C1*dr - m_C2*db + m_L; + if ( denominator == 0. ) + { + return static_cast<TOutput>(0.); + } + return ( static_cast<TOutput>( m_G * (dnir - dr)/denominator ) ); + } + /** Set/Get G parameter */ + void SetG(const double g) + { + m_G = g; + } + double GetG(void)const + { + return (m_G); + } + /** Set/Get C1 parameter */ + void SetC1(const double c1) + { + m_C1 = c1; + } + double GetC1(void)const + { + return (m_C1); + } + /** Set/Get C2 parameter */ + void SetC2(const double c2) + { + m_C2 = c2; + } + double GetC2(void)const + { + return (m_C2); + } + /** Set/Get L parameter */ + void SetL(const double l) + { + m_L = l; + } + double GetL(void)const + { + return (m_L); + } + +private: + + /** Gain factor */ + double m_G; + + /** Coefficient of the aerosol resistance term */ + double m_C1; + + /** Coefficient of the aerosol resistance term */ + double m_C2; + + /** Canopy background adjustment */ + double m_L; +}; + } // namespace Functor } // namespace otb diff --git a/Testing/Code/Radiometry/CMakeLists.txt b/Testing/Code/Radiometry/CMakeLists.txt index ecfe15907588ff63b0c33722f439ffba310c14b9..b49d17bd43ca3ba338b71f3ec09ace193297a47c 100644 --- a/Testing/Code/Radiometry/CMakeLists.txt +++ b/Testing/Code/Radiometry/CMakeLists.txt @@ -487,6 +487,40 @@ ADD_TEST(raTvAtmosphericCorrectionSequencementTest ${RADIOMETRY_TESTS4} ) +# ------- otb::RAndBAndNIRVegetationIndexImageFilter ------------------------------ +ADD_TEST(raTvEVIRAndBAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS4} + #--compare-image ${EPSILON} ${BASELINE}/raRAndBAndNIRVegetationIndex_EVI_poupees_subc1c2c3.tif + # ${TEMP}/raRAndBAndNIRVegetationIndex_EVI_poupees_subc1c2c3.tif + otbEVIRAndBAndNIRVegetationIndexImageFilter + EVI + ${INPUTDATA}/poupees_sub_c1.png + ${INPUTDATA}/poupees_sub_c2.png + ${INPUTDATA}/poupees_sub_c3.png + ${TEMP}/raRAndBAndNIRVegetationIndex_EVI_poupees_subc1c2c3.tif + 2.5 + 6.0 + 7.5 + 1.0 +) + +# ------- otb::MultiChannelRAndBAndNIRVegetationIndexImageFilter ------------------------------ +ADD_TEST(raTvEVIMultiChannelRAndBAndNIRVegetationIndexImageFilter ${RADIOMETRY_TESTS4} + #--compare-image ${EPSILON} ${BASELINE}/raRAndBAndNIRVegetationIndex_EVI_poupees_subc1c2c3.tif + # ${TEMP}/raRAndBAndNIRVegetationIndex_EVI_poupees_subc1c2c3.tif + otbEVIMultiChannelRAndBAndNIRVegetationIndexImageFilter + EVI + ${INPUTDATA}/qb_RoadExtract.img.hdr + ${TEMP}/raRAndBAndNIRVegetationIndex_EVI_qb_RoadExtract.tif + 3 # red + 1 # blue + 4 # nir + 2.5 # gain factor + 6.0 # coefficient of the aerosol resistance term + 7.5 # coefficient of the aerosol resistance term + 1.0 # canopy background adjustment +) + + # A enrichir SET(Radiometry_SRCS1 @@ -526,6 +560,8 @@ SET(Radiometry_SRCS4 otbAtmosphericCorrectionParametersTo6SAtmosphericRadiativeTermsNew.cxx otbAtmosphericCorrectionParametersTo6SAtmosphericRadiativeTerms.cxx otbAtmosphericCorrectionSequencement.cxx +otbEVIRAndBAndNIRVegetationIndexImageFilter.cxx +otbEVIMultiChannelRAndBAndNIRVegetationIndexImageFilter.cxx ) INCLUDE_DIRECTORIES("${OTBTesting_BINARY_DIR}") diff --git a/Testing/Code/Radiometry/otbEVIMultiChannelRAndBAndNIRVegetationIndexImageFilter.cxx b/Testing/Code/Radiometry/otbEVIMultiChannelRAndBAndNIRVegetationIndexImageFilter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..bd3d6503c45b9fa0d68c939a7d0857ce6c5593f9 --- /dev/null +++ b/Testing/Code/Radiometry/otbEVIMultiChannelRAndBAndNIRVegetationIndexImageFilter.cxx @@ -0,0 +1,89 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "itkExceptionObject.h" + +#include "otbMultiChannelRAndBAndNIRVegetationIndexImageFilter.h" +#include "otbImage.h" +#include "otbVectorImage.h" +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" +#include "otbVegetationIndex.h" + + +template<class TInputImage, class TOutputImage, class TFunction> +int generic_EVIMultiChannelRAndBAndNIRVegetationIndexImageFilter(int argc, char * argv[]) +{ + typedef otb::ImageFileReader<TInputImage> ReaderType; + typedef otb::ImageFileWriter<TOutputImage> WriterType; + + typedef otb::MultiChannelRAndBAndNIRVegetationIndexImageFilter<TInputImage,TOutputImage,TFunction> + MultiChannelRAndBAndNIRVegetationIndexImageFilterType; + + // Instantiating object + typename MultiChannelRAndBAndNIRVegetationIndexImageFilterType::Pointer filter = MultiChannelRAndBAndNIRVegetationIndexImageFilterType::New(); + typename ReaderType::Pointer reader = ReaderType::New(); + typename WriterType::Pointer writer = WriterType::New(); + + const char * inputFilename = argv[1]; + const char * outputFilename = argv[2]; + + unsigned int redChannel(::atoi(argv[3])); + unsigned int blueChannel(::atoi(argv[4])); + unsigned int nirChannel(::atoi(argv[5])); + + double g(::atof(argv[6])); + double c1(::atof(argv[7])); + double c2(::atof(argv[8])); + double l(::atof(argv[9])); + + reader->SetFileName( inputFilename ); + writer->SetFileName( outputFilename ); + filter->SetRedIndex(redChannel); + filter->SetBlueIndex(blueChannel); + filter->SetNIRIndex(nirChannel); + filter->SetInput( reader->GetOutput() ); + filter->GetFunctor().SetG(g); + filter->GetFunctor().SetC1(c1); + filter->GetFunctor().SetC2(c2); + filter->GetFunctor().SetL(l); + + writer->SetInput( filter->GetOutput() ); + writer->Update(); + + return EXIT_SUCCESS; +} + +int otbEVIMultiChannelRAndBAndNIRVegetationIndexImageFilter(int argc, char * argv[]) +{ + const unsigned int Dimension = 2; + typedef otb::VectorImage<double ,Dimension> InputImageType; + typedef otb::Image<double,Dimension> OutputImageType; + + std::string strArgv(argv[1]); + argc--; + argv++; + if ( strArgv == "EVI" ) return( generic_EVIMultiChannelRAndBAndNIRVegetationIndexImageFilter<InputImageType, OutputImageType, + otb::Functor::EVI< InputImageType::InternalPixelType, + InputImageType::InternalPixelType, + InputImageType::InternalPixelType, + OutputImageType::PixelType> > + (argc,argv) ); + else + return EXIT_FAILURE; + return EXIT_SUCCESS; +} diff --git a/Testing/Code/Radiometry/otbEVIRAndBAndNIRVegetationIndexImageFilter.cxx b/Testing/Code/Radiometry/otbEVIRAndBAndNIRVegetationIndexImageFilter.cxx new file mode 100644 index 0000000000000000000000000000000000000000..3ba53fa6da3ab02166a6821be4917023638fb6a4 --- /dev/null +++ b/Testing/Code/Radiometry/otbEVIRAndBAndNIRVegetationIndexImageFilter.cxx @@ -0,0 +1,94 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + + This software is distributed WITHOUT ANY WARRANTY; without even + the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR + PURPOSE. See the above copyright notices for more information. + +=========================================================================*/ +#include "itkExceptionObject.h" + +#include "otbRAndBAndNIRVegetationIndexImageFilter.h" +#include "otbImage.h" +#include "otbImageFileReader.h" +#include "otbImageFileWriter.h" +#include "otbVegetationIndex.h" + + +template<class TInputRImage, class TInputBImage, class TInputNIRImage, class TOutputImage, class TFunction> +int generic_EVIRAndBAndNIRVegetationIndexImageFilter(int argc, char * argv[]) +{ + typedef otb::ImageFileReader<TInputRImage> RReaderType; + typedef otb::ImageFileReader<TInputBImage> BReaderType; + typedef otb::ImageFileReader<TInputNIRImage> NIRReaderType; + typedef otb::ImageFileWriter<TOutputImage> WriterType; + + typedef otb::RAndBAndNIRVegetationIndexImageFilter<TInputRImage,TInputBImage,TInputNIRImage,TOutputImage,TFunction> + RAndBAndNIRVegetationIndexImageFilterType; + + // Instantiating object + typename RAndBAndNIRVegetationIndexImageFilterType::Pointer filter = RAndBAndNIRVegetationIndexImageFilterType::New(); + typename RReaderType::Pointer readerR = RReaderType::New(); + typename BReaderType::Pointer readerB = BReaderType::New(); + typename NIRReaderType::Pointer readerNIR = NIRReaderType::New(); + typename WriterType::Pointer writer = WriterType::New(); + + const char * inputFilenameR = argv[1]; + const char * inputFilenameB = argv[2]; + const char * inputFilenameNIR = argv[3]; + const char * outputFilename = argv[4]; + double g(::atof(argv[5])); + double c1(::atof(argv[6])); + double c2(::atof(argv[7])); + double l(::atof(argv[8])); + + readerR->SetFileName( inputFilenameR ); + readerB->SetFileName( inputFilenameB ); + readerNIR->SetFileName( inputFilenameNIR ); + writer->SetFileName( outputFilename ); + filter->SetInputR( readerR->GetOutput() ); + filter->SetInputB( readerB->GetOutput() ); + filter->SetInputNIR( readerNIR->GetOutput() ); + + filter->GetFunctor().SetG(g); + filter->GetFunctor().SetC1(c1); + filter->GetFunctor().SetC2(c2); + filter->GetFunctor().SetL(l); + + writer->SetInput( filter->GetOutput() ); + writer->Update(); + + return EXIT_SUCCESS; +} + +int otbEVIRAndBAndNIRVegetationIndexImageFilter(int argc, char * argv[]) +{ + const unsigned int Dimension = 2; + typedef double PixelType; + typedef otb::Image<PixelType,Dimension> InputRImageType; + typedef otb::Image<PixelType,Dimension> InputBImageType; + typedef otb::Image<PixelType,Dimension> InputNIRImageType; + typedef otb::Image<double,Dimension> OutputImageType; + + std::string strArgv(argv[1]); + argc--; + argv++; + if ( strArgv == "EVI" ) return( generic_EVIRAndBAndNIRVegetationIndexImageFilter<InputRImageType, InputBImageType, InputNIRImageType, OutputImageType, + otb::Functor::EVI< InputRImageType::PixelType, + InputBImageType::PixelType, + InputNIRImageType::PixelType, + OutputImageType::PixelType> > + (argc,argv) ); + else + return EXIT_FAILURE; + return EXIT_SUCCESS; +} diff --git a/Testing/Code/Radiometry/otbRadiometryTests4.cxx b/Testing/Code/Radiometry/otbRadiometryTests4.cxx index 82be2c33f926e90d6a9771eae694b85875f0d6ea..c51fb1b5a29a17e11848460b77f322886111d710 100644 --- a/Testing/Code/Radiometry/otbRadiometryTests4.cxx +++ b/Testing/Code/Radiometry/otbRadiometryTests4.cxx @@ -30,5 +30,7 @@ void RegisterTests() REGISTER_TEST(otbAtmosphericCorrectionParametersTo6SAtmosphericRadiativeTermsNew); REGISTER_TEST(otbAtmosphericCorrectionParametersTo6SAtmosphericRadiativeTerms); REGISTER_TEST(otbAtmosphericCorrectionSequencementTest); + REGISTER_TEST(otbEVIRAndBAndNIRVegetationIndexImageFilter); + REGISTER_TEST(otbEVIMultiChannelRAndBAndNIRVegetationIndexImageFilter); }