/* * 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 otbFuzzyVariable_hxx #define otbFuzzyVariable_hxx #include "otbFuzzyVariable.h" #include "otbMacro.h" namespace otb { template FuzzyVariable::FuzzyVariable() { } template void FuzzyVariable::SetMembership(const LabelType& var, const PrecisionType& v1, const PrecisionType& v2, const PrecisionType& v3, const PrecisionType& v4) { // 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] = static_cast(0); parameters[5] = static_cast(1); // Insert it in the parameters map m_MembershipFunctions[var] = parameters; // Call modified this->Modified(); } template void FuzzyVariable::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"); if (min >= max) itkExceptionMacro(<< "Values have to be minModified(); } template void FuzzyVariable::RemoveMembership(const LabelType& var) { // Erase one parameter m_MembershipFunctions.erase(var); // Call Modified() this->Modified(); } template void FuzzyVariable::Clear() { // Clear the membership parameters map m_MembershipFunctions.clear(); // Call Modified() this->Modified(); } template typename FuzzyVariable::PrecisionType FuzzyVariable::GetMembership(const LabelType& var, const PrecisionType& value) const { // Declare output PrecisionType output = itk::NumericTraits::Zero; // Retrieve parameters for the given membership function typename ParametersMapType::const_iterator mapIt = m_MembershipFunctions.find(var); // If var exists in the parameters map if (mapIt != m_MembershipFunctions.end()) { // Retrieve parameters ParametersType parameters = mapIt->second; // Remaining of the code is trapezoidal function if (value < parameters[0] || value >= parameters[3]) { output = parameters[4]; } else if (value >= parameters[0] && value < parameters[1]) { if (parameters[1] > parameters[0]) { output = static_cast(parameters[4] + (value - parameters[0]) / (parameters[1] - parameters[0]) * (parameters[5] - parameters[4])); } else { output = parameters[5]; } } if (value >= parameters[1] && value < parameters[2]) { output = parameters[5]; } if (value >= parameters[2] && value < parameters[3]) { if (parameters[3] > parameters[2]) { output = static_cast(parameters[4] + (parameters[3] - value) / (parameters[3] - parameters[2]) * (parameters[5] - parameters[4])); } else { output = parameters[5]; } } } // Return the membership value return output; } template typename FuzzyVariable::MembershipValueType FuzzyVariable::GetMembership(const PrecisionType& value) const { // Build the output membership map MembershipValueType output; // Walk the membership parameters map for (typename ParametersMapType::const_iterator mapIt = m_MembershipFunctions.begin(); mapIt != m_MembershipFunctions.end(); ++mapIt) { // Compute the membership output[mapIt->first] = this->GetMembership(mapIt->first, value); } // Return output return output; } template typename FuzzyVariable::LabelType FuzzyVariable::GetMaxVar(const PrecisionType& value) const { // If parameters map is empty, throw an exception if (m_MembershipFunctions.empty()) { itkExceptionMacro(<< "Membership parameters map is empty"); } // First retrieve all membership values MembershipValueType memberships = this->GetMembership(value); // Define an iterator on the membership parameters map typename MembershipValueType::const_iterator mapIt = memberships.begin(); // Look for the higher value LabelType higherVar = mapIt->first; PrecisionType higherVal = mapIt->second; ++mapIt; while (mapIt != memberships.end()) { if (mapIt->second > higherVal) { higherVal = mapIt->second; higherVar = mapIt->first; } ++mapIt; } // Return the higher var return higherVar; } template void FuzzyVariable::PrintSelf(std::ostream& os, itk::Indent indent) const { Superclass::PrintSelf(os, indent); } template std::ostream& FuzzyVariable::PrintMembershipValueType(std::ostream& out, const MembershipValueType& labelMap) { // Define an iterator on the label set typedef std::map LabelMapType; typename LabelMapType::const_iterator it = labelMap.begin(); // Open the set out << "{"; // Append the set elements while (it != labelMap.end()) { out << it->first << " : " << it->second; ++it; if (it != labelMap.end()) out << ", "; } // close the set out << "}"; // Return return out; } } // end namespace otb #endif