From d9d51c12aee7ac5c35b58b9b247d28011ae84353 Mon Sep 17 00:00:00 2001 From: Moritz Maxeiner <mm@ucw.sh> Date: Mon, 15 Nov 2021 01:25:40 +0100 Subject: [PATCH] Replace erroneous subtraction leading to underflow. Instead allow selection between two new subtractions: 1. Absolute Difference 2. Saturated Difference (Truncation at 0,255 limits) --- Src/Config.cpp | 2 + Src/Config.h | 2 + Src/Model/TrackerParameter.cpp | 15 +++++++- Src/Model/TrackerParameter.h | 38 ++++++------------- .../CustomBackgroundSubtractor.cpp | 23 ++++++++++- .../preprocessor/CustomBackgroundSubtractor.h | 5 +++ .../preprocessor/ImagePreProcessor.cpp | 1 + Src/View/TrackerParameterView.cpp | 20 ++++++++-- Src/View/TrackerParameterView.h | 3 ++ 9 files changed, 77 insertions(+), 32 deletions(-) diff --git a/Src/Config.cpp b/Src/Config.cpp index ef92d20..72e8d3c 100644 --- a/Src/Config.cpp +++ b/Src/Config.cpp @@ -51,6 +51,7 @@ void Config::load(QString dir, QString file) config->EnableSwap = tree.get<int>(globalPrefix+"EnableSwap",config->EnableSwap); config->EnableAdd = tree.get<int>(globalPrefix+"EnableAdd",config->EnableAdd); config->EnableRotate = tree.get<int>(globalPrefix+"EnableRotate",config->EnableRotate); + config->UseAbsoluteDifference = tree.get<bool>(globalPrefix+"UseAbsoluteDifference",config->UseAbsoluteDifference); config->BinarizationThreshold = tree.get<int>(globalPrefix+"BinarizationThreshold",config->BinarizationThreshold); config->SizeErode = tree.get<int>(globalPrefix+"SizeErode",config->SizeErode); config->SizeDilate = tree.get<int>(globalPrefix+"SizeDilate",config->SizeDilate); @@ -77,6 +78,7 @@ void Config::save(QString dir, QString file) tree.put(globalPrefix+"EnableSwap", config->EnableSwap); tree.put(globalPrefix+"EnableAdd", config->EnableAdd); tree.put(globalPrefix+"EnableRotate", config->EnableRotate); + tree.put(globalPrefix+"UseAbsoluteDifference", config->UseAbsoluteDifference); tree.put(globalPrefix+"BinarizationThreshold", config->BinarizationThreshold); tree.put(globalPrefix+"SizeErode", config->SizeErode); tree.put(globalPrefix+"SizeDilate", config->SizeDilate); diff --git a/Src/Config.h b/Src/Config.h index 31f70ba..f268060 100644 --- a/Src/Config.h +++ b/Src/Config.h @@ -7,7 +7,9 @@ class Config : public IConfig { public: + bool UseAbsoluteDifference = true; int BinarizationThreshold = 40; + int SizeErode = 8; int SizeDilate = 8; int MinBlobSize = 40; diff --git a/Src/Model/TrackerParameter.cpp b/Src/Model/TrackerParameter.cpp index 8363a86..645159c 100644 --- a/Src/Model/TrackerParameter.cpp +++ b/Src/Model/TrackerParameter.cpp @@ -7,7 +7,7 @@ TrackerParameter::TrackerParameter(QObject *parent) : _cfg = static_cast<ControllerTrackingAlgorithm*>(parent)->getConfig(); - + _UseAbsoluteDifference = _cfg->UseAbsoluteDifference; _BinarizationThreshold = _cfg->BinarizationThreshold; _SizeErode = _cfg->SizeErode; _SizeDilate = _cfg->SizeDilate; @@ -38,4 +38,17 @@ void TrackerParameter::setBinarizationThreshold(int x) int TrackerParameter::getBinarizationThreshold() { return _BinarizationThreshold; +} + + +void TrackerParameter::setUseAbsoluteDifference(bool value) +{ + _UseAbsoluteDifference = value; + _cfg->UseAbsoluteDifference = value; + Q_EMIT notifyView(); +} + +bool TrackerParameter::getUseAbsoluteDifference() +{ + return _UseAbsoluteDifference; } \ No newline at end of file diff --git a/Src/Model/TrackerParameter.h b/Src/Model/TrackerParameter.h index db3384f..5ad37d1 100644 --- a/Src/Model/TrackerParameter.h +++ b/Src/Model/TrackerParameter.h @@ -18,48 +18,58 @@ public slots: _algorithm = algorithm; } + void setUseAbsoluteDifference(bool x); + bool getUseAbsoluteDifference(); + void setBinarizationThreshold(int x); int getBinarizationThreshold(); int getSizeErode() { return _SizeErode; }; void setSizeErode(int x) { _SizeErode = x; + _cfg->SizeErode = x; Q_EMIT notifyView(); }; int getSizeDilate() { return _SizeDilate; }; void setSizeDilate(int x) { _SizeDilate = x; + _cfg->SizeDilate = x; Q_EMIT notifyView(); }; double getLearningRate() { return _LearningRate; }; void setLearningRate(double x) { _LearningRate = x; + _cfg->LearningRate = x; Q_EMIT notifyView(); }; double getMinBlobSize() { return _MinBlobSize; }; void setMinBlobSize(double x) { _MinBlobSize = x; + _cfg->MinBlobSize = x; Q_EMIT notifyView(); }; double getMaxBlobSize() { return _MaxBlobSize; }; void setMaxBlobSize(double x) { _MaxBlobSize = x; + _cfg->MaxBlobSize = x; Q_EMIT notifyView(); }; bool getDoBackground() { return _doBackground; }; void setDoBackground(bool x) { _doBackground = x; + _cfg->DoBackground = x; Q_EMIT notifyView(); }; bool getDoNetwork() { return _doNetwork; }; void setDoNetwork(bool x) { _doNetwork = x; + _cfg->DoNetwork = x; Q_EMIT notifyView(); }; @@ -86,38 +96,14 @@ public slots: void setNewSelection(std::string x) { _newSelection = x; } - - - void setAll( - int BinarizationThreshold, - int SizeErode, - int SizeDilate, - double LearningRate, - int minBlobSize, - int maxBlobSize) - { - _BinarizationThreshold = BinarizationThreshold; - _SizeErode = SizeErode; - _SizeDilate = SizeDilate; - _LearningRate = LearningRate; - _MinBlobSize = minBlobSize; - _MaxBlobSize = maxBlobSize; - _cfg->BinarizationThreshold = BinarizationThreshold; - _cfg->SizeErode = SizeErode; - _cfg->SizeDilate = SizeDilate; - _cfg->MinBlobSize = minBlobSize; - _cfg->MaxBlobSize = maxBlobSize; - _cfg->LearningRate = LearningRate; - Q_EMIT notifyView(); - }; - - private: QString _algorithm; + bool _UseAbsoluteDifference; int _BinarizationThreshold; + int _SizeErode; int _SizeDilate; double _LearningRate; diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.cpp index 95e46cc..cf8f62a 100644 --- a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.cpp +++ b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.cpp @@ -5,6 +5,18 @@ #include <opencv2/imgproc.hpp> +CustomBackgroundSubtractor::CustomBackgroundSubtractor() +: m_useAbsoluteDifference{true} +, m_binarizationThreshold{8} +{ + +} + +void CustomBackgroundSubtractor::setUseAbsoluteDifference(bool value) +{ + m_useAbsoluteDifference = value; +} + void CustomBackgroundSubtractor::setBinarizationThreshold(int value) { m_binarizationThreshold = value; @@ -33,7 +45,9 @@ void CustomBackgroundSubtractor::apply(cv::InputArray image, cv::OutputArray fgm auto fgmaskmat = fgmask.getMat(); - auto workOnRegion = [&](int x, int y) { + const auto useAbsoluteDifference = m_useAbsoluteDifference; + + auto workOnRegion = [&, useAbsoluteDifference](int x, int y) { const int startingX = x * regionWidth; const int startingY = y * regionHeight; const cv::Rect subArea = cv::Rect(startingX, startingY, regionWidth, regionHeight); @@ -41,7 +55,12 @@ void CustomBackgroundSubtractor::apply(cv::InputArray image, cv::OutputArray fgm cv::Mat subImage = image.getMat()(subArea); cv::Mat subResults = fgmaskmat(subArea); - subResults = (subBackground - subImage); + if (useAbsoluteDifference) { + cv::absdiff(subBackground, subImage, subResults); + } else { + cv::subtract(subBackground, subImage, subResults); + } + subBackground = (1.0 - learningRate) * subBackground + learningRate * subImage; }; diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.h b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.h index 551748c..94c79b0 100644 --- a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.h +++ b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/CustomBackgroundSubtractor.h @@ -5,14 +5,19 @@ class CustomBackgroundSubtractor : public cv::BackgroundSubtractor { public: + CustomBackgroundSubtractor(); + void apply(cv::InputArray image, cv::OutputArray fgmask, double learningRate = -1) override; void getBackgroundImage(cv::OutputArray backgroundImage) const override; + void setUseAbsoluteDifference(bool value); void setBinarizationThreshold(int value); private: cv::Mat m_background; + bool m_useAbsoluteDifference; + int m_binarizationThreshold; }; diff --git a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp index 621d935..9f241aa 100644 --- a/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp +++ b/Src/Model/TrackingAlgorithm/imageProcessor/preprocessor/ImagePreProcessor.cpp @@ -85,6 +85,7 @@ cv::Mat ImagePreProcessor::backgroundSubtraction(cv::Mat& image) if (m_TrackingParameter->getAlgorithm() != QString("Custom")) { init(); } + subtractor->setUseAbsoluteDifference(m_TrackingParameter->getUseAbsoluteDifference()); subtractor->setBinarizationThreshold(m_TrackingParameter->getBinarizationThreshold()); } else { qFatal("Unsupported background subtraction algorithm"); diff --git a/Src/View/TrackerParameterView.cpp b/Src/View/TrackerParameterView.cpp index bf58593..5f21a2f 100644 --- a/Src/View/TrackerParameterView.cpp +++ b/Src/View/TrackerParameterView.cpp @@ -5,6 +5,7 @@ TrackerParameterView::TrackerParameterView(QWidget *parent, IController *controller, IModel *model) : IViewWidget(parent, controller, model), _ui(new Ui::TrackerParameterView), + _useAbsDiff(nullptr), _binThres(nullptr) { _ui->setupUi(this); @@ -31,6 +32,8 @@ TrackerParameterView::TrackerParameterView(QWidget *parent, IController *control connect(_ui->lineEdit_7_learningRate, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &TrackerParameterView::parametersChanged); initSubtractorSpecificUI(_ui->algorithmCB->currentText()); + + _ui->algorithmCB->setEnabled(false); } TrackerParameterView::~TrackerParameterView() @@ -46,11 +49,18 @@ void TrackerParameterView::initSubtractorSpecificUI(QString algorithm) _ui->algorithmSpecificParameterLayout->removeRow(0); } - if (_binThres) { - _binThres = nullptr; - } + _useAbsDiff = nullptr; + _binThres = nullptr; if (algorithm == QString("Custom")) { + _useAbsDiff = new QCheckBox(); + _useAbsDiff->setText(" "); + _useAbsDiff->setChecked(parameter->getUseAbsoluteDifference()); + _ui->algorithmSpecificParameterLayout->addRow(tr("Use Absolute Difference:"), _useAbsDiff); + + connect(_useAbsDiff, &QCheckBox::toggled, parameter, &TrackerParameter::setUseAbsoluteDifference); + connect(_useAbsDiff, &QCheckBox::toggled, this, &TrackerParameterView::parametersChanged); + _binThres = new QSpinBox(); _binThres->setMinimum(1); _binThres->setMaximum(255); @@ -85,6 +95,10 @@ void TrackerParameterView::getNotified() _ui->lineEdit_7_learningRate->setValue(parameter->getLearningRate()); + if (_useAbsDiff) { + _useAbsDiff->setChecked(parameter->getUseAbsoluteDifference()); + } + if (_binThres) { _binThres->setValue(parameter->getBinarizationThreshold()); } diff --git a/Src/View/TrackerParameterView.h b/Src/View/TrackerParameterView.h index 6412b0b..172a0e9 100644 --- a/Src/View/TrackerParameterView.h +++ b/Src/View/TrackerParameterView.h @@ -5,6 +5,7 @@ #include "../Model/TrackerParameter.h" #include <QSpinBox> +#include <QCheckBox> namespace Ui { class TrackerParameterView; @@ -31,6 +32,8 @@ public: private: Ui::TrackerParameterView *_ui; + QCheckBox* _useAbsDiff; + QSpinBox* _binThres; private slots: -- GitLab