Commit 0d8e89b5 authored by Cédric Traizet's avatar Cédric Traizet

REFAC: remove opencv2 specific code

parent f365b62b
......@@ -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);
......
......@@ -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);
......
......@@ -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
{
......@@ -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
......
......@@ -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;
......
......@@ -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
};
}
......
......@@ -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;
......
......@@ -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;
}
}
......
......@@ -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;
......
......@@ -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.
......
......@@ -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;
......
......@@ -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>