diff --git a/Code/CMakeLists.txt b/Code/CMakeLists.txt index fb4bf611d89ad61cb3eb9e36f9ac0e3decf2ec9e..5af30b3d21eb2f5c313b18f4d2bf39f2c32e6482 100644 --- a/Code/CMakeLists.txt +++ b/Code/CMakeLists.txt @@ -15,6 +15,9 @@ ADD_SUBDIRECTORY(SARPolarimetry) ADD_SUBDIRECTORY(Testing) ADD_SUBDIRECTORY(OBIA) ADD_SUBDIRECTORY(ObjectDetection) +ADD_SUBDIRECTORY(MultiTemporal) + + IF(OTB_USE_VISU_GUI) ADD_SUBDIRECTORY(Visu) diff --git a/Code/Learning/otbDecisionTree.h b/Code/Learning/otbDecisionTree.h new file mode 100644 index 0000000000000000000000000000000000000000..24cb490ac22a972f78aaa3540ab1c0ba01a563a7 --- /dev/null +++ b/Code/Learning/otbDecisionTree.h @@ -0,0 +1,130 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + Copyright (c) Institut Telecom; Telecom bretagne. All rights reserved. + See ITCopyright.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. + +=========================================================================*/ +#ifndef __otbDecisionTree_h +#define __otbDecisionTree_h + +#include <map> +#include "itkObjectFactory.h" +#include "itkDataObject.h" + +namespace otb +{ + +/** + * \class DecisionTree + * \brief Models a decision tree + * + * A decision tree holds an attribute that is being tested and 2 + * maps (STL): one for subtrees and anoter for labels (for the case + * where there are no subtrees). These maps as keys a pair (STL) which + * holds the value of the attribute being tested as well as the type + * of test (LT, LE, EQ, GE, GT). + * + * In order to build a tree, one uses the method AddBranch. There are + * 2 versions of this method: one for adding a subtree, and another + * for adding labels in the case of leaf nodes. Each of these versions + * has a syntactic sugar version for the case of EQ test. + * + * This implementation does not use different classes for terminal and + * non terminal nodes for simplicity and follows the implementation + * suggested by P. Norvig in the python version of the AIMA code which + * is available at + * http://aima-python.googlecode.com/svn/trunk/learning.py + * + * In the case of several terminal nodes being eligible, the first is returned. + * + * \sa DecisionTreeClassifier + * \sa DecisionTreeEstimator + */ + +template <class AttributeValueType, class LabelType> +class ITK_EXPORT DecisionTree : public itk::DataObject +{ +public: + + enum DecisionTreeTestType { MIN, LT=MIN, LE, EQ, GE, GT, MAX=GT}; + /** Standard typedefs */ + typedef DecisionTree Self; + typedef itk::DataObject Superclass; + typedef itk::SmartPointer<Self> Pointer; + typedef itk::SmartPointer<const Self> ConstPointer; + + /** Creation through object factory macro */ + itkNewMacro(Self); + /** Runtime informations macro */ + itkTypeMacro(DecisionTree, DataObject); + + typedef typename std::pair< AttributeValueType, DecisionTreeTestType > KeyType; + typedef typename std::map< KeyType, Pointer > TreeMapType; + typedef typename std::map< KeyType, LabelType > LabelMapType; + typedef std::vector<AttributeValueType> ExampleType; + + itkSetMacro(Attribute, unsigned int); + itkGetMacro(Attribute, unsigned int); + + /** Add a subtree on the tested attribute*/ + void AddBranch(AttributeValueType attr, DecisionTreeTestType testType, Pointer branch); + /** Add a subtree on the tested attribute - syntactic sugar for the + EQ case*/ + void AddBranch(AttributeValueType attr, Pointer branch); + + /** Add a leaf node on the tested attribute*/ + void AddBranch(AttributeValueType attr, DecisionTreeTestType testType, LabelType label); + /** Add a leaf node on the tested attribute - syntactic sugar for the + EQ case*/ + void AddBranch(AttributeValueType attr, LabelType label); + + LabelType Decide(const ExampleType example); + +protected: + /** Constructor */ + DecisionTree(); + /** Destructor */ + virtual ~DecisionTree(); + /** Output information redefinition */ + + /** PrintSelf method */ + void PrintSelf(std::ostream& os, itk::Indent indent) const; + +private: + DecisionTree(const Self &); // purposely not implemented + void operator =(const Self&); // purposely not implemented + + /** Map holding the subtrees */ + TreeMapType* m_TreeMap; + /** Map holding the labels if final node */ + LabelMapType m_LabelMap; + /** The attribute number (in the vector) being tested */ + unsigned int m_Attribute; + + /** Is the tree a final node? */ + bool m_IsFinal; + + LabelType m_Label; + + +}; +} // end namespace otb + +#ifndef OTB_MANUAL_INSTANTIATION +#include "otbDecisionTree.txx" +#endif + +#endif diff --git a/Code/Learning/otbDecisionTree.txx b/Code/Learning/otbDecisionTree.txx new file mode 100644 index 0000000000000000000000000000000000000000..665a25ed9cf6af5d1ae4aa595253ddaa8dda3193 --- /dev/null +++ b/Code/Learning/otbDecisionTree.txx @@ -0,0 +1,226 @@ +/*========================================================================= + + Program: ORFEO Toolbox + Language: C++ + Date: $Date$ + Version: $Revision$ + + + Copyright (c) Centre National d'Etudes Spatiales. All rights reserved. + See OTBCopyright.txt for details. + + Copyright (c) Institut Telecom; Telecom bretagne. All rights reserved. + See ITCopyright.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. + +=========================================================================*/ +#ifndef __otbDecisionTree_txx +#define __otbDecisionTree_txx + +#include "otbDecisionTree.h" +#include "otbMacro.h" +#include "itkNumericTraits.h" + +namespace otb +{ +/** + * Constructor + */ +template <class AttributeValueType, class LabelType> +DecisionTree<AttributeValueType, LabelType> +::DecisionTree() +{ + m_TreeMap = new TreeMapType; + m_IsFinal = true; + m_Label = static_cast<LabelType>(0); +} +/** + * Destructor + */ +template <class AttributeValueType, class LabelType> +DecisionTree<AttributeValueType, LabelType> +::~DecisionTree() +{ + delete m_TreeMap; +} + +template <class AttributeValueType, class LabelType> +void +DecisionTree<AttributeValueType, LabelType> +::AddBranch(AttributeValueType attr, DecisionTreeTestType testType, Pointer branch) +{ + m_IsFinal = false; + KeyType key = KeyType(attr, testType); + (*m_TreeMap)[key] = branch; +} + +template <class AttributeValueType, class LabelType> +void +DecisionTree<AttributeValueType, LabelType> +::AddBranch(AttributeValueType attr, Pointer branch) +{ + m_IsFinal = false; + KeyType key = KeyType(attr, EQ); + (*m_TreeMap)[key] = branch; +} + +template <class AttributeValueType, class LabelType> +void +DecisionTree<AttributeValueType, LabelType> +::AddBranch(AttributeValueType attr, DecisionTreeTestType testType, LabelType label) +{ + m_IsFinal = true; + KeyType key = KeyType(attr, testType); + m_LabelMap[key] = label; +} + +template <class AttributeValueType, class LabelType> +void +DecisionTree<AttributeValueType, LabelType> +::AddBranch(AttributeValueType attr, LabelType label) +{ + m_IsFinal = true; + KeyType key = KeyType(attr, EQ); + m_LabelMap[key] = label; +} + +template <class AttributeValueType, class LabelType> +LabelType +DecisionTree<AttributeValueType, LabelType> +::Decide(const ExampleType example) +{ + AttributeValueType attrValue = example[m_Attribute]; + + std::cout << "Trying to match attribute " << m_Attribute << " with value " << attrValue << std::endl; + + bool found = false; + KeyType key; + if( m_IsFinal ) + { + typename LabelMapType::const_iterator lmIt = m_LabelMap.begin(); + while( lmIt != m_LabelMap.end() ) + { + KeyType theKey = lmIt->first; + DecisionTreeTestType theTest = theKey.second; + AttributeValueType theValue = theKey.first; + switch( theTest ) + { + case LT: + if( attrValue < theValue ) + return lmIt->second; + break; + case LE: + if( attrValue <= theValue ) + return lmIt->second; + break; + case EQ: + if( attrValue == theValue ) + return lmIt->second; + break; + case GE: + if( attrValue >= theValue ) + return lmIt->second; + break; + case GT: + if( attrValue > theValue ) + return lmIt->second; + break; + } + ++lmIt; + } + + // if we get here it means that a verified test was not found + itkGenericExceptionMacro(<< "Example could not be handled by decision tree."); + + } + else + { + found = false; + + // Look for branches matching the test on the attribute + std::vector< KeyType > candidateKeys; + + typename TreeMapType::const_iterator tmIt = m_TreeMap->begin(); + while( tmIt != m_TreeMap->end() ) + { + KeyType theKey = tmIt->first; + DecisionTreeTestType theTest = theKey.second; + AttributeValueType theValue = theKey.first; + switch( theTest ) + { + case LT: + if( attrValue < theValue ) + { + candidateKeys.push_back( theKey ); + found = true; + } + break; + case LE: + if( attrValue <= theValue ) + { + candidateKeys.push_back( theKey ); + found = true; + } + break; + case EQ: + if( attrValue == theValue ) + { + candidateKeys.push_back( theKey ); + found = true; + } + break; + case GE: + if( attrValue >= theValue ) + { + candidateKeys.push_back( theKey ); + found = true; + } + break; + case GT: + if( attrValue > theValue ) + { + candidateKeys.push_back( theKey ); + found = true; + } + break; + } + ++tmIt; + } + + if( ! found ) // attribute + // not found + // in the map + itkGenericExceptionMacro(<< "Example could not be handled by decision tree."); + + // If we found one or several matching tests + typename std::vector< KeyType >::const_iterator ckIt = candidateKeys.begin(); + while ( ckIt != candidateKeys.end() ) + { + std::cout << (*ckIt).first << " " << (*ckIt).second << std::endl; + Pointer child = (*m_TreeMap)[(*ckIt)]; + return child->Decide(example); + } + + } + +} + + +/** + *PrintSelf method + */ +template <class AttributeValueType, class LabelType> +void +DecisionTree<AttributeValueType, LabelType> +::PrintSelf(std::ostream& os, itk::Indent indent) const +{ + Superclass::PrintSelf(os, indent); +} + +} // end namespace otb + +#endif diff --git a/Code/MultiTemporal/CMakeLists.txt b/Code/MultiTemporal/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..3835f6e6e3f3fc46dc7e90c7e6e3ed083135d829 --- /dev/null +++ b/Code/MultiTemporal/CMakeLists.txt @@ -0,0 +1,24 @@ +# Sources of non-templated classes. + +FILE(GLOB OTBMultiTemporal_SRCS "*.cxx" ) + +ADD_LIBRARY(OTBMultiTemporal ${OTBMultiTemporal_SRCS}) +TARGET_LINK_LIBRARIES (OTBMultiTemporal OTBCommon ITKStatistics) +IF(OTB_LIBRARY_PROPERTIES) + SET_TARGET_PROPERTIES(OTBMultiTemporal PROPERTIES ${OTB_LIBRARY_PROPERTIES}) +ENDIF(OTB_LIBRARY_PROPERTIES) + +IF(NOT OTB_INSTALL_NO_LIBRARIES) + INSTALL(TARGETS OTBMultiTemporal + RUNTIME DESTINATION ${OTB_INSTALL_BIN_DIR_CM24} COMPONENT RuntimeLibraries + LIBRARY DESTINATION ${OTB_INSTALL_LIB_DIR_CM24} COMPONENT RuntimeLibraries + ARCHIVE DESTINATION ${OTB_INSTALL_LIB_DIR_CM24} COMPONENT Development) +ENDIF(NOT OTB_INSTALL_NO_LIBRARIES) + +IF(NOT OTB_INSTALL_NO_DEVELOPMENT) + FILE(GLOB __files1 "${CMAKE_CURRENT_SOURCE_DIR}/*.h") + FILE(GLOB __files2 "${CMAKE_CURRENT_SOURCE_DIR}/*.txx") + INSTALL(FILES ${__files1} ${__files2} + DESTINATION ${OTB_INSTALL_INCLUDE_DIR_CM24}/MultiTemporal + COMPONENT Development) +ENDIF(NOT OTB_INSTALL_NO_DEVELOPMENT) diff --git a/Code/MultiTemporal/foo.cxx b/Code/MultiTemporal/foo.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391 diff --git a/Code/Radiometry/otbVegetationIndicesFunctor.h b/Code/Radiometry/otbVegetationIndicesFunctor.h index 04951bd427c6b04e36b70c198235495f510fad6b..e4ad81cb75a9292615ee00f234f909c025987d57 100644 --- a/Code/Radiometry/otbVegetationIndicesFunctor.h +++ b/Code/Radiometry/otbVegetationIndicesFunctor.h @@ -1237,6 +1237,149 @@ private: const NDVIFunctorType m_NDVIfunctor; }; +/** \class LAIFromNDVILogarithmic + * This functor computes the LAI from NDVI using a + * logarithmic relationship. Asrar et al. (1984), Baret and Guyot + * (1991) and Wilson and Meyers (2007). Default values for the + * parameters are taken from A. Bsaibes et al. / Remote Sensing of + * Environment 113 (2009) 716–729 + * + * + * \ingroup Functor + * \ingroup Radiometry + * \ingroup VegetationIndices + */ +template <class TInput1, class TInput2, class TOutput> +class LAIFromNDVILogarithmic : public RAndNIRIndexBase<TInput1, TInput2, TOutput> +{ +public: + /** Return the index name */ + virtual std::string GetName() const + { + return "LAIFromNDVILogarithmic"; + } + + typedef NDVI<TInput1, TInput2, TOutput> NDVIFunctorType; + LAIFromNDVILogarithmic() : m_NdviSoil(0.10), m_NdviInf(0.89), m_ExtinctionCoefficient(0.71) {} + virtual ~LAIFromNDVILogarithmic() {} + + NDVIFunctorType GetNDVI(void) const + { + return (m_NDVIfunctor); + } + + void SetNdviSoil(const double val) + { + m_NdviSoil = val; + } + double GetNdviSoil(void) const + { + return (m_NdviSoil); + } + + void SetNdviInf(const double val) + { + m_NdviInf = val; + } + double GetNdviInf(void) const + { + return (m_NdviInf); + } + + void SetExtinctionCoefficient(const double val) + { + m_ExtinctionCoefficient = val; + } + double GetExtinctionCoefficient(void) const + { + return (m_ExtinctionCoefficient); + } + +protected: + inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const + { + double dval = this->GetNDVI() (r, nir); + if (dval < 0) + { + return (static_cast<TOutput>(0)); + } + else + { + return (static_cast<TOutput>( + -(1.0/m_ExtinctionCoefficient)*vcl_log((dval- m_NdviInf)/(m_NdviSoil-m_NdviInf)) + )); + } + } +private: + const NDVIFunctorType m_NDVIfunctor; + double m_NdviSoil; + double m_NdviInf; + double m_ExtinctionCoefficient; +}; + + +/** \class LAIFromReflectancesLinear + * This functor computes the LAI from reflectances using a + * linear relationship. + * LAI = \beta_0 + \sum_j \beta_j \rho_j where \rho are the + * reflectances + * Default values for the parameters are taken from A. Bsaibes et + * al. / Remote Sensing of Environment 113 (2009) 716–729 + * + * + * \ingroup Functor + * \ingroup Radiometry + * \ingroup VegetationIndices + */ +template <class TInput1, class TInput2, class TOutput> +class LAIFromReflectancesLinear : public RAndNIRIndexBase<TInput1, TInput2, TOutput> +{ +public: + /** Return the index name */ + virtual std::string GetName() const + { + return "LAIFromReflectancesLinear"; + } + + typedef NDVI<TInput1, TInput2, TOutput> NDVIFunctorType; + LAIFromReflectancesLinear() : m_RedCoef(-17.91), m_NirCoef(12.26) {} + virtual ~LAIFromReflectancesLinear() {} + + NDVIFunctorType GetReflectances(void) const + { + return (m_NDVIfunctor); + } + + void SetRedCoef(const double val) + { + m_RedCoef = val; + } + double GetRedCoef(void) const + { + return (m_RedCoef); + } + + void SetNirCoef(const double val) + { + m_NirCoef = val; + } + double GetNirCoef(void) const + { + return (m_NirCoef); + } + +protected: + inline TOutput Evaluate(const TInput1& r, const TInput2& nir) const + { + return (static_cast<TOutput>(m_RedCoef*r+m_NirCoef*nir)); + } +private: + const NDVIFunctorType m_NDVIfunctor; + double m_RedCoef; + double m_NirCoef; +}; + + } // namespace Functor } // namespace otb diff --git a/Testing/Code/CMakeLists.txt b/Testing/Code/CMakeLists.txt index 2aa3fbb087c69677e141915048ceb3a5b1430668..1119ecf4321db6a2615c87324c96b430b3d5f6e2 100644 --- a/Testing/Code/CMakeLists.txt +++ b/Testing/Code/CMakeLists.txt @@ -20,6 +20,7 @@ ADD_SUBDIRECTORY(ObjectDetection) + IF(OTB_USE_VISU_GUI) ADD_SUBDIRECTORY(Visu) ADD_SUBDIRECTORY(Gui) diff --git a/Testing/Code/Learning/CMakeLists.txt b/Testing/Code/Learning/CMakeLists.txt index 31c62d6df081e43e7c22394753e6ec9edc2e16aa..e3ba3bae9143cef8f6fecaf1d5b7ce700bceca63 100644 --- a/Testing/Code/Learning/CMakeLists.txt +++ b/Testing/Code/Learning/CMakeLists.txt @@ -22,6 +22,7 @@ SET(LEARNING_TESTS1 ${CXX_TEST_PATH}/otbLearningTests1) SET(LEARNING_TESTS2 ${CXX_TEST_PATH}/otbLearningTests2) SET(LEARNING_TESTS3 ${CXX_TEST_PATH}/otbLearningTests3) SET(LEARNING_TESTS4 ${CXX_TEST_PATH}/otbLearningTests4) +SET(LEARNING_TESTS5 ${CXX_TEST_PATH}/otbLearningTests5) # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbLearningTESTS1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -584,7 +585,6 @@ ${TEMP}/leTvGaussianAdditiveNoiseSampleListFilterOutput.txt 0 -1 ) - # ConcatenateSampleListFilter tests ---------- ADD_TEST(leTuConcatenateSampleListFilterNew ${LEARNING_TESTS4} otbConcatenateSampleListFilterNew) @@ -630,6 +630,19 @@ ${TEMP}/leTvListSampleToBalancedListSampleFilterOutput.txt 1 -1 2 ) +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbLearningTESTS5 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ------- otb::DecisionTree ------------------------------ +ADD_TEST(leTuDecisionTreeNew ${LEARNING_TESTS5} +otbDecisionTreeNew) + +ADD_TEST(leTvDecisionTreeBuild ${LEARNING_TESTS5} +otbDecisionTreeBuild) + +ADD_TEST(leTvDecisionTreeWithRealValues ${LEARNING_TESTS5} +otbDecisionTreeWithRealValues) + # Testing srcs SET(BasicLearning_SRCS1 @@ -702,10 +715,18 @@ otbConcatenateSampleListFilter.cxx otbListSampleToBalancedListSampleFilter.cxx ) +SET(BasicLearning_SRCS5 +otbLearningTests5.cxx +otbDecisionTreeNew.cxx +otbDecisionTreeBuild.cxx +otbDecisionTreeWithRealValues.cxx +) + OTB_ADD_EXECUTABLE(otbLearningTests1 "${BasicLearning_SRCS1}" "OTBLearning;OTBIO;OTBTesting") OTB_ADD_EXECUTABLE(otbLearningTests2 "${BasicLearning_SRCS2}" "OTBLearning;OTBIO;OTBTesting") OTB_ADD_EXECUTABLE(otbLearningTests3 "${BasicLearning_SRCS3}" "OTBLearning;OTBIO;OTBTesting") OTB_ADD_EXECUTABLE(otbLearningTests4 "${BasicLearning_SRCS4}" "OTBLearning;OTBIO;OTBTesting") +OTB_ADD_EXECUTABLE(otbLearningTests5 "${BasicLearning_SRCS5}" "OTBLearning;OTBIO;OTBTesting") ENDIF( NOT OTB_DISABLE_CXX_TESTING AND BUILD_TESTING ) diff --git a/Testing/Code/Learning/otbDecisionTreeBuild.cxx b/Testing/Code/Learning/otbDecisionTreeBuild.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ca5a26c7e1abf77192bca6b078cff814f1d805b3 --- /dev/null +++ b/Testing/Code/Learning/otbDecisionTreeBuild.cxx @@ -0,0 +1,114 @@ +/*========================================================================= + + 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 "otbDecisionTree.h" + +enum WheatTypes { WinterWheat, SummerWheat }; + +int otbDecisionTreeBuild(int argc, char* argv[]) +{ +/** We build the following decision tree + + ------------- + ( DOY LT 100 ) + ------------- + Yes -/ -- No + --/ \-- + ------------- ------------- + ( NDVI GT 0.7 ) ( NDVI GT 0.7 ) + ------------- ------------- + / -- /\ + Yes -/ \- No Yes-/ \- No + -/ \ -/ \- + WW SW SW WW + + */ + typedef bool AttributeValueType; + + typedef otb::DecisionTree< AttributeValueType, WheatTypes > DecisionTreeType; + + DecisionTreeType::Pointer decisionTree = DecisionTreeType::New(); + DecisionTreeType::Pointer doyLT100Tree = DecisionTreeType::New(); + DecisionTreeType::Pointer doyGT100Tree = DecisionTreeType::New(); + + + decisionTree->SetAttribute( 0 ); + decisionTree->AddBranch( false, doyGT100Tree ); + decisionTree->AddBranch( true, doyLT100Tree ); + + doyLT100Tree->SetAttribute( 1 ); + doyLT100Tree->AddBranch( false, SummerWheat ); + doyLT100Tree->AddBranch( true, WinterWheat ); + + doyGT100Tree->SetAttribute( 1 ); + doyGT100Tree->AddBranch( false, WinterWheat ); + doyGT100Tree->AddBranch( true, SummerWheat ); + + // Build some examples for testing + + DecisionTreeType::ExampleType ww_in_summer;//(DoY<100), (NDVI>0.7) + ww_in_summer.push_back(false); + ww_in_summer.push_back(false); + + DecisionTreeType::ExampleType ww_in_winter; + ww_in_winter.push_back(true); + ww_in_winter.push_back(true); + + DecisionTreeType::ExampleType sw_in_winter; + sw_in_winter.push_back(true); + sw_in_winter.push_back(false); + + DecisionTreeType::ExampleType sw_in_summer; + sw_in_summer.push_back(false); + sw_in_summer.push_back(true); + + std::cout << "ww_in_summer" << std::endl; + if( decisionTree->Decide( ww_in_summer ) != WinterWheat ) + { + std::cerr << "ww_in_summer yields " << decisionTree->Decide( ww_in_summer ) << std::endl; + return EXIT_FAILURE; + } + + std::cout << "sw_in_winter" << std::endl; + if( decisionTree->Decide( sw_in_winter ) != SummerWheat ) + { + std::cerr << "sw_in_winter yields " << decisionTree->Decide( sw_in_winter ) << std::endl; + return EXIT_FAILURE; + } + + std::cout << "sw_in_summer" << std::endl; + if( decisionTree->Decide( sw_in_summer ) != SummerWheat ) + { + std::cerr << "sw_in_summer yields " << decisionTree->Decide( sw_in_summer ) << std::endl; + return EXIT_FAILURE; + } + + + std::cout << "ww_in_winter" << std::endl; + if( decisionTree->Decide( ww_in_winter ) != WinterWheat ) + { + std::cerr << "ww_in_winter yields " << decisionTree->Decide( ww_in_winter ) << std::endl; + return EXIT_FAILURE; + } + + + + + return EXIT_SUCCESS; +} + diff --git a/Testing/Code/Learning/otbDecisionTreeNew.cxx b/Testing/Code/Learning/otbDecisionTreeNew.cxx new file mode 100644 index 0000000000000000000000000000000000000000..09977dbdefce5f478472cfc61e025f2803423ad2 --- /dev/null +++ b/Testing/Code/Learning/otbDecisionTreeNew.cxx @@ -0,0 +1,33 @@ +/*========================================================================= + + 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 "otbDecisionTree.h" + +enum WheatTypes { WinterWheat, SummerWheat }; + +int otbDecisionTreeNew(int argc, char* argv[]) +{ + + typedef bool AttributeValueType; + + typedef otb::DecisionTree< AttributeValueType, WheatTypes > DecisionTreeType; + + DecisionTreeType::Pointer decisionTree = DecisionTreeType::New(); + + return EXIT_SUCCESS; +} diff --git a/Testing/Code/Learning/otbDecisionTreeWithRealValues.cxx b/Testing/Code/Learning/otbDecisionTreeWithRealValues.cxx new file mode 100644 index 0000000000000000000000000000000000000000..b492bf19d86297f50f2a2f44026a7349500db1cc --- /dev/null +++ b/Testing/Code/Learning/otbDecisionTreeWithRealValues.cxx @@ -0,0 +1,114 @@ +/*========================================================================= + + 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 "otbDecisionTree.h" + +enum WheatTypes { WinterWheat, SummerWheat }; + +int otbDecisionTreeWithRealValues(int argc, char* argv[]) +{ +/** We build the following decision tree + + ------------- + ( DOY LE 100 ) + ------------- + Yes -/ -- No + --/ \-- + ------------- ------------- + ( NDVI GT 0.7 ) ( NDVI GT 0.7 ) + ------------- ------------- + / -- /\ + Yes -/ \- No Yes-/ \- No + -/ \ -/ \- + WW SW SW WW + + */ + typedef double AttributeValueType; + + typedef otb::DecisionTree< AttributeValueType, WheatTypes > DecisionTreeType; + + DecisionTreeType::Pointer decisionTree = DecisionTreeType::New(); + DecisionTreeType::Pointer doyLE100Tree = DecisionTreeType::New(); + DecisionTreeType::Pointer doyGT100Tree = DecisionTreeType::New(); + + + decisionTree->SetAttribute( 0 ); + decisionTree->AddBranch( 100, DecisionTreeType::GT, doyGT100Tree ); + decisionTree->AddBranch( 100, DecisionTreeType::LE, doyLE100Tree ); + + doyLE100Tree->SetAttribute( 1 ); + doyLE100Tree->AddBranch( 0.7, DecisionTreeType::LT, SummerWheat ); + doyLE100Tree->AddBranch( 0.7, DecisionTreeType::GE, WinterWheat ); + + doyGT100Tree->SetAttribute( 1 ); + doyGT100Tree->AddBranch( 0.7, DecisionTreeType::LE, WinterWheat ); + doyGT100Tree->AddBranch( 0.7, DecisionTreeType::GT, SummerWheat ); + + // Build some examples for testing + + DecisionTreeType::ExampleType ww_in_summer;//(DoY), (NDVI) + ww_in_summer.push_back(200); + ww_in_summer.push_back(0.2); + + DecisionTreeType::ExampleType ww_in_winter; + ww_in_winter.push_back(70); + ww_in_winter.push_back(0.9); + + DecisionTreeType::ExampleType sw_in_winter; + sw_in_winter.push_back(60); + sw_in_winter.push_back(0.1); + + DecisionTreeType::ExampleType sw_in_summer; + sw_in_summer.push_back(220); + sw_in_summer.push_back(0.76); + + std::cout << "ww_in_summer" << std::endl; + if( decisionTree->Decide( ww_in_summer ) != WinterWheat ) + { + std::cerr << "ww_in_summer yields " << decisionTree->Decide( ww_in_summer ) << std::endl; + return EXIT_FAILURE; + } + + std::cout << "sw_in_winter" << std::endl; + if( decisionTree->Decide( sw_in_winter ) != SummerWheat ) + { + std::cerr << "sw_in_winter yields " << decisionTree->Decide( sw_in_winter ) << std::endl; + return EXIT_FAILURE; + } + + std::cout << "sw_in_summer" << std::endl; + if( decisionTree->Decide( sw_in_summer ) != SummerWheat ) + { + std::cerr << "sw_in_summer yields " << decisionTree->Decide( sw_in_summer ) << std::endl; + return EXIT_FAILURE; + } + + + std::cout << "ww_in_winter" << std::endl; + if( decisionTree->Decide( ww_in_winter ) != WinterWheat ) + { + std::cerr << "ww_in_winter yields " << decisionTree->Decide( ww_in_winter ) << std::endl; + return EXIT_FAILURE; + } + + + + + return EXIT_SUCCESS; +} + diff --git a/Testing/Code/Learning/otbLearningTests5.cxx b/Testing/Code/Learning/otbLearningTests5.cxx new file mode 100644 index 0000000000000000000000000000000000000000..af05ccb7a785d714e9f17ccc32f0ec8ec594fbd1 --- /dev/null +++ b/Testing/Code/Learning/otbLearningTests5.cxx @@ -0,0 +1,32 @@ +/*========================================================================= + + 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. + +=========================================================================*/ + +// this file defines the otbCommonTest for the test driver +// and all it expects is that you have a function called RegisterTests +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#include "otbTestMain.h" + +void RegisterTests() +{ + REGISTER_TEST(otbDecisionTreeNew); + REGISTER_TEST(otbDecisionTreeBuild); + REGISTER_TEST(otbDecisionTreeWithRealValues); +} diff --git a/Testing/Code/MultiTemporal/CMakeLists.txt b/Testing/Code/MultiTemporal/CMakeLists.txt new file mode 100644 index 0000000000000000000000000000000000000000..383377c1eacf0d0475b50d53bd95a4baef2811a9 --- /dev/null +++ b/Testing/Code/MultiTemporal/CMakeLists.txt @@ -0,0 +1,41 @@ + +IF( NOT OTB_DISABLE_CXX_TESTING AND BUILD_TESTING ) + +SET(BASELINE ${OTB_DATA_ROOT}/Baseline/OTB/Images) +SET(BASELINE_FILES ${OTB_DATA_ROOT}/Baseline/OTB/Files) +SET(INPUTDATA ${OTB_DATA_ROOT}/Input) +SET(TEMP ${OTBTesting_BINARY_DIR}/Temporary) + + +#Tolerance sur diff pixel image +SET(NOTOL 0.0) +SET(EPSILON_10 0.0000000001) + +SET(MULTITEMPORAL_TESTS1 ${CXX_TEST_PATH}/otbMultiTemporalTests1) + +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ MULTITEMPORAL_TESTS1 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +# ------- otb::testname ------------------------------ + +ADD_TEST(mtTvCBAMI ${MULTITEMPORAL_TESTS1} + --compare-image ${TOL} ${BASELINE}/cdCBAMIImage.png + ${TEMP}/cdCBAMIImage.png + otbCBAMIMultiTemporalTest + ${INPUTDATA}/GomaAvant.png + ${INPUTDATA}/GomaApres.png + 2 + ${TEMP}/cdCBAMIImage.png + ) + + +# ------- CXX Source Files ----------------------------------- +SET(BasicMultiTemporal_SRCS1 +otbMultiTemporalTests1.cxx +) + +OTB_ADD_EXECUTABLE(otbMultiTemporalTests1 "${BasicMultiTemporal_SRCS1}" "OTBMultiTemporal;OTBIO;OTBTesting") + + +ENDIF( NOT OTB_DISABLE_CXX_TESTING AND BUILD_TESTING ) diff --git a/Testing/Code/MultiTemporal/otbMultiTemporalTests1.cxx b/Testing/Code/MultiTemporal/otbMultiTemporalTests1.cxx new file mode 100644 index 0000000000000000000000000000000000000000..e08703f2bcdb22b7c6ba566500e7079039f1eeee --- /dev/null +++ b/Testing/Code/MultiTemporal/otbMultiTemporalTests1.cxx @@ -0,0 +1,30 @@ +/*========================================================================= + + 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. + +=========================================================================*/ + +// this file defines the otbCommonTest for the test driver +// and all it expects is that you have a function called RegisterTests +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#include "otbTestMain.h" + +void RegisterTests() +{ + REGISTER_TEST(otbCBAMIChangeDetectionTest); +} diff --git a/Testing/Code/Radiometry/CMakeLists.txt b/Testing/Code/Radiometry/CMakeLists.txt index a8ae745df0104258be68d0945a0f6e6453c56716..90cc869b92bfefb17e09235540d4e671c1a36376 100644 --- a/Testing/Code/Radiometry/CMakeLists.txt +++ b/Testing/Code/Radiometry/CMakeLists.txt @@ -920,6 +920,26 @@ ADD_TEST(raTvWDVI_MultiChannelRAndNIRVegetationIndexImageFilter ${RADIOMETRY_TES 2.0 # g : slope of soil line ) +# ------- LAI NDVI Logarithmic ------------------------------ +ADD_TEST(raTvLAIFromNDVILogarithmicFunctorTest ${RADIOMETRY_TESTS6} + otbLAIFromNDVILogarithmic + 3 # red + 4 # nir + 0.12 # ndvi soil + 0.91 # ndvi infinity + 0.70 # extinction coefficient +) + +# ------- LAI Reflectances Linear ------------------------------ +ADD_TEST(raTvLAIFromReflectancesLinearFunctorTest ${RADIOMETRY_TESTS6} + otbLAIFromReflectancesLinear + 3 # red + 4 # nir + -18 # red coef + 13 # nir coef +) + + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ otbRADIOMETRY_TESTS7 ~~~~~~~~~~~~~~~~~~~~~~~~~~~ # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -1606,6 +1626,8 @@ otbAVIRAndGAndNIRVegetationIndexImageFilter.cxx otbAVIMultiChannelRAndGAndNIRVegetationIndexImageFilter.cxx otbWDVIRAndNIRVegetationIndexImageFilter.cxx otbWDVIMultiChannelRAndNIRVegetationIndexImageFilter.cxx +otbLAIFromNDVILogarithmicFunctorTest.cxx +otbLAIFromReflectancesLinearFunctorTest.cxx ) SET(Radiometry_SRCS7 diff --git a/Testing/Code/Radiometry/otbLAIFromNDVILogarithmicFunctorTest.cxx b/Testing/Code/Radiometry/otbLAIFromNDVILogarithmicFunctorTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..ae84ff486d3ac821b0d30f7f5297067b5229e056 --- /dev/null +++ b/Testing/Code/Radiometry/otbLAIFromNDVILogarithmicFunctorTest.cxx @@ -0,0 +1,56 @@ +/*========================================================================= + + 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 "otbVegetationIndicesFunctor.h" + +int otbLAIFromNDVILogarithmic(int argc, char * argv[]) +{ + const unsigned int Dimension = 2; + typedef double PixelType; + + typedef otb::Functor::LAIFromNDVILogarithmic<PixelType, PixelType, PixelType> FunctorType; + + FunctorType laiFunct = FunctorType(); + + double redValue = (::atof(argv[1])); + double nirValue = (::atof(argv[2])); + double ndviSoil(::atof(argv[3])); + double ndviInf(::atof(argv[4])); + double extCoef(::atof(argv[5])); + + double ndvi = (nirValue-redValue)/(nirValue+redValue); + double goodResult = -1/extCoef*vcl_log((ndvi-ndviInf)/(ndviSoil-ndviInf)); + + laiFunct.SetNdviInf(ndviInf); + laiFunct.SetNdviSoil(ndviSoil); + laiFunct.SetExtinctionCoefficient(extCoef); + + laiFunct.SetRedIndex(1); + laiFunct.SetNIRIndex(2); + + itk::VariableLengthVector<PixelType> pixel; + pixel.Reserve(2); + pixel[0] = redValue; + pixel[1] = nirValue; + + double result = laiFunct(pixel); + + if( result!=goodResult ) return EXIT_FAILURE; + + return EXIT_SUCCESS; +} diff --git a/Testing/Code/Radiometry/otbLAIFromReflectancesLinearFunctorTest.cxx b/Testing/Code/Radiometry/otbLAIFromReflectancesLinearFunctorTest.cxx new file mode 100644 index 0000000000000000000000000000000000000000..8637f0c066408fc94c7b23436ebc8f951888e018 --- /dev/null +++ b/Testing/Code/Radiometry/otbLAIFromReflectancesLinearFunctorTest.cxx @@ -0,0 +1,53 @@ +/*========================================================================= + + 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 "otbVegetationIndicesFunctor.h" + +int otbLAIFromReflectancesLinear(int argc, char * argv[]) +{ + const unsigned int Dimension = 2; + typedef double PixelType; + + typedef otb::Functor::LAIFromReflectancesLinear<PixelType, PixelType, PixelType> FunctorType; + + FunctorType laiFunct = FunctorType(); + + double redValue = (::atof(argv[1])); + double nirValue = (::atof(argv[2])); + double redCoef(::atof(argv[3])); + double nirCoef(::atof(argv[4])); + + double goodResult = redCoef*redValue+nirCoef*nirValue; + + laiFunct.SetRedCoef(redCoef); + laiFunct.SetNirCoef(nirCoef); + + laiFunct.SetRedIndex(1); + laiFunct.SetNIRIndex(2); + + itk::VariableLengthVector<PixelType> pixel; + pixel.Reserve(2); + pixel[0] = redValue; + pixel[1] = nirValue; + + double result = laiFunct(pixel); + + if( result!=goodResult ) return EXIT_FAILURE; + + return EXIT_SUCCESS; +} diff --git a/Testing/Code/Radiometry/otbRadiometryTests6.cxx b/Testing/Code/Radiometry/otbRadiometryTests6.cxx index 9d3469dca9b5161e556b8eb44a9b00160c87e479..c09b3d00ac3f7551eb99a117baca6eff1fe7473a 100644 --- a/Testing/Code/Radiometry/otbRadiometryTests6.cxx +++ b/Testing/Code/Radiometry/otbRadiometryTests6.cxx @@ -34,4 +34,6 @@ void RegisterTests() REGISTER_TEST(otbAVIMultiChannelRAndGAndNIRVegetationIndexImageFilter); REGISTER_TEST(otbWDVIRAndNIRVegetationIndexImageFilter); REGISTER_TEST(otbWDVIMultiChannelRAndNIRVegetationIndexImageFilter); + REGISTER_TEST(otbLAIFromNDVILogarithmic); + REGISTER_TEST(otbLAIFromReflectancesLinear); }