Commit 6aaf3177 authored by guillaume pernot's avatar guillaume pernot

Drop OpenCV2 support

parent 832879c3
#Reference labels (rows):1,2,3,4
#Produced labels (columns):1,2,3,4
42,0,0,0
0,41,1,0
0,0,42,0
0,0,0,42
%YAML:1.0
my_tree: !!opencv-ml-tree
is_classifier: 1
var_all: 4
var_count: 4
ord_var_count: 4
cat_var_count: 0
training_params:
use_surrogates: 1
max_categories: 10
max_depth: 25
min_sample_count: 10
cross_validation_folds: 10
use_1se_rule: 1
truncate_pruned_tree: 1
priors: !!opencv-matrix
rows: 1
cols: 4
dt: d
data: [ 1., 1., 1., 1. ]
var_type: [ 0, 0, 0, 0 ]
cat_count: !!opencv-matrix
rows: 1
cols: 1
dt: i
data: [ 4 ]
cat_map: !!opencv-matrix
rows: 1
cols: 4
dt: i
data: [ 1, 2, 3, 4 ]
best_tree_idx: -1
nodes:
-
depth: 0
sample_count: 180
value: 1.
norm_class_idx: 0
Tn: 0
complexity: 4
alpha: 45.
node_risk: 135.
tree_risk: 0.
tree_error: 0.
splits:
- { var:0, quality:90., le:2.4664748460054398e-02 }
-
depth: 1
sample_count: 90
value: 1.
norm_class_idx: 0
Tn: 2147483647
complexity: 2
alpha: 45.
node_risk: 45.
tree_risk: 0.
tree_error: 0.
splits:
- { var:3, quality:90., le:-1.2730357646942139e+00 }
-
depth: 2
sample_count: 45
value: 1.
norm_class_idx: 0
Tn: 2147483647
complexity: 1
alpha: 0.
node_risk: 0.
tree_risk: 0.
tree_error: 0.
-
depth: 2
sample_count: 45
value: 3.
norm_class_idx: 2
Tn: 2147483647
complexity: 1
alpha: 0.
node_risk: 0.
tree_risk: 0.
tree_error: 0.
-
depth: 1
sample_count: 90
value: 2.
norm_class_idx: 1
Tn: 2147483647
complexity: 2
alpha: 45.
node_risk: 45.
tree_risk: 0.
tree_error: 0.
splits:
- { var:2, quality:90., le:8.2657122611999512e-01 }
-
depth: 2
sample_count: 45
value: 2.
norm_class_idx: 1
Tn: 2147483647
complexity: 1
alpha: 0.
node_risk: 0.
tree_risk: 0.
tree_error: 0.
-
depth: 2
sample_count: 45
value: 4.
norm_class_idx: 3
Tn: 2147483647
complexity: 1
alpha: 0.
node_risk: 0.
tree_risk: 0.
tree_error: 0.
%YAML:1.0
my_tree: !!opencv-ml-tree
is_classifier: 1
var_all: 4
var_count: 4
ord_var_count: 4
cat_var_count: 0
training_params:
use_surrogates: 1
max_categories: 10
max_depth: 25
min_sample_count: 10
cross_validation_folds: 10
use_1se_rule: 1
truncate_pruned_tree: 1
priors: !!opencv-matrix
rows: 1
cols: 4
dt: d
data: [ 1., 1., 1., 1. ]
var_type: [ 0, 0, 0, 0 ]
cat_count: !!opencv-matrix
rows: 1
cols: 1
dt: i
data: [ 4 ]
cat_map: !!opencv-matrix
rows: 1
cols: 4
dt: i
data: [ 1, 2, 3, 4 ]
best_tree_idx: 0
nodes:
-
depth: 0
sample_count: 190
value: 3.
norm_class_idx: 2
Tn: 2
complexity: 4
alpha: 41.
node_risk: 142.
tree_risk: 3.
tree_error: 1.
splits:
- { var:1, quality:9.5338027954101562e+01,
le:4.1874265670776367e-01 }
-
depth: 1
sample_count: 142
value: 3.
norm_class_idx: 2
Tn: 1
complexity: 3
alpha: 4.2500000000000000e+01
node_risk: 94.
tree_risk: 3.
tree_error: 1.
splits:
- { var:3, quality:9.2062500000000000e+01,
le:-1.1355226486921310e-01 }
-
depth: 2
sample_count: 96
value: 1.
norm_class_idx: 0
Tn: 2147483647
complexity: 2
alpha: 43.
node_risk: 49.
tree_risk: 3.
tree_error: 1.
splits:
- { var:1, quality:8.8470588684082031e+01,
le:-4.6542203426361084e-01 }
-
depth: 3
sample_count: 51
value: 1.
norm_class_idx: 0
Tn: 0
complexity: 1
alpha: 2.
node_risk: 4.
tree_risk: 3.
tree_error: 1.
-
depth: 3
sample_count: 45
value: 2.
norm_class_idx: 1
Tn: 2147483647
complexity: 1
alpha: 0.
node_risk: 0.
tree_risk: 0.
tree_error: 0.
-
depth: 2
sample_count: 46
value: 3.
norm_class_idx: 2
Tn: 2147483647
complexity: 1
alpha: 0.
node_risk: 0.
tree_risk: 0.
tree_error: 0.
-
depth: 1
sample_count: 48
value: 4.
norm_class_idx: 3
Tn: 2147483647
complexity: 1
alpha: 0.
node_risk: 0.
tree_risk: 0.
tree_error: 0.
%YAML:1.0
my_tree: !!opencv-ml-tree
is_classifier: 1
var_all: 4
var_count: 4
ord_var_count: 4
cat_var_count: 0
training_params:
use_surrogates: 1
max_categories: 10
max_depth: 25
min_sample_count: 10
cross_validation_folds: 10
use_1se_rule: 1
truncate_pruned_tree: 1
priors: !!opencv-matrix
rows: 1
cols: 4
dt: d
data: [ 1., 1., 1., 1. ]
var_type: [ 0, 0, 0, 0 ]
cat_count: !!opencv-matrix
rows: 1
cols: 1
dt: i
data: [ 4 ]
cat_map: !!opencv-matrix
rows: 1
cols: 4
dt: i
data: [ 1, 2, 3, 4 ]
best_tree_idx: -1
nodes:
-
depth: 0
sample_count: 180
value: 1.
norm_class_idx: 0
Tn: 0
complexity: 4
alpha: 45.
node_risk: 135.
tree_risk: 0.
tree_error: 0.
splits:
- { var:0, quality:90., le:2.4664748460054398e-02 }
-
depth: 1
sample_count: 90
value: 1.
norm_class_idx: 0
Tn: 2147483647
complexity: 2
alpha: 45.
node_risk: 45.
tree_risk: 0.
tree_error: 0.
splits:
- { var:3, quality:90., le:-1.2730357646942139e+00 }
-
depth: 2
sample_count: 45
value: 1.
norm_class_idx: 0
Tn: 2147483647
complexity: 1
alpha: 0.
node_risk: 0.
tree_risk: 0.
tree_error: 0.
-
depth: 2
sample_count: 45
value: 3.
norm_class_idx: 2
Tn: 2147483647
complexity: 1
alpha: 0.
node_risk: 0.
tree_risk: 0.
tree_error: 0.
-
depth: 1
sample_count: 90
value: 2.
norm_class_idx: 1
Tn: 2147483647
complexity: 2
alpha: 45.
node_risk: 45.
tree_risk: 0.
tree_error: 0.
splits:
- { var:2, quality:90., le:8.2657122611999512e-01 }
-
depth: 2
sample_count: 45
value: 2.
norm_class_idx: 1
Tn: 2147483647
complexity: 1
alpha: 0.
node_risk: 0.
tree_risk: 0.
tree_error: 0.
-
depth: 2
sample_count: 45
value: 4.
norm_class_idx: 3
Tn: 2147483647
complexity: 1
alpha: 0.
node_risk: 0.
tree_risk: 0.
tree_error: 0.
......@@ -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 "
......@@ -73,7 +69,7 @@ void LearningApplicationBase<TInputValue, TOutputValue>::InitDecisionTreeParams(
"suboptimal split.");
// CVFolds: only exposed for OPENCV 2 because it crashes in OpenCV 3
// TODO: 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);
......@@ -109,7 +105,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
// TODO: CVFolds is only exposed for OPENCV 2 because it crashes in OpenCV 3
#ifndef OTB_OPENCV_3
classifier->SetCVFolds(GetParameterInt("classifier.dt.f"));
#endif
......
......@@ -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")
......
......@@ -27,11 +27,7 @@
#include "itkFixedArray.h"
#include "otbMachineLearningModel.h"
#ifdef OTB_OPENCV_3
#include "otbOpenCVUtils.h"
#else
class CvBoost;
#endif
namespace otb
{
......@@ -119,9 +115,6 @@ protected:
/** Constructor */
BoostMachineLearningModel();
/** Destructor */
~BoostMachineLearningModel() override;
/** Predict values using the model */
TargetSampleType DoPredict(const InputSampleType& input, ConfidenceValueType* quality = nullptr, ProbaSampleType* proba = nullptr) const override;
......@@ -132,11 +125,7 @@ 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;
......
......@@ -33,33 +33,17 @@ 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_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 +59,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 +66,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,22 +80,12 @@ 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
);
}
if (proba != nullptr && !this->m_ProbaIndex)
......@@ -130,32 +98,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>
......@@ -177,9 +131,7 @@ bool BoostMachineLearningModel<TInputValue, TOutputValue>::CanReadFile(const std
// 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
)
{
// std::cout<<"Reading a "<<CV_TYPE_NAME_ML_BOOSTING<<" model"<<std::endl;
......
......@@ -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,8 +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; \
virtual void set##name(type val) override;
......@@ -125,7 +119,6 @@ public:
private:
cv::Ptr<cv::ml::RTrees> m_Impl;
#endif // OTB_OPENCV_3
};
}
......
......@@ -27,11 +27,7 @@
#include "itkFixedArray.h"
#include "otbMachineLearningModel.h"
#ifdef OTB_OPENCV_3
#include "otbOpenCVUtils.h"
#else
class CvDTree;
#endif
namespace otb
{
......@@ -174,9 +170,6 @@ protected:
/** Constructor */
DecisionTreeMachineLearningModel();
/** Destructor */
~DecisionTreeMachineLearningModel() override;
/** Predict values using the model */
TargetSampleType DoPredict(const InputSampleType& input, ConfidenceValueType* quality = nullptr, ProbaSampleType* proba = nullptr) const override;
......@@ -187,11 +180,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;
......
......@@ -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,29 +40,12 @@ 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)
{
this->m_IsRegressionSupported = true;
}
template <class TInputValue, class TOutputValue>
DecisionTreeMachineLearningModel<TInputValue, TOutputValue>::~DecisionTreeMachineLearningModel()
{
#ifndef OTB_OPENCV_3
delete m_DTreeModel;
#endif
}
/** Train the machine learning model */
template <class TInputValue, class TOutputValue>
void DecisionTreeMachineLearningModel<TInputValue, TOutputValue>::Train()
......@@ -81,7 +63,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 +73,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 +85,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 +105,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