From 0d8e89b5ce1a2f8b8870f7a8b33a303b93c57a47 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=A9dric=20Traizet?= <cedric.traizet@c-s.fr>
Date: Wed, 8 Jan 2020 15:36:00 +0100
Subject: [PATCH] REFAC: remove opencv2 specific code

---
 .../include/otbTrainBoost.hxx                 |  1 -
 .../include/otbTrainDecisionTree.hxx          | 19 +---
 .../AppClassification/test/CMakeLists.txt     |  3 -
 .../include/otbBoostMachineLearningModel.h    | 20 +---
 .../include/otbBoostMachineLearningModel.hxx  | 61 +-----------
 .../Supervised/include/otbCvRTreesWrapper.h   |  8 +-
 .../otbDecisionTreeMachineLearningModel.h     |  8 --
 .../otbDecisionTreeMachineLearningModel.hxx   | 48 +---------
 ...otbKNearestNeighborsMachineLearningModel.h |  9 +-
 ...bKNearestNeighborsMachineLearningModel.hxx | 54 +----------
 .../otbNeuralNetworkMachineLearningModel.h    |  7 +-
 .../otbNeuralNetworkMachineLearningModel.hxx  | 94 +------------------
 .../otbNormalBayesMachineLearningModel.h      | 10 +-
 .../otbNormalBayesMachineLearningModel.hxx    | 41 +-------
 .../Supervised/include/otbOpenCVUtils.h       |  3 +-
 .../otbRandomForestsMachineLearningModel.h    |  7 +-
 .../otbRandomForestsMachineLearningModel.hxx  | 57 +----------
 .../include/otbSVMMachineLearningModel.h      | 10 +-
 .../include/otbSVMMachineLearningModel.hxx    | 74 +--------------
 .../Supervised/src/otbCvRTreesWrapper.cxx     | 21 +----
 20 files changed, 24 insertions(+), 531 deletions(-)

diff --git a/Modules/Applications/AppClassification/include/otbTrainBoost.hxx b/Modules/Applications/AppClassification/include/otbTrainBoost.hxx
index 9e551b7a94..6c831522a8 100644
--- a/Modules/Applications/AppClassification/include/otbTrainBoost.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainBoost.hxx
@@ -58,7 +58,6 @@ void LearningApplicationBase<TInputValue, TOutputValue>::InitBoostParams()
                           "rather than exact optimization at each step.");
   SetParameterString("classifier.boost.t", "real");
   SetParameterDescription("classifier.boost.t", "Type of Boosting algorithm.");
-  // Do not expose SplitCriteria
   // WeakCount
   AddParameter(ParameterType_Int, "classifier.boost.w", "Weak count");
   SetParameterInt("classifier.boost.w", 100);
diff --git a/Modules/Applications/AppClassification/include/otbTrainDecisionTree.hxx b/Modules/Applications/AppClassification/include/otbTrainDecisionTree.hxx
index c0f70c3385..e9c6416321 100644
--- a/Modules/Applications/AppClassification/include/otbTrainDecisionTree.hxx
+++ b/Modules/Applications/AppClassification/include/otbTrainDecisionTree.hxx
@@ -35,11 +35,7 @@ void LearningApplicationBase<TInputValue, TOutputValue>::InitDecisionTreeParams(
   SetParameterDescription("classifier.dt", "http://docs.opencv.org/modules/ml/doc/decision_trees.html");
   // MaxDepth
   AddParameter(ParameterType_Int, "classifier.dt.max", "Maximum depth of the tree");
-#ifdef OTB_OPENCV_3
   SetParameterInt("classifier.dt.max", 10);
-#else
-  SetParameterInt("classifier.dt.max", 65535);
-#endif
   SetParameterDescription("classifier.dt.max",
                           "The training algorithm attempts to split each node while its depth is smaller "
                           "than the maximum possible depth of the tree. The actual depth may be smaller "
@@ -72,16 +68,6 @@ void LearningApplicationBase<TInputValue, TOutputValue>::InitDecisionTreeParams(
                           "Cluster possible values of a categorical variable into K <= cat clusters to find a "
                           "suboptimal split.");
 
-
-// CVFolds: only exposed for OPENCV 2 because it crashes in OpenCV 3
-#ifndef OTB_OPENCV_3
-  AddParameter(ParameterType_Int, "classifier.dt.f", "K-fold cross-validations");
-  SetParameterInt("classifier.dt.f", 10);
-  SetParameterDescription("classifier.dt.f",
-                          "If cv_folds > 1, then it prunes a tree with K-fold cross-validation where K "
-                          "is equal to cv_folds.");
-#endif
-
   // Use1seRule
   AddParameter(ParameterType_Bool, "classifier.dt.r", "Set Use1seRule flag to false");
   SetParameterDescription("classifier.dt.r",
@@ -109,10 +95,7 @@ void LearningApplicationBase<TInputValue, TOutputValue>::TrainDecisionTree(typen
   classifier->SetMinSampleCount(GetParameterInt("classifier.dt.min"));
   classifier->SetRegressionAccuracy(GetParameterFloat("classifier.dt.ra"));
   classifier->SetMaxCategories(GetParameterInt("classifier.dt.cat"));
-// CVFolds is only exposed for OPENCV 2 because it crashes in OpenCV 3
-#ifndef OTB_OPENCV_3
-  classifier->SetCVFolds(GetParameterInt("classifier.dt.f"));
-#endif
+
   if (GetParameterInt("classifier.dt.r"))
   {
     classifier->SetUse1seRule(false);
diff --git a/Modules/Applications/AppClassification/test/CMakeLists.txt b/Modules/Applications/AppClassification/test/CMakeLists.txt
index 9da705b64c..8e99d91e33 100644
--- a/Modules/Applications/AppClassification/test/CMakeLists.txt
+++ b/Modules/Applications/AppClassification/test/CMakeLists.txt
@@ -126,9 +126,6 @@ set(classifierList)
 if(OTB_USE_OPENCV)
   #list(APPEND classifierList "SVM" "BOOST" "DT" "ANN" "BAYES" "RF" "KNN")
   list(APPEND classifierList "BOOST" "DT" "ANN" "BAYES" "RF" "KNN")
-  if(NOT OTB_OPENCV_3)
-   set(dt_output_format "cv2.dt")
-  endif()
 endif()
 if(OTB_USE_SHARK)
   list(APPEND classifierList "SHARKRF" "SHARKKM")
diff --git a/Modules/Learning/Supervised/include/otbBoostMachineLearningModel.h b/Modules/Learning/Supervised/include/otbBoostMachineLearningModel.h
index 92d6121fd0..966b47a60f 100644
--- a/Modules/Learning/Supervised/include/otbBoostMachineLearningModel.h
+++ b/Modules/Learning/Supervised/include/otbBoostMachineLearningModel.h
@@ -27,11 +27,7 @@
 #include "itkFixedArray.h"
 #include "otbMachineLearningModel.h"
 
-#ifdef OTB_OPENCV_3
 #include "otbOpenCVUtils.h"
-#else
-class CvBoost;
-#endif
 
 namespace otb
 {
@@ -65,14 +61,6 @@ public:
   itkGetMacro(BoostType, int);
   itkSetMacro(BoostType, int);
 
-  /** Setters/Getters to the split criteria
-   *  It can be CvBoost::DEFAULT, CvBoost::GINI, CvBoost::MISCLASS, CvBoost::SQERR
-   *  Default is CvBoost::DEFAULT. It uses default value according to \c BoostType
-   *  \see http://docs.opencv.org/modules/ml/doc/boosting.html#cvboost-predict
-   */
-  itkGetMacro(SplitCrit, int);
-  itkSetMacro(SplitCrit, int);
-
   /** Setters/Getters to the number of weak classifiers.
    *  Default is 100.
    *  \see http://docs.opencv.org/modules/ml/doc/boosting.html#cvboostparams-cvboostparams
@@ -120,7 +108,7 @@ protected:
   BoostMachineLearningModel();
 
   /** Destructor */
-  ~BoostMachineLearningModel() override;
+  ~BoostMachineLearningModel() override = default;
 
   /** Predict values using the model */
   TargetSampleType DoPredict(const InputSampleType& input, ConfidenceValueType* quality = nullptr, ProbaSampleType* proba = nullptr) const override;
@@ -132,15 +120,11 @@ private:
   BoostMachineLearningModel(const Self&) = delete;
   void operator=(const Self&) = delete;
 
-#ifdef OTB_OPENCV_3
   cv::Ptr<cv::ml::Boost> m_BoostModel;
-#else
-  CvBoost* m_BoostModel;
-#endif
+
   int    m_BoostType;
   int    m_WeakCount;
   double m_WeightTrimRate;
-  int    m_SplitCrit;
   int    m_MaxDepth;
 };
 } // end namespace otb
diff --git a/Modules/Learning/Supervised/include/otbBoostMachineLearningModel.hxx b/Modules/Learning/Supervised/include/otbBoostMachineLearningModel.hxx
index 54a8f2aa9e..908c04b743 100644
--- a/Modules/Learning/Supervised/include/otbBoostMachineLearningModel.hxx
+++ b/Modules/Learning/Supervised/include/otbBoostMachineLearningModel.hxx
@@ -32,34 +32,15 @@ namespace otb
 
 template <class TInputValue, class TOutputValue>
 BoostMachineLearningModel<TInputValue, TOutputValue>::BoostMachineLearningModel()
-  :
-#ifdef OTB_OPENCV_3
-    m_BoostModel(cv::ml::Boost::create()),
-#else
-    m_BoostModel(new CvBoost),
-#endif
+  : m_BoostModel(cv::ml::Boost::create()),
     m_BoostType(CvBoost::REAL),
     m_WeakCount(100),
     m_WeightTrimRate(0.95),
-#ifdef OTB_OPENCV_3
-    m_SplitCrit(0), // not used in OpenCV 3.x
-#else
-    m_SplitCrit(CvBoost::DEFAULT),
-#endif
     m_MaxDepth(1)
 {
   this->m_ConfidenceIndex = true;
 }
 
-
-template <class TInputValue, class TOutputValue>
-BoostMachineLearningModel<TInputValue, TOutputValue>::~BoostMachineLearningModel()
-{
-#ifndef OTB_OPENCV_3
-  delete m_BoostModel;
-#endif
-}
-
 /** Train the machine learning model */
 template <class TInputValue, class TOutputValue>
 void BoostMachineLearningModel<TInputValue, TOutputValue>::Train()
@@ -75,7 +56,6 @@ void BoostMachineLearningModel<TInputValue, TOutputValue>::Train()
   var_type.setTo(cv::Scalar(CV_VAR_NUMERICAL)); // all inputs are numerical
   var_type.at<uchar>(this->GetInputListSample()->GetMeasurementVectorSize(), 0) = CV_VAR_CATEGORICAL;
 
-#ifdef OTB_OPENCV_3
   m_BoostModel->setBoostType(m_BoostType);
   m_BoostModel->setWeakCount(m_WeakCount);
   m_BoostModel->setWeightTrimRate(m_WeightTrimRate);
@@ -83,11 +63,6 @@ void BoostMachineLearningModel<TInputValue, TOutputValue>::Train()
   m_BoostModel->setUseSurrogates(false);
   m_BoostModel->setPriors(cv::Mat());
   m_BoostModel->train(cv::ml::TrainData::create(samples, cv::ml::ROW_SAMPLE, labels, cv::noArray(), cv::noArray(), cv::noArray(), var_type));
-#else
-  CvBoostParams params  = CvBoostParams(m_BoostType, m_WeakCount, m_WeightTrimRate, m_MaxDepth, false, nullptr);
-  params.split_criteria = m_SplitCrit;
-  m_BoostModel->train(samples, CV_ROW_SAMPLE, labels, cv::Mat(), cv::Mat(), var_type, cv::Mat(), params);
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
@@ -102,23 +77,11 @@ BoostMachineLearningModel<TInputValue, TOutputValue>::DoPredict(const InputSampl
   otb::SampleToMat<InputSampleType>(input, sample);
   double result = 0.;
 
-#ifdef OTB_OPENCV_3
   result = m_BoostModel->predict(sample);
-#else
-  cv::Mat missing = cv::Mat(1, input.Size(), CV_8U);
-  missing.setTo(0);
-  result = m_BoostModel->predict(sample, missing);
-#endif
 
   if (quality != nullptr)
   {
-    (*quality) = static_cast<ConfidenceValueType>(
-#ifdef OTB_OPENCV_3
-        m_BoostModel->predict(sample, cv::noArray(), cv::ml::StatModel::RAW_OUTPUT)
-#else
-        m_BoostModel->predict(sample, missing, cv::Range::all(), false, true)
-#endif
-            );
+    (*quality) = static_cast<ConfidenceValueType>(m_BoostModel->predict(sample, cv::noArray(), cv::ml::StatModel::RAW_OUTPUT));
   }
   if (proba != nullptr && !this->m_ProbaIndex)
     itkExceptionMacro("Probability per class not available for this classifier !");
@@ -130,32 +93,18 @@ BoostMachineLearningModel<TInputValue, TOutputValue>::DoPredict(const InputSampl
 template <class TInputValue, class TOutputValue>
 void BoostMachineLearningModel<TInputValue, TOutputValue>::Save(const std::string& filename, const std::string& name)
 {
-#ifdef OTB_OPENCV_3
   cv::FileStorage fs(filename, cv::FileStorage::WRITE);
   fs << (name.empty() ? m_BoostModel->getDefaultName() : cv::String(name)) << "{";
   m_BoostModel->write(fs);
   fs << "}";
   fs.release();
-#else
-  if (name == "")
-    m_BoostModel->save(filename.c_str(), nullptr);
-  else
-    m_BoostModel->save(filename.c_str(), name.c_str());
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
 void BoostMachineLearningModel<TInputValue, TOutputValue>::Load(const std::string& filename, const std::string& name)
 {
-#ifdef OTB_OPENCV_3
   cv::FileStorage fs(filename, cv::FileStorage::READ);
   m_BoostModel->read(name.empty() ? fs.getFirstTopLevelNode() : fs[name]);
-#else
-  if (name == "")
-    m_BoostModel->load(filename.c_str(), nullptr);
-  else
-    m_BoostModel->load(filename.c_str(), name.c_str());
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
@@ -176,11 +125,7 @@ bool BoostMachineLearningModel<TInputValue, TOutputValue>::CanReadFile(const std
     std::getline(ifs, line);
 
     // if (line.find(m_SVMModel->getName()) != std::string::npos)
-    if (line.find(CV_TYPE_NAME_ML_BOOSTING) != std::string::npos
-#ifdef OTB_OPENCV_3
-        || line.find(m_BoostModel->getDefaultName()) != std::string::npos
-#endif
-        )
+    if (line.find(CV_TYPE_NAME_ML_BOOSTING) != std::string::npos || line.find(m_BoostModel->getDefaultName()) != std::string::npos)
     {
       // std::cout<<"Reading a "<<CV_TYPE_NAME_ML_BOOSTING<<" model"<<std::endl;
       return true;
diff --git a/Modules/Learning/Supervised/include/otbCvRTreesWrapper.h b/Modules/Learning/Supervised/include/otbCvRTreesWrapper.h
index 5398430f03..6229bd0203 100644
--- a/Modules/Learning/Supervised/include/otbCvRTreesWrapper.h
+++ b/Modules/Learning/Supervised/include/otbCvRTreesWrapper.h
@@ -33,11 +33,7 @@ namespace otb
  * \ingroup OTBSupervised
  */
 class OTBSupervised_EXPORT CvRTreesWrapper
-#ifdef OTB_OPENCV_3
     : public cv::ml::RTrees
-#else
-    : public CvRTrees
-#endif
 {
 public:
   typedef std::vector<unsigned int> VotesVectorType;
@@ -60,7 +56,6 @@ public:
   */
   float predict_margin(const cv::Mat& sample, const cv::Mat& missing = cv::Mat()) const;
 
-#ifdef OTB_OPENCV_3
 
 #define OTB_CV_WRAP_PROPERTY(type, name)   \
   virtual type get##name() const override; \
@@ -83,6 +78,8 @@ public:
   OTB_CV_WRAP_PROPERTY(int, MaxDepth)
   OTB_CV_WRAP_PROPERTY(int, MinSampleCount)
   OTB_CV_WRAP_PROPERTY(bool, UseSurrogates)
+  
+  // warning: CV fold crash in openCV 3
   OTB_CV_WRAP_PROPERTY(int, CVFolds)
   OTB_CV_WRAP_PROPERTY(bool, Use1SERule)
   OTB_CV_WRAP_PROPERTY(bool, TruncatePrunedTree)
@@ -125,7 +122,6 @@ public:
 
 private:
   cv::Ptr<cv::ml::RTrees> m_Impl;
-#endif // OTB_OPENCV_3
 };
 }
 
diff --git a/Modules/Learning/Supervised/include/otbDecisionTreeMachineLearningModel.h b/Modules/Learning/Supervised/include/otbDecisionTreeMachineLearningModel.h
index e8a23d2bcd..c26a258749 100644
--- a/Modules/Learning/Supervised/include/otbDecisionTreeMachineLearningModel.h
+++ b/Modules/Learning/Supervised/include/otbDecisionTreeMachineLearningModel.h
@@ -27,11 +27,7 @@
 #include "itkFixedArray.h"
 #include "otbMachineLearningModel.h"
 
-#ifdef OTB_OPENCV_3
 #include "otbOpenCVUtils.h"
-#else
-class CvDTree;
-#endif
 
 namespace otb
 {
@@ -187,11 +183,7 @@ private:
   DecisionTreeMachineLearningModel(const Self&) = delete;
   void operator=(const Self&) = delete;
 
-#ifdef OTB_OPENCV_3
   cv::Ptr<cv::ml::DTrees> m_DTreeModel;
-#else
-  CvDTree* m_DTreeModel;
-#endif
 
   int                m_MaxDepth;
   int                m_MinSampleCount;
diff --git a/Modules/Learning/Supervised/include/otbDecisionTreeMachineLearningModel.hxx b/Modules/Learning/Supervised/include/otbDecisionTreeMachineLearningModel.hxx
index 228c397b31..95fd46ec09 100644
--- a/Modules/Learning/Supervised/include/otbDecisionTreeMachineLearningModel.hxx
+++ b/Modules/Learning/Supervised/include/otbDecisionTreeMachineLearningModel.hxx
@@ -33,7 +33,6 @@ namespace otb
 template <class TInputValue, class TOutputValue>
 DecisionTreeMachineLearningModel<TInputValue, TOutputValue>::DecisionTreeMachineLearningModel()
   :
-#ifdef OTB_OPENCV_3
     m_DTreeModel(cv::ml::DTrees::create()),
     m_MaxDepth(10),
     m_MinSampleCount(10),
@@ -41,15 +40,6 @@ DecisionTreeMachineLearningModel<TInputValue, TOutputValue>::DecisionTreeMachine
     m_UseSurrogates(false),
     m_MaxCategories(10),
     m_CVFolds(0),
-#else
-    m_DTreeModel(new CvDTree),
-    m_MaxDepth(INT_MAX),
-    m_MinSampleCount(10),
-    m_RegressionAccuracy(0.01),
-    m_UseSurrogates(true),
-    m_MaxCategories(10),
-    m_CVFolds(10),
-#endif
     m_Use1seRule(true),
     m_TruncatePrunedTree(true)
 {
@@ -59,9 +49,6 @@ DecisionTreeMachineLearningModel<TInputValue, TOutputValue>::DecisionTreeMachine
 template <class TInputValue, class TOutputValue>
 DecisionTreeMachineLearningModel<TInputValue, TOutputValue>::~DecisionTreeMachineLearningModel()
 {
-#ifndef OTB_OPENCV_3
-  delete m_DTreeModel;
-#endif
 }
 
 /** Train the machine learning model */
@@ -81,7 +68,6 @@ void DecisionTreeMachineLearningModel<TInputValue, TOutputValue>::Train()
   if (!this->m_RegressionMode) // Classification
     var_type.at<uchar>(this->GetInputListSample()->GetMeasurementVectorSize(), 0) = CV_VAR_CATEGORICAL;
 
-#ifdef OTB_OPENCV_3
   m_DTreeModel->setMaxDepth(m_MaxDepth);
   m_DTreeModel->setMinSampleCount(m_MinSampleCount);
   m_DTreeModel->setRegressionAccuracy(m_RegressionAccuracy);
@@ -92,15 +78,6 @@ void DecisionTreeMachineLearningModel<TInputValue, TOutputValue>::Train()
   m_DTreeModel->setTruncatePrunedTree(m_TruncatePrunedTree);
   m_DTreeModel->setPriors(cv::Mat(m_Priors));
   m_DTreeModel->train(cv::ml::TrainData::create(samples, cv::ml::ROW_SAMPLE, labels, cv::noArray(), cv::noArray(), cv::noArray(), var_type));
-#else
-  float* priors = m_Priors.empty() ? nullptr : &m_Priors.front();
-
-  CvDTreeParams params = CvDTreeParams(m_MaxDepth, m_MinSampleCount, m_RegressionAccuracy, m_UseSurrogates, m_MaxCategories, m_CVFolds, m_Use1seRule,
-                                       m_TruncatePrunedTree, priors);
-
-  // train the Decision Tree model
-  m_DTreeModel->train(samples, CV_ROW_SAMPLE, labels, cv::Mat(), cv::Mat(), var_type, cv::Mat(), params);
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
@@ -113,11 +90,7 @@ DecisionTreeMachineLearningModel<TInputValue, TOutputValue>::DoPredict(const Inp
   cv::Mat sample;
 
   otb::SampleToMat<InputSampleType>(input, sample);
-#ifdef OTB_OPENCV_3
   double result = m_DTreeModel->predict(sample);
-#else
-  double result = m_DTreeModel->predict(sample, cv::Mat(), false)->value;
-#endif
 
   target[0] = static_cast<TOutputValue>(result);
 
@@ -137,32 +110,18 @@ DecisionTreeMachineLearningModel<TInputValue, TOutputValue>::DoPredict(const Inp
 template <class TInputValue, class TOutputValue>
 void DecisionTreeMachineLearningModel<TInputValue, TOutputValue>::Save(const std::string& filename, const std::string& name)
 {
-#ifdef OTB_OPENCV_3
   cv::FileStorage fs(filename, cv::FileStorage::WRITE);
   fs << (name.empty() ? m_DTreeModel->getDefaultName() : cv::String(name)) << "{";
   m_DTreeModel->write(fs);
   fs << "}";
   fs.release();
-#else
-  if (name == "")
-    m_DTreeModel->save(filename.c_str(), nullptr);
-  else
-    m_DTreeModel->save(filename.c_str(), name.c_str());
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
 void DecisionTreeMachineLearningModel<TInputValue, TOutputValue>::Load(const std::string& filename, const std::string& name)
 {
-#ifdef OTB_OPENCV_3
   cv::FileStorage fs(filename, cv::FileStorage::READ);
   m_DTreeModel->read(name.empty() ? fs.getFirstTopLevelNode() : fs[name]);
-#else
-  if (name == "")
-    m_DTreeModel->load(filename.c_str(), nullptr);
-  else
-    m_DTreeModel->load(filename.c_str(), name.c_str());
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
@@ -183,13 +142,8 @@ bool DecisionTreeMachineLearningModel<TInputValue, TOutputValue>::CanReadFile(co
     std::getline(ifs, line);
 
     // if (line.find(m_SVMModel->getName()) != std::string::npos)
-    if (line.find(CV_TYPE_NAME_ML_TREE) != std::string::npos
-#ifdef OTB_OPENCV_3
-        || line.find(m_DTreeModel->getDefaultName()) != std::string::npos
-#endif
-        )
+    if (line.find(CV_TYPE_NAME_ML_TREE) != std::string::npos || line.find(m_DTreeModel->getDefaultName()) != std::string::npos)
     {
-      // std::cout<<"Reading a "<<CV_TYPE_NAME_ML_TREE<<" model"<<std::endl;
       return true;
     }
   }
diff --git a/Modules/Learning/Supervised/include/otbKNearestNeighborsMachineLearningModel.h b/Modules/Learning/Supervised/include/otbKNearestNeighborsMachineLearningModel.h
index 887dcc659d..ed96f66a76 100644
--- a/Modules/Learning/Supervised/include/otbKNearestNeighborsMachineLearningModel.h
+++ b/Modules/Learning/Supervised/include/otbKNearestNeighborsMachineLearningModel.h
@@ -27,11 +27,7 @@
 #include "itkFixedArray.h"
 #include "otbMachineLearningModel.h"
 
-#ifdef OTB_OPENCV_3
 #include "otbOpenCVUtils.h"
-#else
-class CvKNearest;
-#endif
 
 namespace otb
 {
@@ -117,11 +113,8 @@ private:
   KNearestNeighborsMachineLearningModel(const Self&) = delete;
   void operator=(const Self&) = delete;
 
-#ifdef OTB_OPENCV_3
   cv::Ptr<cv::ml::KNearest> m_KNearestModel;
-#else
-  CvKNearest* m_KNearestModel;
-#endif
+
   int m_K;
 
   int m_DecisionRule;
diff --git a/Modules/Learning/Supervised/include/otbKNearestNeighborsMachineLearningModel.hxx b/Modules/Learning/Supervised/include/otbKNearestNeighborsMachineLearningModel.hxx
index 6fefbd9f56..3b1ed213d0 100644
--- a/Modules/Learning/Supervised/include/otbKNearestNeighborsMachineLearningModel.hxx
+++ b/Modules/Learning/Supervised/include/otbKNearestNeighborsMachineLearningModel.hxx
@@ -35,11 +35,7 @@ namespace otb
 template <class TInputValue, class TTargetValue>
 KNearestNeighborsMachineLearningModel<TInputValue, TTargetValue>::KNearestNeighborsMachineLearningModel()
   :
-#ifdef OTB_OPENCV_3
     m_KNearestModel(cv::ml::KNearest::create()),
-#else
-    m_KNearestModel(new CvKNearest),
-#endif
     m_K(32),
     m_DecisionRule(KNN_VOTING)
 {
@@ -51,9 +47,6 @@ KNearestNeighborsMachineLearningModel<TInputValue, TTargetValue>::KNearestNeighb
 template <class TInputValue, class TTargetValue>
 KNearestNeighborsMachineLearningModel<TInputValue, TTargetValue>::~KNearestNeighborsMachineLearningModel()
 {
-#ifndef OTB_OPENCV_3
-  delete m_KNearestModel;
-#endif
 }
 
 /** Train the machine learning model */
@@ -83,17 +76,12 @@ void KNearestNeighborsMachineLearningModel<TInputValue, TTargetValue>::Train()
     }
   }
 
-#ifdef OTB_OPENCV_3
   m_KNearestModel->setDefaultK(m_K);
   // would be nice to expose KDTree mode ( maybe in a different classifier)
   m_KNearestModel->setAlgorithmType(cv::ml::KNearest::BRUTE_FORCE);
   m_KNearestModel->setIsClassifier(!this->m_RegressionMode);
   // setEmax() ?
   m_KNearestModel->train(cv::ml::TrainData::create(samples, cv::ml::ROW_SAMPLE, labels));
-#else
-  // train the KNN model
-  m_KNearestModel->train(samples, labels, cv::Mat(), this->m_RegressionMode, m_K, false);
-#endif
 }
 
 template <class TInputValue, class TTargetValue>
@@ -109,11 +97,8 @@ KNearestNeighborsMachineLearningModel<TInputValue, TTargetValue>::DoPredict(cons
 
   float   result;
   cv::Mat nearest(1, m_K, CV_32FC1);
-#ifdef OTB_OPENCV_3
   result = m_KNearestModel->findNearest(sample, m_K, cv::noArray(), nearest, cv::noArray());
-#else
-  result = m_KNearestModel->find_nearest(sample, m_K, nullptr, nullptr, &nearest, nullptr);
-#endif
+
   // compute quality if asked (only happens in classification mode)
   if (quality != nullptr)
   {
@@ -157,47 +142,12 @@ KNearestNeighborsMachineLearningModel<TInputValue, TTargetValue>::DoPredict(cons
 template <class TInputValue, class TTargetValue>
 void KNearestNeighborsMachineLearningModel<TInputValue, TTargetValue>::Save(const std::string& filename, const std::string& name)
 {
-#ifdef OTB_OPENCV_3
   cv::FileStorage fs(filename, cv::FileStorage::WRITE);
   fs << (name.empty() ? m_KNearestModel->getDefaultName() : cv::String(name)) << "{";
   m_KNearestModel->write(fs);
   fs << "DecisionRule" << m_DecisionRule;
   fs << "}";
   fs.release();
-#else
-  (void)name;
-  // there is no m_KNearestModel->save(filename.c_str(), name.c_str()).
-  // We need to save the K parameter, IsRegression flag, DecisionRule and the samples.
-
-  std::ofstream ofs(filename);
-  // Save K parameter and IsRegression flag.
-  ofs << "K=" << m_K << "\n";
-  ofs << "IsRegression=" << this->m_RegressionMode << "\n";
-  // Save the DecisionRule if regression
-  if (this->m_RegressionMode)
-  {
-    ofs << "DecisionRule=" << m_DecisionRule << "\n";
-  }
-
-  // Save the samples. First column is the Label and other columns are the sample data.
-  typename InputListSampleType::ConstIterator  sampleIt   = this->GetInputListSample()->Begin();
-  typename TargetListSampleType::ConstIterator labelIt    = this->GetTargetListSample()->Begin();
-  const unsigned int                           sampleSize = this->GetInputListSample()->GetMeasurementVectorSize();
-  for (; sampleIt != this->GetInputListSample()->End(); ++sampleIt, ++labelIt)
-  {
-    // Retrieve sample
-    typename InputListSampleType::MeasurementVectorType sample = sampleIt.GetMeasurementVector();
-    ofs << labelIt.GetMeasurementVector()[0];
-
-    // Loop on sample size
-    for (unsigned int i = 0; i < sampleSize; ++i)
-    {
-      ofs << " " << sample[i];
-    }
-    ofs << "\n";
-  }
-  ofs.close();
-#endif
 }
 
 template <class TInputValue, class TTargetValue>
@@ -208,7 +158,6 @@ void KNearestNeighborsMachineLearningModel<TInputValue, TTargetValue>::Load(cons
   {
     itkExceptionMacro(<< "Could not read file " << filename);
   }
-#ifdef OTB_OPENCV_3
   // try to load with the 3.x syntax
   bool isKNNv3 = false;
   while (!ifs.eof())
@@ -230,7 +179,6 @@ void KNearestNeighborsMachineLearningModel<TInputValue, TTargetValue>::Load(cons
     return;
   }
   ifs.open(filename);
-#endif
   // there is no m_KNearestModel->load(filename.c_str(), name.c_str());
 
   // first line is the K parameter of this algorithm.
diff --git a/Modules/Learning/Supervised/include/otbNeuralNetworkMachineLearningModel.h b/Modules/Learning/Supervised/include/otbNeuralNetworkMachineLearningModel.h
index 0cde70c93d..32317f9ca7 100644
--- a/Modules/Learning/Supervised/include/otbNeuralNetworkMachineLearningModel.h
+++ b/Modules/Learning/Supervised/include/otbNeuralNetworkMachineLearningModel.h
@@ -174,7 +174,7 @@ protected:
   NeuralNetworkMachineLearningModel();
 
   /** Destructor */
-  ~NeuralNetworkMachineLearningModel() override;
+  ~NeuralNetworkMachineLearningModel() override = default;
 
   /** Predict values using the model */
   TargetSampleType DoPredict(const InputSampleType& input, ConfidenceValueType* quality = nullptr, ProbaSampleType* proba = nullptr) const override;
@@ -190,12 +190,7 @@ private:
 
   void CreateNetwork();
   void SetupNetworkAndTrain(cv::Mat& labels);
-#ifdef OTB_OPENCV_3
   cv::Ptr<cv::ml::ANN_MLP> m_ANNModel;
-#else
-  CvANN_MLP_TrainParams SetNetworkParameters();
-  CvANN_MLP*            m_ANNModel;
-#endif
   int                       m_TrainMethod;
   int                       m_ActivateFunction;
   std::vector<unsigned int> m_LayerSizes;
diff --git a/Modules/Learning/Supervised/include/otbNeuralNetworkMachineLearningModel.hxx b/Modules/Learning/Supervised/include/otbNeuralNetworkMachineLearningModel.hxx
index 9389aa5ae8..dd1169141a 100644
--- a/Modules/Learning/Supervised/include/otbNeuralNetworkMachineLearningModel.hxx
+++ b/Modules/Learning/Supervised/include/otbNeuralNetworkMachineLearningModel.hxx
@@ -31,12 +31,7 @@ namespace otb
 template <class TInputValue, class TOutputValue>
 NeuralNetworkMachineLearningModel<TInputValue, TOutputValue>::NeuralNetworkMachineLearningModel()
   :
-#ifdef OTB_OPENCV_3
     m_ANNModel(cv::ml::ANN_MLP::create()),
-// TODO
-#else
-    m_ANNModel(new CvANN_MLP),
-#endif
     m_TrainMethod(CvANN_MLP_TrainParams::RPROP),
     m_ActivateFunction(CvANN_MLP::SIGMOID_SYM),
     m_Alpha(1.),
@@ -53,14 +48,6 @@ NeuralNetworkMachineLearningModel<TInputValue, TOutputValue>::NeuralNetworkMachi
   this->m_IsRegressionSupported = true;
 }
 
-template <class TInputValue, class TOutputValue>
-NeuralNetworkMachineLearningModel<TInputValue, TOutputValue>::~NeuralNetworkMachineLearningModel()
-{
-#ifndef OTB_OPENCV_3
-  delete m_ANNModel;
-#endif
-}
-
 /** Sets the topology of the NN */
 template <class TInputValue, class TOutputValue>
 void NeuralNetworkMachineLearningModel<TInputValue, TOutputValue>::SetLayerSizes(const std::vector<unsigned int> layers)
@@ -148,29 +135,10 @@ void NeuralNetworkMachineLearningModel<TInputValue, TOutputValue>::CreateNetwork
     layers.row(i) = m_LayerSizes[i];
   }
 
-#ifdef OTB_OPENCV_3
   m_ANNModel->setLayerSizes(layers);
   m_ANNModel->setActivationFunction(m_ActivateFunction, m_Alpha, m_Beta);
-#else
-  m_ANNModel->create(layers, m_ActivateFunction, m_Alpha, m_Beta);
-#endif
 }
 
-#ifndef OTB_OPENCV_3
-template <class TInputValue, class TOutputValue>
-CvANN_MLP_TrainParams NeuralNetworkMachineLearningModel<TInputValue, TOutputValue>::SetNetworkParameters()
-{
-  CvANN_MLP_TrainParams params;
-  params.train_method      = m_TrainMethod;
-  params.bp_dw_scale       = m_BackPropDWScale;
-  params.bp_moment_scale   = m_BackPropMomentScale;
-  params.rp_dw0            = m_RegPropDW0;
-  params.rp_dw_min         = m_RegPropDWMin;
-  CvTermCriteria term_crit = cvTermCriteria(m_TermCriteriaType, m_MaxIter, m_Epsilon);
-  params.term_crit         = term_crit;
-  return params;
-}
-#endif
 
 template <class TInputValue, class TOutputValue>
 void NeuralNetworkMachineLearningModel<TInputValue, TOutputValue>::SetupNetworkAndTrain(cv::Mat& labels)
@@ -179,7 +147,6 @@ void NeuralNetworkMachineLearningModel<TInputValue, TOutputValue>::SetupNetworkA
   cv::Mat samples;
   otb::ListSampleToMat<InputListSampleType>(this->GetInputListSample(), samples);
   this->CreateNetwork();
-#ifdef OTB_OPENCV_3
   int flags = (this->m_RegressionMode ? 0 : cv::ml::ANN_MLP::NO_OUTPUT_SCALE);
   m_ANNModel->setTrainMethod(m_TrainMethod);
   m_ANNModel->setBackpropMomentumScale(m_BackPropMomentScale);
@@ -191,11 +158,6 @@ void NeuralNetworkMachineLearningModel<TInputValue, TOutputValue>::SetupNetworkA
   // m_ANNModel->setRpropDWPlus( );
   m_ANNModel->setTermCriteria(cv::TermCriteria(m_TermCriteriaType, m_MaxIter, m_Epsilon));
   m_ANNModel->train(cv::ml::TrainData::create(samples, cv::ml::ROW_SAMPLE, labels), flags);
-#else
-  CvANN_MLP_TrainParams params = this->SetNetworkParameters();
-  // train the Neural network model
-  m_ANNModel->train(samples, labels, cv::Mat(), cv::Mat(), params);
-#endif
 }
 
 /** Train the machine learning model for classification*/
@@ -279,7 +241,6 @@ NeuralNetworkMachineLearningModel<TInputValue, TOutputValue>::DoPredict(const In
 template <class TInputValue, class TOutputValue>
 void NeuralNetworkMachineLearningModel<TInputValue, TOutputValue>::Save(const std::string& filename, const std::string& name)
 {
-#ifdef OTB_OPENCV_3
   cv::FileStorage fs(filename, cv::FileStorage::WRITE);
   fs << (name.empty() ? m_ANNModel->getDefaultName() : cv::String(name)) << "{";
   m_ANNModel->write(fs);
@@ -290,65 +251,16 @@ void NeuralNetworkMachineLearningModel<TInputValue, TOutputValue>::Save(const st
   }
   fs << "}";
   fs.release();
-#else
-  const char* lname = "my_nn";
-  if (!name.empty())
-    lname = name.c_str();
-
-  CvFileStorage* fs = nullptr;
-  fs                = cvOpenFileStorage(filename.c_str(), nullptr, CV_STORAGE_WRITE);
-  if (!fs)
-  {
-    itkExceptionMacro("Could not open the file " << filename << " for writing");
-  }
-
-  m_ANNModel->write(fs, lname);
-  if (!m_MatrixOfLabels.empty())
-  {
-    // cvWrite can't write cv::Mat
-    auto tmpMat = CvMat(m_MatrixOfLabels);
-    cvWrite(fs, "class_labels", &tmpMat);
-  }
-  cvReleaseFileStorage(&fs);
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
 void NeuralNetworkMachineLearningModel<TInputValue, TOutputValue>::Load(const std::string& filename, const std::string& name)
 {
-#ifdef OTB_OPENCV_3
   cv::FileStorage fs(filename, cv::FileStorage::READ);
   cv::FileNode    model_node(name.empty() ? fs.getFirstTopLevelNode() : fs[name]);
   m_ANNModel->read(model_node);
   model_node["class_labels"] >> m_MatrixOfLabels;
   fs.release();
-#else
-  const char* lname = nullptr;
-  if (!name.empty())
-    lname = name.c_str();
-
-  cv::FileNode    model_node;
-  cv::FileStorage fs(filename, cv::FileStorage::READ);
-  if (!fs.isOpened())
-  {
-    itkExceptionMacro("Could not open the file " << filename << " for reading");
-  }
-
-  if (lname)
-    model_node = fs[lname];
-  else
-  {
-    cv::FileNode root = fs.root();
-    if (root.size() > 0)
-    {
-      model_node = *(root.begin());
-    }
-  }
-
-  m_ANNModel->read(*fs,*model_node);
-  model_node["class_labels"] >> m_MatrixOfLabels;
-  fs.release();
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
@@ -368,11 +280,7 @@ bool NeuralNetworkMachineLearningModel<TInputValue, TOutputValue>::CanReadFile(c
     std::string line;
     std::getline(ifs, line);
 
-    if (line.find(CV_TYPE_NAME_ML_ANN_MLP) != std::string::npos
-#ifdef OTB_OPENCV_3
-        || line.find(m_ANNModel->getDefaultName()) != std::string::npos
-#endif
-        )
+    if (line.find(CV_TYPE_NAME_ML_ANN_MLP) != std::string::npos || line.find(m_ANNModel->getDefaultName()) != std::string::npos)
     {
       return true;
     }
diff --git a/Modules/Learning/Supervised/include/otbNormalBayesMachineLearningModel.h b/Modules/Learning/Supervised/include/otbNormalBayesMachineLearningModel.h
index f1d94f24ca..ed42dd2de6 100644
--- a/Modules/Learning/Supervised/include/otbNormalBayesMachineLearningModel.h
+++ b/Modules/Learning/Supervised/include/otbNormalBayesMachineLearningModel.h
@@ -27,11 +27,7 @@
 #include "itkFixedArray.h"
 #include "otbMachineLearningModel.h"
 
-#ifdef OTB_OPENCV_3
 #include "otbOpenCVUtils.h"
-#else
-class CvNormalBayesClassifier;
-#endif
 
 namespace otb
 {
@@ -80,7 +76,7 @@ protected:
   NormalBayesMachineLearningModel();
 
   /** Destructor */
-  ~NormalBayesMachineLearningModel() override;
+  ~NormalBayesMachineLearningModel() override = default;
 
   /** Predict values using the model */
   TargetSampleType DoPredict(const InputSampleType& input, ConfidenceValueType* quality = nullptr, ProbaSampleType* proba = nullptr) const override;
@@ -91,11 +87,7 @@ protected:
 private:
   NormalBayesMachineLearningModel(const Self&) = delete;
   void operator=(const Self&) = delete;
-#ifdef OTB_OPENCV_3
   cv::Ptr<cv::ml::NormalBayesClassifier> m_NormalBayesModel;
-#else
-  CvNormalBayesClassifier* m_NormalBayesModel;
-#endif
 };
 } // end namespace otb
 
diff --git a/Modules/Learning/Supervised/include/otbNormalBayesMachineLearningModel.hxx b/Modules/Learning/Supervised/include/otbNormalBayesMachineLearningModel.hxx
index df55a91b7e..16832e3028 100644
--- a/Modules/Learning/Supervised/include/otbNormalBayesMachineLearningModel.hxx
+++ b/Modules/Learning/Supervised/include/otbNormalBayesMachineLearningModel.hxx
@@ -31,24 +31,10 @@ namespace otb
 
 template <class TInputValue, class TOutputValue>
 NormalBayesMachineLearningModel<TInputValue, TOutputValue>::NormalBayesMachineLearningModel()
-  :
-#ifdef OTB_OPENCV_3
-    m_NormalBayesModel(cv::ml::NormalBayesClassifier::create())
-#else
-    m_NormalBayesModel(new CvNormalBayesClassifier)
-#endif
+  : m_NormalBayesModel(cv::ml::NormalBayesClassifier::create())
 {
 }
 
-
-template <class TInputValue, class TOutputValue>
-NormalBayesMachineLearningModel<TInputValue, TOutputValue>::~NormalBayesMachineLearningModel()
-{
-#ifndef OTB_OPENCV_3
-  delete m_NormalBayesModel;
-#endif
-}
-
 /** Train the machine learning model */
 template <class TInputValue, class TOutputValue>
 void NormalBayesMachineLearningModel<TInputValue, TOutputValue>::Train()
@@ -60,15 +46,11 @@ void NormalBayesMachineLearningModel<TInputValue, TOutputValue>::Train()
   cv::Mat labels;
   otb::ListSampleToMat<TargetListSampleType>(this->GetTargetListSample(), labels);
 
-#ifdef OTB_OPENCV_3
   cv::Mat var_type = cv::Mat(this->GetInputListSample()->GetMeasurementVectorSize() + 1, 1, CV_8U);
   var_type.setTo(cv::Scalar(CV_VAR_NUMERICAL)); // all inputs are numerical
   var_type.at<uchar>(this->GetInputListSample()->GetMeasurementVectorSize(), 0) = CV_VAR_CATEGORICAL;
 
   m_NormalBayesModel->train(cv::ml::TrainData::create(samples, cv::ml::ROW_SAMPLE, labels, cv::noArray(), cv::noArray(), cv::noArray(), var_type));
-#else
-  m_NormalBayesModel->train(samples, labels, cv::Mat(), cv::Mat(), false);
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
@@ -104,32 +86,18 @@ NormalBayesMachineLearningModel<TInputValue, TOutputValue>::DoPredict(const Inpu
 template <class TInputValue, class TOutputValue>
 void NormalBayesMachineLearningModel<TInputValue, TOutputValue>::Save(const std::string& filename, const std::string& name)
 {
-#ifdef OTB_OPENCV_3
   cv::FileStorage fs(filename, cv::FileStorage::WRITE);
   fs << (name.empty() ? m_NormalBayesModel->getDefaultName() : cv::String(name)) << "{";
   m_NormalBayesModel->write(fs);
   fs << "}";
   fs.release();
-#else
-  if (name == "")
-    m_NormalBayesModel->save(filename.c_str(), nullptr);
-  else
-    m_NormalBayesModel->save(filename.c_str(), name.c_str());
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
 void NormalBayesMachineLearningModel<TInputValue, TOutputValue>::Load(const std::string& filename, const std::string& name)
 {
-#ifdef OTB_OPENCV_3
   cv::FileStorage fs(filename, cv::FileStorage::READ);
   m_NormalBayesModel->read(name.empty() ? fs.getFirstTopLevelNode() : fs[name]);
-#else
-  if (name == "")
-    m_NormalBayesModel->load(filename.c_str(), nullptr);
-  else
-    m_NormalBayesModel->load(filename.c_str(), name.c_str());
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
@@ -149,13 +117,8 @@ bool NormalBayesMachineLearningModel<TInputValue, TOutputValue>::CanReadFile(con
     std::string line;
     std::getline(ifs, line);
 
-    if (line.find(CV_TYPE_NAME_ML_NBAYES) != std::string::npos
-#ifdef OTB_OPENCV_3
-        || line.find(m_NormalBayesModel->getDefaultName()) != std::string::npos
-#endif
-        )
+    if (line.find(CV_TYPE_NAME_ML_NBAYES) != std::string::npos || line.find(m_NormalBayesModel->getDefaultName()) != std::string::npos)
     {
-      // std::cout<<"Reading a "<<CV_TYPE_NAME_ML_NBAYES<<" model"<<std::endl;
       return true;
     }
   }
diff --git a/Modules/Learning/Supervised/include/otbOpenCVUtils.h b/Modules/Learning/Supervised/include/otbOpenCVUtils.h
index 2992037f13..d846b7750a 100644
--- a/Modules/Learning/Supervised/include/otbOpenCVUtils.h
+++ b/Modules/Learning/Supervised/include/otbOpenCVUtils.h
@@ -47,7 +47,6 @@
 
 #include "itkListSample.h"
 
-#ifdef OTB_OPENCV_3
 #define CV_TYPE_NAME_ML_SVM "opencv-ml-svm"
 #define CV_TYPE_NAME_ML_RTREES "opencv-ml-random-trees"
 #define CV_TYPE_NAME_ML_BOOSTING "opencv-ml-boost-tree"
@@ -62,7 +61,7 @@
 
 #define CV_VAR_NUMERICAL cv::ml::VAR_NUMERICAL
 #define CV_VAR_CATEGORICAL cv::ml::VAR_CATEGORICAL
-#endif
+
 
 namespace otb
 {
diff --git a/Modules/Learning/Supervised/include/otbRandomForestsMachineLearningModel.h b/Modules/Learning/Supervised/include/otbRandomForestsMachineLearningModel.h
index ee53c3f33e..965e63397a 100644
--- a/Modules/Learning/Supervised/include/otbRandomForestsMachineLearningModel.h
+++ b/Modules/Learning/Supervised/include/otbRandomForestsMachineLearningModel.h
@@ -133,7 +133,7 @@ protected:
   RandomForestsMachineLearningModel();
 
   /** Destructor */
-  ~RandomForestsMachineLearningModel() override;
+  ~RandomForestsMachineLearningModel() override = default;
 
   /** Predict values using the model */
   TargetSampleType DoPredict(const InputSampleType& input, ConfidenceValueType* quality = nullptr, ProbaSampleType* proba = nullptr) const override;
@@ -151,11 +151,8 @@ private:
   RandomForestsMachineLearningModel(const Self&) = delete;
   void operator=(const Self&) = delete;
 
-#ifdef OTB_OPENCV_3
   cv::Ptr<CvRTreesWrapper> m_RFModel;
-#else
-  CvRTreesWrapper* m_RFModel;
-#endif
+
   /** The depth of the tree. A low value will likely underfit and conversely a
    * high value will likely overfit. The optimal value can be obtained using cross
    * validation or other suitable methods. */
diff --git a/Modules/Learning/Supervised/include/otbRandomForestsMachineLearningModel.hxx b/Modules/Learning/Supervised/include/otbRandomForestsMachineLearningModel.hxx
index 567faa29dd..c5a2f7c48d 100644
--- a/Modules/Learning/Supervised/include/otbRandomForestsMachineLearningModel.hxx
+++ b/Modules/Learning/Supervised/include/otbRandomForestsMachineLearningModel.hxx
@@ -32,11 +32,7 @@ namespace otb
 template <class TInputValue, class TOutputValue>
 RandomForestsMachineLearningModel<TInputValue, TOutputValue>::RandomForestsMachineLearningModel()
   :
-#ifdef OTB_OPENCV_3
     m_RFModel(CvRTreesWrapper::create()),
-#else
-    m_RFModel(new CvRTreesWrapper),
-#endif
     m_MaxDepth(5),
     m_MinSampleCount(10),
     m_RegressionAccuracy(0.01),
@@ -54,19 +50,9 @@ RandomForestsMachineLearningModel<TInputValue, TOutputValue>::RandomForestsMachi
   this->m_IsRegressionSupported = true;
 }
 
-
-template <class TInputValue, class TOutputValue>
-RandomForestsMachineLearningModel<TInputValue, TOutputValue>::~RandomForestsMachineLearningModel()
-{
-#ifndef OTB_OPENCV_3
-  delete m_RFModel;
-#endif
-}
-
 template <class TInputValue, class TOutputValue>
 float RandomForestsMachineLearningModel<TInputValue, TOutputValue>::GetTrainError()
 {
-#ifdef OTB_OPENCV_3
   // TODO
   cv::Mat samples;
   otb::ListSampleToMat<InputListSampleType>(this->GetInputListSample(), samples);
@@ -84,9 +70,6 @@ float RandomForestsMachineLearningModel<TInputValue, TOutputValue>::GetTrainErro
 
   return m_RFModel->calcError(cv::ml::TrainData::create(samples, cv::ml::ROW_SAMPLE, labels, cv::noArray(), cv::noArray(), cv::noArray(), var_type), false,
                               cv::noArray());
-#else
-  return m_RFModel->get_train_error();
-#endif
 }
 
 /** Train the machine learning model */
@@ -112,7 +95,6 @@ void RandomForestsMachineLearningModel<TInputValue, TOutputValue>::Train()
 // std::cout << "priors " << m_Priors[0] << std::endl;
 // Define random forests paramneters
 // FIXME do this in the constructor?
-#ifdef OTB_OPENCV_3
   m_RFModel->setMaxDepth(m_MaxDepth);
   m_RFModel->setMinSampleCount(m_MinSampleCount);
   m_RFModel->setRegressionAccuracy(m_RegressionAccuracy);
@@ -123,24 +105,6 @@ void RandomForestsMachineLearningModel<TInputValue, TOutputValue>::Train()
   m_RFModel->setActiveVarCount(m_MaxNumberOfVariables);
   m_RFModel->setTermCriteria(cv::TermCriteria(m_TerminationCriteria, m_MaxNumberOfTrees, m_ForestAccuracy));
   m_RFModel->train(cv::ml::TrainData::create(samples, cv::ml::ROW_SAMPLE, labels, cv::noArray(), cv::noArray(), cv::noArray(), var_type));
-#else
-  float* priors = m_Priors.empty() ? nullptr : &m_Priors.front();
-
-  CvRTParams params = CvRTParams(m_MaxDepth,                    // max depth
-                                 m_MinSampleCount,              // min sample count
-                                 m_RegressionAccuracy,          // regression accuracy: N/A here
-                                 m_ComputeSurrogateSplit,       // compute surrogate split, no missing data
-                                 m_MaxNumberOfCategories,       // max number of categories (use sub-optimal algorithm for larger numbers)
-                                 priors,                        // the array of priors
-                                 m_CalculateVariableImportance, // calculate variable importance
-                                 m_MaxNumberOfVariables,        // number of variables randomly selected at node and used to find the best split(s).
-                                 m_MaxNumberOfTrees,            // max number of trees in the forest
-                                 m_ForestAccuracy,              // forest accuracy
-                                 m_TerminationCriteria          // termination criteria
-                                 );
-  // train the RT model
-  m_RFModel->train(samples, CV_ROW_SAMPLE, labels, cv::Mat(), cv::Mat(), var_type, cv::Mat(), params);
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
@@ -176,32 +140,18 @@ RandomForestsMachineLearningModel<TInputValue, TOutputValue>::DoPredict(const In
 template <class TInputValue, class TOutputValue>
 void RandomForestsMachineLearningModel<TInputValue, TOutputValue>::Save(const std::string& filename, const std::string& name)
 {
-#ifdef OTB_OPENCV_3
   cv::FileStorage fs(filename, cv::FileStorage::WRITE);
   fs << (name.empty() ? m_RFModel->getDefaultName() : cv::String(name)) << "{";
   m_RFModel->write(fs);
   fs << "}";
   fs.release();
-#else
-  if (name == "")
-    m_RFModel->save(filename.c_str(), nullptr);
-  else
-    m_RFModel->save(filename.c_str(), name.c_str());
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
 void RandomForestsMachineLearningModel<TInputValue, TOutputValue>::Load(const std::string& filename, const std::string& name)
 {
-#ifdef OTB_OPENCV_3
   cv::FileStorage fs(filename, cv::FileStorage::READ);
   m_RFModel->read(name.empty() ? fs.getFirstTopLevelNode() : fs[name]);
-#else
-  if (name == "")
-    m_RFModel->load(filename.c_str(), nullptr);
-  else
-    m_RFModel->load(filename.c_str(), name.c_str());
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
@@ -223,13 +173,8 @@ bool RandomForestsMachineLearningModel<TInputValue, TOutputValue>::CanReadFile(c
     std::getline(ifs, line);
 
     // if (line.find(m_RFModel->getName()) != std::string::npos)
-    if (line.find(CV_TYPE_NAME_ML_RTREES) != std::string::npos
-#ifdef OTB_OPENCV_3
-        || line.find(m_RFModel->getDefaultName()) != std::string::npos
-#endif
-        )
+    if (line.find(CV_TYPE_NAME_ML_RTREES) != std::string::npos || line.find(m_RFModel->getDefaultName()) != std::string::npos)
     {
-      // std::cout<<"Reading a "<<CV_TYPE_NAME_ML_RTREES<<" model"<<std::endl;
       return true;
     }
   }
diff --git a/Modules/Learning/Supervised/include/otbSVMMachineLearningModel.h b/Modules/Learning/Supervised/include/otbSVMMachineLearningModel.h
index f24a5d564c..8642380290 100644
--- a/Modules/Learning/Supervised/include/otbSVMMachineLearningModel.h
+++ b/Modules/Learning/Supervised/include/otbSVMMachineLearningModel.h
@@ -26,11 +26,7 @@
 #include "itkFixedArray.h"
 #include "otbMachineLearningModel.h"
 
-#ifdef OTB_OPENCV_3
 #include "otbOpenCVUtils.h"
-#else
-class CvSVM;
-#endif
 
 namespace otb
 {
@@ -137,7 +133,7 @@ protected:
   SVMMachineLearningModel();
 
   /** Destructor */
-  ~SVMMachineLearningModel() override;
+  ~SVMMachineLearningModel() override = default;
 
   /** Predict values using the model */
   TargetSampleType DoPredict(const InputSampleType& input, ConfidenceValueType* quality = nullptr, ProbaSampleType* proba = nullptr) const override;
@@ -148,11 +144,7 @@ protected:
 private:
   SVMMachineLearningModel(const Self&) = delete;
   void operator=(const Self&) = delete;
-#ifdef OTB_OPENCV_3
   cv::Ptr<cv::ml::SVM> m_SVMModel;
-#else
-  CvSVM* m_SVMModel;
-#endif
   int    m_SVMType;
   int    m_KernelType;
   double m_Degree;
diff --git a/Modules/Learning/Supervised/include/otbSVMMachineLearningModel.hxx b/Modules/Learning/Supervised/include/otbSVMMachineLearningModel.hxx
index 97f933668e..20eb00e7f5 100644
--- a/Modules/Learning/Supervised/include/otbSVMMachineLearningModel.hxx
+++ b/Modules/Learning/Supervised/include/otbSVMMachineLearningModel.hxx
@@ -32,11 +32,7 @@ namespace otb
 template <class TInputValue, class TOutputValue>
 SVMMachineLearningModel<TInputValue, TOutputValue>::SVMMachineLearningModel()
   :
-#ifdef OTB_OPENCV_3
     m_SVMModel(cv::ml::SVM::create()),
-#else
-    m_SVMModel(new CvSVM),
-#endif
     m_SVMType(CvSVM::C_SVC),
     m_KernelType(CvSVM::RBF),
     m_Degree(0),
@@ -60,15 +56,6 @@ SVMMachineLearningModel<TInputValue, TOutputValue>::SVMMachineLearningModel()
   this->m_IsRegressionSupported = true;
 }
 
-
-template <class TInputValue, class TOutputValue>
-SVMMachineLearningModel<TInputValue, TOutputValue>::~SVMMachineLearningModel()
-{
-#ifndef OTB_OPENCV_3
-  delete m_SVMModel;
-#endif
-}
-
 /** Train the machine learning model */
 template <class TInputValue, class TOutputValue>
 void SVMMachineLearningModel<TInputValue, TOutputValue>::Train()
@@ -89,7 +76,6 @@ void SVMMachineLearningModel<TInputValue, TOutputValue>::Train()
   cv::Mat labels;
   otb::ListSampleToMat<TargetListSampleType>(this->GetTargetListSample(), labels);
 
-#ifdef OTB_OPENCV_3
   cv::Mat var_type = cv::Mat(this->GetInputListSample()->GetMeasurementVectorSize() + 1, 1, CV_8U);
   var_type.setTo(cv::Scalar(CV_VAR_NUMERICAL)); // all inputs are numerical
 
@@ -121,37 +107,6 @@ void SVMMachineLearningModel<TInputValue, TOutputValue>::Train()
   m_OutputC      = m_SVMModel->getC();
   m_OutputNu     = m_SVMModel->getNu();
   m_OutputP      = m_SVMModel->getP();
-#else
-  // Set up SVM's parameters
-  CvTermCriteria term_crit = cvTermCriteria(m_TermCriteriaType, m_MaxIter, m_Epsilon);
-  CvSVMParams    params(m_SVMType, m_KernelType, m_Degree, m_Gamma, m_Coef0, m_C, m_Nu, m_P, nullptr, term_crit);
-
-  // Train the SVM
-  if (!m_ParameterOptimization)
-  {
-    m_SVMModel->train(samples, labels, cv::Mat(), cv::Mat(), params);
-  }
-  else
-  {
-    // Trains SVM with optimal parameters.
-    // train_auto(const Mat& trainData, const Mat& responses, const Mat& varIdx, const Mat& sampleIdx,
-    // CvSVMParams params, int k_fold=10, CvParamGrid Cgrid=CvSVM::get_default_grid(CvSVM::C),
-    // CvParamGrid gammaGrid=CvSVM::get_default_grid(CvSVM::GAMMA),
-    // CvParamGrid pGrid=CvSVM::get_default_grid(CvSVM::P), CvParamGrid nuGrid=CvSVM::get_default_grid(CvSVM::NU),
-    // CvParamGrid coeffGrid=CvSVM::get_default_grid(CvSVM::COEF), CvParamGrid degreeGrid=CvSVM::get_default_grid(CvSVM::DEGREE),
-    // bool balanced=false)
-    // We used default parameters grid. If not enough, those grids should be expose to the user.
-    m_SVMModel->train_auto(samples, labels, cv::Mat(), cv::Mat(), params);
-  }
-
-  // Export of the SVM parameters into the class SVMMachineLearningModel
-  m_OutputDegree = m_SVMModel->get_params().degree;
-  m_OutputGamma  = m_SVMModel->get_params().gamma;
-  m_OutputCoef0  = m_SVMModel->get_params().coef0;
-  m_OutputC      = m_SVMModel->get_params().C;
-  m_OutputNu     = m_SVMModel->get_params().nu;
-  m_OutputP      = m_SVMModel->get_params().p;
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
@@ -164,21 +119,13 @@ SVMMachineLearningModel<TInputValue, TOutputValue>::DoPredict(const InputSampleT
 
   otb::SampleToMat<InputSampleType>(input, sample);
 
-#ifdef OTB_OPENCV_3
   double result = m_SVMModel->predict(sample);
-#else
-  double result  = m_SVMModel->predict(sample, false);
-#endif
 
   target[0] = static_cast<TOutputValue>(result);
 
   if (quality != nullptr)
   {
-#ifdef OTB_OPENCV_3
     (*quality) = m_SVMModel->predict(sample, cv::noArray(), cv::ml::StatModel::RAW_OUTPUT);
-#else
-    (*quality)   = m_SVMModel->predict(sample, true);
-#endif
   }
   if (proba != nullptr && !this->m_ProbaIndex)
     itkExceptionMacro("Probability per class not available for this classifier !");
@@ -189,32 +136,18 @@ SVMMachineLearningModel<TInputValue, TOutputValue>::DoPredict(const InputSampleT
 template <class TInputValue, class TOutputValue>
 void SVMMachineLearningModel<TInputValue, TOutputValue>::Save(const std::string& filename, const std::string& name)
 {
-#ifdef OTB_OPENCV_3
   cv::FileStorage fs(filename, cv::FileStorage::WRITE);
   fs << (name.empty() ? m_SVMModel->getDefaultName() : cv::String(name)) << "{";
   m_SVMModel->write(fs);
   fs << "}";
   fs.release();
-#else
-  if (name == "")
-    m_SVMModel->save(filename.c_str(), nullptr);
-  else
-    m_SVMModel->save(filename.c_str(), name.c_str());
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
 void SVMMachineLearningModel<TInputValue, TOutputValue>::Load(const std::string& filename, const std::string& name)
 {
-#ifdef OTB_OPENCV_3
   cv::FileStorage fs(filename, cv::FileStorage::READ);
   m_SVMModel->read(name.empty() ? fs.getFirstTopLevelNode() : fs[name]);
-#else
-  if (name == "")
-    m_SVMModel->load(filename.c_str(), nullptr);
-  else
-    m_SVMModel->load(filename.c_str(), name.c_str());
-#endif
 }
 
 template <class TInputValue, class TOutputValue>
@@ -235,13 +168,8 @@ bool SVMMachineLearningModel<TInputValue, TOutputValue>::CanReadFile(const std::
     std::getline(ifs, line);
 
     // if (line.find(m_SVMModel->getName()) != std::string::npos)
-    if (line.find(CV_TYPE_NAME_ML_SVM) != std::string::npos
-#ifdef OTB_OPENCV_3
-        || line.find(m_SVMModel->getDefaultName()) != std::string::npos
-#endif
-        )
+    if (line.find(CV_TYPE_NAME_ML_SVM) != std::string::npos || line.find(m_SVMModel->getDefaultName()) != std::string::npos)
     {
-      // std::cout<<"Reading a "<<CV_TYPE_NAME_ML_SVM<<" model"<<std::endl;
       return true;
     }
   }
diff --git a/Modules/Learning/Supervised/src/otbCvRTreesWrapper.cxx b/Modules/Learning/Supervised/src/otbCvRTreesWrapper.cxx
index ce59504901..e1b0f756e6 100644
--- a/Modules/Learning/Supervised/src/otbCvRTreesWrapper.cxx
+++ b/Modules/Learning/Supervised/src/otbCvRTreesWrapper.cxx
@@ -27,9 +27,7 @@ namespace otb
 
 CvRTreesWrapper::CvRTreesWrapper()
 {
-#ifdef OTB_OPENCV_3
   m_Impl = cv::ml::RTrees::create();
-#endif
 }
 
 CvRTreesWrapper::~CvRTreesWrapper()
@@ -38,7 +36,6 @@ CvRTreesWrapper::~CvRTreesWrapper()
 
 void CvRTreesWrapper::get_votes(const cv::Mat& sample, const cv::Mat& missing, CvRTreesWrapper::VotesVectorType& vote_count) const
 {
-#ifdef OTB_OPENCV_3
   // missing samples not implemented yet
   (void)missing;
 
@@ -86,23 +83,12 @@ void CvRTreesWrapper::get_votes(const cv::Mat& sample, const cv::Mat& missing, C
     // give at least 2 classes
     vote_count.push_back(0);
   }
-#else
-  vote_count.resize(nclasses);
-  for (int k = 0; k < ntrees; k++)
-  {
-    CvDTreeNode* predicted_node = trees[k]->predict(sample, missing);
-    int          class_idx      = predicted_node->class_idx;
-    CV_Assert(0 <= class_idx && class_idx < nclasses);
-    ++vote_count[class_idx];
-  }
-#endif
 }
 
 float CvRTreesWrapper::predict_margin(const cv::Mat& sample, const cv::Mat& missing) const
 {
-#ifdef OTB_OPENCV_3
   int ntrees = m_Impl->getRoots().size();
-#endif
+
   // Sanity check (division by ntrees later on)
   if (ntrees == 0)
   {
@@ -118,9 +104,8 @@ float CvRTreesWrapper::predict_margin(const cv::Mat& sample, const cv::Mat& miss
 
 float CvRTreesWrapper::predict_confidence(const cv::Mat& sample, const cv::Mat& missing) const
 {
-#ifdef OTB_OPENCV_3
   int ntrees = m_Impl->getRoots().size();
-#endif
+
   // Sanity check (division by ntrees later on)
   if (ntrees == 0)
   {
@@ -133,7 +118,6 @@ float CvRTreesWrapper::predict_confidence(const cv::Mat& sample, const cv::Mat&
   return confidence;
 }
 
-#ifdef OTB_OPENCV_3
 #define OTB_CV_WRAP_IMPL(type, name)        \
   type CvRTreesWrapper::get##name() const   \
   {                                         \
@@ -250,5 +234,4 @@ cv::Ptr<CvRTreesWrapper> CvRTreesWrapper::create()
 #undef OTB_CV_WRAP_IMPL
 #undef OTB_CV_WRAP_IMPL_REF
 #undef OTB_CV_WRAP_IMPL_CSTREF_GET
-#endif
 }
-- 
GitLab