From 391b6eecf8d8157106d698739ed5ce4efbbec473 Mon Sep 17 00:00:00 2001
From: Aurelien Bricier <aurelien.bricier@c-s.fr>
Date: Mon, 16 May 2011 18:05:43 +0200
Subject: [PATCH] ENH: added new class StandardDSCostFunction

---
 Code/Fuzzy/otbStandardDSCostFunction.h   | 151 +++++++++++++++++++++
 Code/Fuzzy/otbStandardDSCostFunction.txx | 166 +++++++++++++++++++++++
 2 files changed, 317 insertions(+)
 create mode 100644 Code/Fuzzy/otbStandardDSCostFunction.h
 create mode 100644 Code/Fuzzy/otbStandardDSCostFunction.txx

diff --git a/Code/Fuzzy/otbStandardDSCostFunction.h b/Code/Fuzzy/otbStandardDSCostFunction.h
new file mode 100644
index 0000000000..f5b5a7cd6b
--- /dev/null
+++ b/Code/Fuzzy/otbStandardDSCostFunction.h
@@ -0,0 +1,151 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+#ifndef __otbStandardDSCostFunction_h
+#define __otbStandardDSCostFunction_h
+
+#include "itkSingleValuedCostFunction.h"
+
+#include "otbVectorDataToDSValidatedVectorDataFilter.h"
+#include "otbParser.h"
+#include "otbFuzzyDescriptorsModelManager.h"
+
+namespace otb
+{
+/** \class StandardDSCostFunction
+  * \brief Standard Cost Function used to estimate the fuzzy model parameters
+  * in the Dempster-Shafer framework
+  *
+  * This class has been developed to estimate, with the help of the Amoeba
+  * optimizer, the fuzzy model parameters to be used in the class
+  * otb::VectorDataToDSValidatedVectorDataFilter. The cost value compute the
+  * cost according to:
+  * - an enriched ground truth vector data (using VectorDataToRoadDescription)
+  * - an enriched negative sample VectorData or at least random samples
+  * - an hypothesis (the same as the considered DSValidationFilter)
+  *      (by default (NDVI, RADIOM))
+  * - a weight between 0 and 1 (0.5 by default) corresponding to the situation
+  *      policy regarding under detection/false detection (1 no under detection
+  *      0 no false detection)
+  * For now the cost function use the NDVI Feature and the RADIOM Feature.
+  * For each evolution of the VectorDataToDSValidatedVectorDataFilter,
+  * this cost function must be adapted.
+  *
+  * Limitation: the use of a custom criterion is to be implemented.
+  * For now, it uses (Belief+Plausibility)/2.0 so it can be used only to
+  * parameter the DSValidetionFilter considering the same criterion
+  *
+  * \ingroup CostFunction
+  * \sa VectorDataToDSValidatedVectorDataFilter
+  * \sa AmoebaOptimizer
+ */
+
+template <class TDSValidationFilter>
+class ITK_EXPORT StandardDSCostFunction :
+public itk::SingleValuedCostFunction
+{
+public:
+  /** Standard class typedefs. */
+  typedef StandardDSCostFunction                       Self;
+  typedef itk::SingleValuedCostFunction                Superclass;
+  typedef itk::SmartPointer<Self>                      Pointer;
+  typedef itk::SmartPointer<const Self>                ConstPointer;
+
+  /** Method for creation through the object factory. */
+  itkNewMacro(Self);
+
+  /** Run-time type information (and related methods). */
+  itkTypeMacro(StandardDSCostFunction, itk::SingleValuedCostFunction);
+
+  typedef Superclass::MeasureType                      MeasureType;   //double
+  typedef Superclass::DerivativeType                   DerivativeType;//Array<double>
+  typedef Superclass::ParametersType                   ParametersType;//Array<double>
+
+  typedef TDSValidationFilter                          DSValidationFilterType;
+  typedef typename DSValidationFilterType::VectorDataType
+                                                       VectorDataType;
+  typedef typename DSValidationFilterType::TreeIteratorType
+                                                       TreeIteratorType;
+  typedef typename DSValidationFilterType::LabelSetType
+                                                       LabelSetType;
+
+  typedef FuzzyDescriptorsModelManager                 FuzzyDescriptorsModelManagerType;
+
+  typedef Parser                                       ParserType;
+
+  /** This method returns the value of the cost function corresponding
+    * to the specified parameters.    */
+  virtual MeasureType GetValue( const ParametersType & parameters ) const;
+
+  /** This method returns the derivative of the cost function corresponding
+    * to the specified parameters.   */
+  virtual void GetDerivative( const ParametersType & parameters,
+                               DerivativeType & derivative ) const;
+
+  virtual unsigned int GetNumberOfParameters(void) const;
+
+  itkSetMacro(Weight, double);
+  itkGetConstMacro(Weight, double);
+
+  itkSetObjectMacro(GTVectorData, VectorDataType);
+  itkGetConstObjectMacro(GTVectorData, VectorDataType);
+
+  itkSetObjectMacro(NSVectorData, VectorDataType);
+  itkGetConstObjectMacro(NSVectorData, VectorDataType);
+
+  LabelSetType GetHypothesis()
+  {
+    return m_Hypothesis;
+  }
+
+  void SetHypothesis(LabelSetType hypothesis)
+  {
+    m_Hypothesis = hypothesis;
+  }
+
+protected:
+  /** Constructor */
+  StandardDSCostFunction();
+  /** Destructor */
+  virtual ~StandardDSCostFunction() {}
+  /**PrintSelf method */
+  virtual void PrintSelf(std::ostream& os, itk::Indent indent) const;
+
+private:
+  StandardDSCostFunction(const Self &); //purposely not implemented
+  void operator =(const Self&); //purposely not implemented
+
+
+  typename VectorDataType::Pointer            m_GTVectorData;//Ground Truth
+  typename VectorDataType::Pointer            m_NSVectorData;//Negative Samples
+
+  typename ParserType::Pointer       m_Parser;
+  std::string                        m_CriterionFormula;
+
+  double                             m_Weight; //range ]0; 1[
+
+  LabelSetType                       m_Hypothesis;
+  const unsigned int                 m_NumberOfParameters;
+};
+
+} // end namespace otb
+
+#ifndef OTB_MANUAL_INSTANTIATION
+#include "otbStandardDSCostFunction.txx"
+#endif
+
+#endif
diff --git a/Code/Fuzzy/otbStandardDSCostFunction.txx b/Code/Fuzzy/otbStandardDSCostFunction.txx
new file mode 100644
index 0000000000..8b6891d6d8
--- /dev/null
+++ b/Code/Fuzzy/otbStandardDSCostFunction.txx
@@ -0,0 +1,166 @@
+/*=========================================================================
+
+  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.
+
+=========================================================================*/
+#ifndef __otbStandardDSCostFunction_txx
+#define __otbStandardDSCostFunction_txx
+
+#include "otbStandardDSCostFunction.h"
+
+namespace otb
+{
+// Constructor
+template <class TDSValidationFilter>
+StandardDSCostFunction<TDSValidationFilter>
+::StandardDSCostFunction() :
+  m_CriterionFormula("((Belief + Plausibility)/2)"),
+  m_Weight(0.5),
+  m_NumberOfParameters(8)
+{
+ m_GTVectorData = VectorDataType::New();
+ m_NSVectorData = VectorDataType::New();
+ m_Parser =  ParserType::New();
+
+ m_Hypothesis.insert("NDVI");
+ m_Hypothesis.insert("RADIOM");
+}
+
+template <class TDSValidationFilter>
+unsigned int
+StandardDSCostFunction<TDSValidationFilter>
+::GetNumberOfParameters() const
+ {
+  return m_NumberOfParameters;
+ }
+
+template <class TDSValidationFilter>
+typename StandardDSCostFunction<TDSValidationFilter>
+::MeasureType
+ StandardDSCostFunction<TDSValidationFilter>
+::GetValue(const ParametersType & parameters) const
+ {
+  //Initialize parser
+  m_Parser->SetExpr(m_CriterionFormula);
+
+  unsigned int nbParam = this->GetNumberOfParameters();
+
+  std::vector<double> ndvi, radiom;
+  for (unsigned int i=0; i<4; i++)
+    {
+      ndvi.push_back(parameters[i]);
+    }
+  for (unsigned int i=0; i<4; i++)
+    {
+      radiom.push_back(parameters[i+4]);
+    }
+  typename DSValidationFilterType::Pointer internalFunctionGT
+    = DSValidationFilterType::New();
+  internalFunctionGT->SetCriterionFormula("1");
+  internalFunctionGT->SetInput(m_GTVectorData);
+  internalFunctionGT->SetHypothesis(m_Hypothesis);
+  try
+  {
+    internalFunctionGT->SetFuzzyModel("NDVI", ndvi);
+    internalFunctionGT->SetFuzzyModel("RADIOM", radiom);
+  }
+  catch (itk::ExceptionObject & err)
+  {
+    return (m_Weight*m_GTVectorData->Size() + (1-m_Weight)*m_NSVectorData->Size());;
+  }
+  internalFunctionGT->Update();
+
+  typename DSValidationFilterType::Pointer internalFunctionNS
+    = DSValidationFilterType::New();
+  internalFunctionNS->SetCriterionFormula("1");
+  internalFunctionNS->SetInput(m_NSVectorData);
+  internalFunctionNS->SetHypothesis(m_Hypothesis);
+  try
+  {
+    internalFunctionNS->SetFuzzyModel("NDVI", ndvi);
+    internalFunctionNS->SetFuzzyModel("RADIOM", radiom);
+  }
+  catch (itk::ExceptionObject & err)
+  {
+    return (m_Weight*m_GTVectorData->Size() + (1-m_Weight)*m_NSVectorData->Size());;
+  }
+  internalFunctionNS->Update();
+
+  double accGT, accNS, belief, plausibility;
+  accGT = 0.0;
+  accNS = 0.0;
+
+  TreeIteratorType itVectorGT(internalFunctionGT->GetOutput()->GetDataTree());
+  itVectorGT.GoToBegin();
+  while (!itVectorGT.IsAtEnd())
+      {
+      if (!itVectorGT.Get()->IsRoot() && !itVectorGT.Get()->IsDocument() && !itVectorGT.Get()->IsFolder())
+        {
+        belief       = itVectorGT.Get()->GetFieldAsDouble("Belief");
+        plausibility = itVectorGT.Get()->GetFieldAsDouble("Plausi");
+
+        m_Parser->DefineVar("Belief", &belief);
+        m_Parser->DefineVar("Plausibility", &plausibility);
+
+        accGT += (1 - m_Parser->Eval()) * (1 - m_Parser->Eval());
+
+        m_Parser->ClearVar();
+        }
+      itVectorGT++;
+      }
+
+  TreeIteratorType itVectorNS(internalFunctionNS->GetOutput()->GetDataTree());
+  itVectorNS.GoToBegin();
+  while (!itVectorNS.IsAtEnd())
+      {
+      if (!itVectorNS.Get()->IsRoot() && !itVectorNS.Get()->IsDocument() && !itVectorNS.Get()->IsFolder())
+        {
+        belief       = itVectorNS.Get()->GetFieldAsDouble("Belief");
+        plausibility = itVectorNS.Get()->GetFieldAsDouble("Plausi");
+
+        m_Parser->DefineVar("Belief", &belief);
+        m_Parser->DefineVar("Plausibility", &plausibility);
+
+        accNS += m_Parser->Eval() * m_Parser->Eval();
+
+        m_Parser->ClearVar();
+        }
+      itVectorNS++;
+      }
+  return (m_Weight*accGT + (1-m_Weight)*accNS);
+ }
+
+template <class TDSValidationFilter>
+void
+StandardDSCostFunction<TDSValidationFilter>
+::GetDerivative(const ParametersType & parameters, DerivativeType & derivative) const
+ {
+  //Not necessary for Amoeba Optimizer
+  itkExceptionMacro(<< "Not Supposed to be used when using Amoeba Optimizer!")
+ }
+
+// PrintSelf Method
+template <class TDSValidationFilter>
+void
+StandardDSCostFunction<TDSValidationFilter>
+::PrintSelf(std::ostream& os, itk::Indent indent) const
+{
+  Superclass::PrintSelf(os, indent);
+}
+
+
+}// end namespace otb
+
+#endif
-- 
GitLab