From f104fd5b17c2b0cc599ed2d0b0c6baed973e9159 Mon Sep 17 00:00:00 2001 From: Paul Leroy Date: Wed, 18 Jan 2023 23:57:59 +0100 Subject: [PATCH] confusion matrix added to the training step Add the confusion matrix to the training step Delete confusion matrices properly after the training step --- confusionmatrix.cpp | 6 +++--- q3DMASC.cpp | 2 ++ q3DMASCClassifier.cpp | 12 ++++++++++-- q3DMASCClassifier.h | 3 +++ qTrain3DMASCDialog.cpp | 7 +++++++ qTrain3DMASCDialog.h | 5 +++++ 6 files changed, 30 insertions(+), 5 deletions(-) diff --git a/confusionmatrix.cpp b/confusionmatrix.cpp index cbbfcf3..25d498c 100644 --- a/confusionmatrix.cpp +++ b/confusionmatrix.cpp @@ -14,7 +14,10 @@ ConfusionMatrix::ConfusionMatrix(std::vector &actual, std::vectorsetupUi(this); + this->setWindowFlag(Qt::WindowStaysOnTopHint); compute(actual, predicted); + this->show(); + this->setMinimumSize(this->ui->tableWidget->sizeHint()); } ConfusionMatrix::~ConfusionMatrix() @@ -215,7 +218,4 @@ void ConfusionMatrix::compute(std::vector& actual, std::vector(realIdx, F1_SCORE), 'g', 2)); this->ui->tableWidget->setItem(2 + realIdx, 2 + nbClasses + F1_SCORE, newItem); } - - this->show(); - this->setMinimumSize(this->ui->tableWidget->sizeHint()); } diff --git a/q3DMASC.cpp b/q3DMASC.cpp index c8c86bc..4e20f03 100644 --- a/q3DMASC.cpp +++ b/q3DMASC.cpp @@ -364,6 +364,7 @@ void q3DMASCPlugin::doTrainAction() //show the training dialog for the first time Train3DMASCDialog trainDlg(m_app->getMainWindow()); + trainDlg.setWindowModality(Qt::WindowModal); // to be able to move the confusion matrix window trainDlg.maxDepthSpinBox->setValue(s_params.rt.maxDepth); trainDlg.maxTreeCountSpinBox->setValue(s_params.rt.maxTreeCount); trainDlg.activeVarCountSpinBox->setValue(s_params.rt.activeVarCount); @@ -633,6 +634,7 @@ void q3DMASCPlugin::doTrainAction() testCloud ? testCloud : corePoints.cloud, metrics, errorMessage, + trainDlg, testCloud ? nullptr : testSubset.data(), "Classification_pred", m_app->getMainWindow())) diff --git a/q3DMASCClassifier.cpp b/q3DMASCClassifier.cpp index fad380e..546032f 100644 --- a/q3DMASCClassifier.cpp +++ b/q3DMASCClassifier.cpp @@ -38,6 +38,7 @@ #include #include +#include "qTrain3DMASCDialog.h" #include "confusionmatrix.h" using namespace masc; @@ -274,7 +275,7 @@ bool Classifier::classify( const Feature::Source::Set& featureSources, QCoreApplication::processEvents(); } - ConfusionMatrix *confusionMatrix = new ConfusionMatrix(*classifSFBackup, *classificationSF); + ConfusionMatrix *confusionMatrix = new ConfusionMatrix(*classifSFBackup, *classificationSF, parentWidget); return success; } @@ -283,6 +284,7 @@ bool Classifier::evaluate(const Feature::Source::Set& featureSources, ccPointCloud* testCloud, AccuracyMetrics& metrics, QString& errorMessage, + Train3DMASCDialog& train3DMASCDialog, CCCoreLib::ReferenceCloud* testSubset/*=nullptr=*/, QString outputSFName/*=QString()*/, QWidget* parentWidget/*=nullptr*/) @@ -394,7 +396,10 @@ bool Classifier::evaluate(const Feature::Source::Set& featureSources, } } + //estimate the efficiency of the classifier + std::vector actualClass(testSampleCount); + std::vector predictectedClass(testSampleCount); { metrics.sampleCount = testSampleCount; metrics.goodGuess = 0; @@ -412,6 +417,8 @@ bool Classifier::evaluate(const Feature::Source::Set& featureSources, float fPredictedClass = m_rtrees->predict(test_data.row(i), cv::noArray(), cv::ml::DTrees::PREDICT_MAX_VOTE); int iPredictedClass = static_cast(fPredictedClass); + actualClass.at(i) = iClass; + predictectedClass.at(i) = iPredictedClass; if (iPredictedClass == iClass) { ++metrics.goodGuess; @@ -434,7 +441,8 @@ bool Classifier::evaluate(const Feature::Source::Set& featureSources, metrics.ratio = static_cast(metrics.goodGuess) / metrics.sampleCount; } - ConfusionMatrix *confusionMatrix = new ConfusionMatrix(*classifSF, *outputSF); + std::unique_ptr confusionMatrix(new ConfusionMatrix(actualClass, predictectedClass)); + train3DMASCDialog.deleteLaterConfusionMatrix(confusionMatrix); return true; } diff --git a/q3DMASCClassifier.h b/q3DMASCClassifier.h index 356363a..c24611a 100644 --- a/q3DMASCClassifier.h +++ b/q3DMASCClassifier.h @@ -32,6 +32,8 @@ class QWidget; class ccMainAppInterface; +class ConfusionMatrix; +class Train3DMASCDialog; //! 3DMASC classifier namespace masc @@ -65,6 +67,7 @@ namespace masc ccPointCloud* testCloud, AccuracyMetrics& metrics, QString& errorMessage, + Train3DMASCDialog& train3DMASCDialog, CCCoreLib::ReferenceCloud* testSubset = nullptr, QString outputSFName = QString(), QWidget* parentWidget = nullptr); diff --git a/qTrain3DMASCDialog.cpp b/qTrain3DMASCDialog.cpp index 75f19ab..5ba595e 100644 --- a/qTrain3DMASCDialog.cpp +++ b/qTrain3DMASCDialog.cpp @@ -27,6 +27,8 @@ //System #include +#include + static const int FeatureImportanceColumn = 1; Train3DMASCDialog::Train3DMASCDialog(QWidget* parent/*=nullptr*/) @@ -184,3 +186,8 @@ void Train3DMASCDialog::onExportResults() stream << featureName << ";" << importance << Qt::endl; } } + +void Train3DMASCDialog::deleteLaterConfusionMatrix(std::unique_ptr& ptr) +{ + m_confusionMatrixToDeleteLater.push_back(std::move(ptr)); +} diff --git a/qTrain3DMASCDialog.h b/qTrain3DMASCDialog.h index 56f5bf9..2ee68cb 100644 --- a/qTrain3DMASCDialog.h +++ b/qTrain3DMASCDialog.h @@ -22,6 +22,8 @@ #include +#include "confusionmatrix.h" + //! 3DMASC plugin 'train' dialog class Train3DMASCDialog : public QDialog, public Ui::Train3DMASCDialog { @@ -51,6 +53,8 @@ public: inline bool shouldSaveClassifier() const { return saveRequested; } + void deleteLaterConfusionMatrix(std::unique_ptr& ptr); + protected slots: void onClose(); @@ -61,4 +65,5 @@ protected: //members bool classifierSaved; bool saveRequested; + std::vector> m_confusionMatrixToDeleteLater; };