From cbfc5e238da071a65606c5eeb51dab779a6f08e8 Mon Sep 17 00:00:00 2001 From: Aurelien Bricier <aurelien.bricier@c-s.fr> Date: Mon, 7 Mar 2011 13:09:44 +0100 Subject: [PATCH] ENH: enriched fuzzy variable parametrization --- Code/Fuzzy/otbFuzzyVariable.h | 14 ++- Code/Fuzzy/otbFuzzyVariable.txx | 45 ++++++- Testing/Code/Fuzzy/CMakeLists.txt | 36 ++++++ Testing/Code/Fuzzy/otbFuzzyTests2.cxx | 35 ++++++ .../Code/Fuzzy/otbFuzzyVariableDSApplied.cxx | 73 ++++++++++++ .../Code/Fuzzy/otbMassOfBeliefDSApplied.cxx | 112 ++++++++++++++++++ 6 files changed, 307 insertions(+), 8 deletions(-) create mode 100644 Testing/Code/Fuzzy/otbFuzzyTests2.cxx create mode 100644 Testing/Code/Fuzzy/otbFuzzyVariableDSApplied.cxx create mode 100644 Testing/Code/Fuzzy/otbMassOfBeliefDSApplied.cxx diff --git a/Code/Fuzzy/otbFuzzyVariable.h b/Code/Fuzzy/otbFuzzyVariable.h index 5673062590..56a9984502 100644 --- a/Code/Fuzzy/otbFuzzyVariable.h +++ b/Code/Fuzzy/otbFuzzyVariable.h @@ -34,6 +34,9 @@ namespace otb * of the qualitative values of the variable (MEDIUM = 0.9). Each * membership function is modeled by a trapezoidal function for which * 4 values have to be provided. + * In addition, 2 more values can be provided to define the min and + * the max. By default, they ar 0 and 1 respectively. + * */ template <class TLabel = unsigned short, class TPrecision=double> class ITK_EXPORT FuzzyVariable : public itk::DataObject @@ -56,9 +59,8 @@ public: typedef TPrecision PrecisionType; /** Type to hold the membership values */ - typedef std::map<LabelType, PrecisionType> MembershipValueType; - typedef itk::FixedArray< PrecisionType, 4 > ParametersType; + typedef itk::FixedArray< PrecisionType, 6> ParametersType; typedef std::map<LabelType, ParametersType> ParametersMapType; /** Get the membership related to one label */ @@ -77,6 +79,14 @@ public: const PrecisionType & v3, const PrecisionType & v4); + void SetMembership(const LabelType & var, + const PrecisionType & v1, + const PrecisionType & v2, + const PrecisionType & v3, + const PrecisionType & v4, + const PrecisionType & min, + const PrecisionType & max); + /** Remove a given label from the membership table */ void RemoveMembership(const LabelType & var); diff --git a/Code/Fuzzy/otbFuzzyVariable.txx b/Code/Fuzzy/otbFuzzyVariable.txx index 5570d8b73d..8c971e7b04 100644 --- a/Code/Fuzzy/otbFuzzyVariable.txx +++ b/Code/Fuzzy/otbFuzzyVariable.txx @@ -50,6 +50,8 @@ FuzzyVariable<TLabel, TPrecision>::SetMembership(const LabelType& var, parameters[1] = v2; parameters[2] = v3; parameters[3] = v4; + parameters[4] = static_cast<TPrecision>(0); + parameters[5] = static_cast<TPrecision>(1); // Insert it in the parameters map m_MembershipFunctions[var]=parameters; @@ -58,6 +60,35 @@ FuzzyVariable<TLabel, TPrecision>::SetMembership(const LabelType& var, this->Modified(); } +template <class TLabel, class TPrecision> +void +FuzzyVariable<TLabel, TPrecision>::SetMembership(const LabelType& var, + const PrecisionType & v1, + const PrecisionType & v2, + const PrecisionType & v3, + const PrecisionType & v4, + const PrecisionType & min, + const PrecisionType & max) +{ + // Check if values are ordered correctly + if( v1>v2 || v2>v3 || v3>v4) + itkExceptionMacro(<< "Values have to be v1<=v2<=v3<=v4"); + + // Build the membership parameters + ParametersType parameters; + parameters[0] = v1; + parameters[1] = v2; + parameters[2] = v3; + parameters[3] = v4; + parameters[4] = min; + parameters[5] = max; + + // Insert it in the parameters map + m_MembershipFunctions[var]=parameters; + + // Call modified + this->Modified(); +} template <class TLabel, class TPrecision> void @@ -105,7 +136,7 @@ FuzzyVariable<TLabel, TPrecision> // Remaining of the code is trapezoidal function if( value < parameters[0] || value > parameters[3] ) { - output = 0; + output = parameters[4]; } else if( value >= parameters[0] && value < parameters[1] ) @@ -113,18 +144,19 @@ FuzzyVariable<TLabel, TPrecision> if(parameters[1]>parameters[0]) { output = static_cast<TPrecision>((value - parameters[0]) - /(parameters[1] - parameters[0])); + /(parameters[1] - parameters[0]) + *(parameters[5] - parameters[4])); } else { - output = static_cast<TPrecision>(1); + output = parameters[5]; } } if( value >= parameters[1] && value < parameters[2] ) { - output = static_cast<TPrecision>(1); + output = parameters[5]; } if( value >= parameters[2] @@ -133,11 +165,12 @@ FuzzyVariable<TLabel, TPrecision> if(parameters[3]>parameters[2]) { output = static_cast<TPrecision>((parameters[3] - value) - /(parameters[3] - parameters[2])); + /(parameters[3] - parameters[2]) + *(parameters[5] - parameters[4])); } else { - output = static_cast<TPrecision>(1); + output = parameters[5]; } } diff --git a/Testing/Code/Fuzzy/CMakeLists.txt b/Testing/Code/Fuzzy/CMakeLists.txt index 7d86ce8a19..cdd21b05b4 100644 --- a/Testing/Code/Fuzzy/CMakeLists.txt +++ b/Testing/Code/Fuzzy/CMakeLists.txt @@ -19,6 +19,8 @@ SET(EPSILON_3 0.001) # Common generic tests SET(Fuzzy_TESTS1 ${CXX_TEST_PATH}/otbFuzzyTests1) +# Advanced tests +SET(Fuzzy_TESTS2 ${CXX_TEST_PATH}/otbFuzzyTests2) # FuzzyTests1 ADD_TEST(fzTuFuzzyVariableNew ${Fuzzy_TESTS1} @@ -39,6 +41,30 @@ ADD_TEST(fzTvMassOfBelief ${Fuzzy_TESTS1} ADD_TEST(fzTvJointMassOfBeliefFilter ${Fuzzy_TESTS1} otbJointMassOfBeliefFilter) +# FuzzyTests2 +ADD_TEST(fzTvFuzzyVariableDSApplied ${Fuzzy_TESTS2} + otbFuzzyVariableDSApplied) + +ADD_TEST(fzTvMassOfBeliefDSApplied ${Fuzzy_TESTS2} + otbMassOfBeliefDSApplied) + +#ADD_TEST(fzTuVectorDataToSpecificDescriptionFilterBaseNew ${Fuzzy_TESTS2} +# otbVectorDataToSpecificDescriptionFilterBaseNew) + +#ADD_TEST(fzTuVectorDataToRoadDescriptionFilterNew ${Fuzzy_TESTS2} +# otbVectorDataToRoadDescriptionFilterNew) + +#ADD_TEST(fzTvVectorDataToRoadDescriptionFilter ${Fuzzy_TESTS2} + #--compare-ogr ${NOTOL} + #${INPUTDATA}/.shp + #${TEMP}/.shp + #otbVectorDataToRoadDescriptionFilter + #${INPUTDATA}/ROI_QB_RANGUEUIL_ROADS.shp + #${INPUTDATA}/ROI_QB_RANGUEUIL_MUL_4.TIF + #${TEMP}/fzTvVectorDataToRoadDescriptionFilterOutput.shp + #) + + SET(BasicFuzzy_SRCS1 otbFuzzyVariableNew.cxx otbFuzzyVariable2Values.cxx @@ -48,7 +74,17 @@ otbMassOfBelief.cxx otbJointMassOfBeliefFilter.cxx ) +SET(BasicFuzzy_SRCS2 +otbFuzzyVariableDSApplied.cxx +otbMassOfBeliefDSApplied.cxx +#otbVectorDataToSpecificDescriptionFilterBase.cxx +#otbVectorDataToRoadDescriptionFilter.cxx +) + ADD_EXECUTABLE(otbFuzzyTests1 otbFuzzyTests1.cxx ${BasicFuzzy_SRCS1}) TARGET_LINK_LIBRARIES(otbFuzzyTests1 OTBIO OTBFuzzy OTBTesting) +ADD_EXECUTABLE(otbFuzzyTests2 otbFuzzyTests2.cxx ${BasicFuzzy_SRCS2}) +TARGET_LINK_LIBRARIES(otbFuzzyTests2 OTBIO OTBFuzzy OTBTesting) + ENDIF( NOT OTB_DISABLE_CXX_TESTING AND BUILD_TESTING ) diff --git a/Testing/Code/Fuzzy/otbFuzzyTests2.cxx b/Testing/Code/Fuzzy/otbFuzzyTests2.cxx new file mode 100644 index 0000000000..988452c771 --- /dev/null +++ b/Testing/Code/Fuzzy/otbFuzzyTests2.cxx @@ -0,0 +1,35 @@ +/*========================================================================= + + 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(otbFuzzyVariableDSApplied); + REGISTER_TEST(otbMassOfBeliefDSApplied); + //REGISTER_TEST(otbVectorDataToSpecificDescriptionFilterBaseNew); + //REGISTER_TEST(otbVectorDataToRoadDescriptionFilterNew); + //REGISTER_TEST(otbVectorDataToRoadDescriptionFilter); +} diff --git a/Testing/Code/Fuzzy/otbFuzzyVariableDSApplied.cxx b/Testing/Code/Fuzzy/otbFuzzyVariableDSApplied.cxx new file mode 100644 index 0000000000..94266656df --- /dev/null +++ b/Testing/Code/Fuzzy/otbFuzzyVariableDSApplied.cxx @@ -0,0 +1,73 @@ +/*========================================================================= + + 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. + +=========================================================================*/ +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#include "otbFuzzyVariable.h" + +int otbFuzzyVariableDSApplied(int argc, char* argv[]) +{ + typedef float PrecisionType; + + typedef otb::FuzzyVariable<std::string, PrecisionType> FuzzyVarType; + + FuzzyVarType::Pointer fv = FuzzyVarType::New(); + + fv->SetMembership("H1", 0, 0, 0.1, 0.5, 0, 0.8); + fv->SetMembership("!H1", 0.5, 0.8, 1.0, 1.0, 0, 0.8); + fv->SetMembership("Theta",0.1, 0.5, 0.5, 0.8, 0.2, 1); + + std::string maxVar; + PrecisionType pos; + PrecisionType memH1; + PrecisionType memH1_; + PrecisionType memTheta; + + + for(unsigned int i=0; i<=100; i++) + { + pos = (PrecisionType)i/100; + maxVar = fv->GetMaxVar(pos); + memH1 = fv->GetMembership("H1", pos); + memH1_ = fv->GetMembership("!H1", pos); + memTheta = fv->GetMembership("Theta", pos); + + + std::cout << "Memberships(" + << pos + << "): [" + << memH1 + << ", " + << memH1_ + << ", " + << memTheta + <<"] - MaxVar(" + << pos + << ") : " + << maxVar + << std::endl; + } + + fv->RemoveMembership("H1"); + fv->RemoveMembership("!H1"); + fv->RemoveMembership("Theta"); + fv->Clear(); + + return EXIT_SUCCESS; +} diff --git a/Testing/Code/Fuzzy/otbMassOfBeliefDSApplied.cxx b/Testing/Code/Fuzzy/otbMassOfBeliefDSApplied.cxx new file mode 100644 index 0000000000..80d3e876ff --- /dev/null +++ b/Testing/Code/Fuzzy/otbMassOfBeliefDSApplied.cxx @@ -0,0 +1,112 @@ +/*========================================================================= + + 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. + +=========================================================================*/ +#if defined(_MSC_VER) +#pragma warning ( disable : 4786 ) +#endif + +#include "otbMassOfBelief.h" + +#include "otbFuzzyVariable.h" +#include "otbJointMassOfBeliefFilter.h" + +int otbMassOfBeliefDSApplied(int argc, char* argv[]) +{ + typedef float PrecisionType; + typedef otb::FuzzyVariable<std::string, + PrecisionType> FuzzyVarType; + + typedef otb::MassOfBelief<std::string> MassOfBeliefFunctionType; + + typedef otb::JointMassOfBeliefFilter<MassOfBeliefFunctionType> JointMassOfBeliefFilterType; + + FuzzyVarType::Pointer desc1 = FuzzyVarType::New(); + FuzzyVarType::Pointer desc2 = FuzzyVarType::New(); + + desc1->SetMembership("H1", 0, 0, 0.1, 0.5, 0, 0.8); + desc1->SetMembership("H1_", 0.5, 0.8, 1.0, 1.0, 0, 0.8); + + desc2->SetMembership("H2", 0, 0, 0.58, 0.68, 0, 0.99); + desc2->SetMembership("H2_", 0.68, 0.98, 1.0, 1.0, 0, 0.99); + + PrecisionType desc1Val = 0.9; + PrecisionType desc2Val = 0.9; + + MassOfBeliefFunctionType::Pointer mass1 = MassOfBeliefFunctionType::New(); + MassOfBeliefFunctionType::Pointer mass2 = MassOfBeliefFunctionType::New(); + MassOfBeliefFunctionType::Pointer jointMass = MassOfBeliefFunctionType::New(); + + MassOfBeliefFunctionType::LabelSetType H1, H1_, H2, H2_, universe, Hyp; + universe.insert("H1"); + universe.insert("H1_"); + universe.insert("H2"); + universe.insert("H2_"); + + Hyp.insert("H1"); + Hyp.insert("H2_"); + + mass1->InitializePowerSetMasses(universe); + mass2->InitializePowerSetMasses(universe); + + H1.insert("H1"); + H1_.insert("H1_"); + mass1->SetMass(H1, desc1->GetMembership("H1", desc1Val)); + mass1->SetMass(H1_, desc1->GetMembership("H1_", desc1Val)); + mass1->EstimateUncertainty(); + + H2.insert("H2"); + H2_.insert("H2_"); + mass2->SetMass(H2, desc2->GetMembership("H2", desc2Val)); + mass2->SetMass(H2_, desc2->GetMembership("H2_", desc2Val)); + mass2->EstimateUncertainty(); + + JointMassOfBeliefFilterType::Pointer jointMassFilter = JointMassOfBeliefFilterType::New(); + // Compute joint mass + jointMassFilter->PushBackInput(mass1); + jointMassFilter->PushBackInput(mass2); + jointMassFilter->Update(); + jointMass = jointMassFilter->GetOutput(); + + std::cout<<mass1<<std::endl; + std::cout << "[" + << desc1->GetMembership("H1", desc1Val) + << "," + << desc1->GetMembership("H1_", desc1Val) + << "]" + << std::endl; + + std::cout<<mass2<<std::endl; + std::cout << "[" + << desc2->GetMembership("H2", desc2Val) + << "," + << desc2->GetMembership("H2_", desc2Val) + << "]" + << std::endl; + + std::cout << jointMass << std::endl; + std::cout << "Belief(Hyp) : " + << jointMass->GetBelief(Hyp) + << " - Plausibility(Hyp) : " + << jointMass->GetPlausibility(Hyp) + << " - Score(Hyp) : " + << (jointMass->GetBelief(Hyp) + jointMass->GetPlausibility(Hyp))/2.0 + << std::endl; + + return EXIT_SUCCESS; +} + + -- GitLab