Skip to content
Snippets Groups Projects
Commit d9d51c12 authored by calrama's avatar calrama
Browse files

Replace erroneous subtraction leading to underflow.

Instead allow selection between two new subtractions:
1. Absolute Difference
2. Saturated Difference (Truncation at 0,255 limits)
parent d5bb7657
No related branches found
No related tags found
No related merge requests found
Pipeline #42591 passed
...@@ -51,6 +51,7 @@ void Config::load(QString dir, QString file) ...@@ -51,6 +51,7 @@ void Config::load(QString dir, QString file)
config->EnableSwap = tree.get<int>(globalPrefix+"EnableSwap",config->EnableSwap); config->EnableSwap = tree.get<int>(globalPrefix+"EnableSwap",config->EnableSwap);
config->EnableAdd = tree.get<int>(globalPrefix+"EnableAdd",config->EnableAdd); config->EnableAdd = tree.get<int>(globalPrefix+"EnableAdd",config->EnableAdd);
config->EnableRotate = tree.get<int>(globalPrefix+"EnableRotate",config->EnableRotate); 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->BinarizationThreshold = tree.get<int>(globalPrefix+"BinarizationThreshold",config->BinarizationThreshold);
config->SizeErode = tree.get<int>(globalPrefix+"SizeErode",config->SizeErode); config->SizeErode = tree.get<int>(globalPrefix+"SizeErode",config->SizeErode);
config->SizeDilate = tree.get<int>(globalPrefix+"SizeDilate",config->SizeDilate); config->SizeDilate = tree.get<int>(globalPrefix+"SizeDilate",config->SizeDilate);
...@@ -77,6 +78,7 @@ void Config::save(QString dir, QString file) ...@@ -77,6 +78,7 @@ void Config::save(QString dir, QString file)
tree.put(globalPrefix+"EnableSwap", config->EnableSwap); tree.put(globalPrefix+"EnableSwap", config->EnableSwap);
tree.put(globalPrefix+"EnableAdd", config->EnableAdd); tree.put(globalPrefix+"EnableAdd", config->EnableAdd);
tree.put(globalPrefix+"EnableRotate", config->EnableRotate); tree.put(globalPrefix+"EnableRotate", config->EnableRotate);
tree.put(globalPrefix+"UseAbsoluteDifference", config->UseAbsoluteDifference);
tree.put(globalPrefix+"BinarizationThreshold", config->BinarizationThreshold); tree.put(globalPrefix+"BinarizationThreshold", config->BinarizationThreshold);
tree.put(globalPrefix+"SizeErode", config->SizeErode); tree.put(globalPrefix+"SizeErode", config->SizeErode);
tree.put(globalPrefix+"SizeDilate", config->SizeDilate); tree.put(globalPrefix+"SizeDilate", config->SizeDilate);
......
...@@ -7,7 +7,9 @@ ...@@ -7,7 +7,9 @@
class Config : public IConfig class Config : public IConfig
{ {
public: public:
bool UseAbsoluteDifference = true;
int BinarizationThreshold = 40; int BinarizationThreshold = 40;
int SizeErode = 8; int SizeErode = 8;
int SizeDilate = 8; int SizeDilate = 8;
int MinBlobSize = 40; int MinBlobSize = 40;
......
...@@ -7,7 +7,7 @@ TrackerParameter::TrackerParameter(QObject *parent) : ...@@ -7,7 +7,7 @@ TrackerParameter::TrackerParameter(QObject *parent) :
_cfg = static_cast<ControllerTrackingAlgorithm*>(parent)->getConfig(); _cfg = static_cast<ControllerTrackingAlgorithm*>(parent)->getConfig();
_UseAbsoluteDifference = _cfg->UseAbsoluteDifference;
_BinarizationThreshold = _cfg->BinarizationThreshold; _BinarizationThreshold = _cfg->BinarizationThreshold;
_SizeErode = _cfg->SizeErode; _SizeErode = _cfg->SizeErode;
_SizeDilate = _cfg->SizeDilate; _SizeDilate = _cfg->SizeDilate;
...@@ -38,4 +38,17 @@ void TrackerParameter::setBinarizationThreshold(int x) ...@@ -38,4 +38,17 @@ void TrackerParameter::setBinarizationThreshold(int x)
int TrackerParameter::getBinarizationThreshold() int TrackerParameter::getBinarizationThreshold()
{ {
return _BinarizationThreshold; 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
...@@ -18,48 +18,58 @@ public slots: ...@@ -18,48 +18,58 @@ public slots:
_algorithm = algorithm; _algorithm = algorithm;
} }
void setUseAbsoluteDifference(bool x);
bool getUseAbsoluteDifference();
void setBinarizationThreshold(int x); void setBinarizationThreshold(int x);
int getBinarizationThreshold(); int getBinarizationThreshold();
int getSizeErode() { return _SizeErode; }; int getSizeErode() { return _SizeErode; };
void setSizeErode(int x) { void setSizeErode(int x) {
_SizeErode = x; _SizeErode = x;
_cfg->SizeErode = x;
Q_EMIT notifyView(); Q_EMIT notifyView();
}; };
int getSizeDilate() { return _SizeDilate; }; int getSizeDilate() { return _SizeDilate; };
void setSizeDilate(int x) { void setSizeDilate(int x) {
_SizeDilate = x; _SizeDilate = x;
_cfg->SizeDilate = x;
Q_EMIT notifyView(); Q_EMIT notifyView();
}; };
double getLearningRate() { return _LearningRate; }; double getLearningRate() { return _LearningRate; };
void setLearningRate(double x) { void setLearningRate(double x) {
_LearningRate = x; _LearningRate = x;
_cfg->LearningRate = x;
Q_EMIT notifyView(); Q_EMIT notifyView();
}; };
double getMinBlobSize() { return _MinBlobSize; }; double getMinBlobSize() { return _MinBlobSize; };
void setMinBlobSize(double x) { void setMinBlobSize(double x) {
_MinBlobSize = x; _MinBlobSize = x;
_cfg->MinBlobSize = x;
Q_EMIT notifyView(); Q_EMIT notifyView();
}; };
double getMaxBlobSize() { return _MaxBlobSize; }; double getMaxBlobSize() { return _MaxBlobSize; };
void setMaxBlobSize(double x) { void setMaxBlobSize(double x) {
_MaxBlobSize = x; _MaxBlobSize = x;
_cfg->MaxBlobSize = x;
Q_EMIT notifyView(); Q_EMIT notifyView();
}; };
bool getDoBackground() { return _doBackground; }; bool getDoBackground() { return _doBackground; };
void setDoBackground(bool x) { void setDoBackground(bool x) {
_doBackground = x; _doBackground = x;
_cfg->DoBackground = x;
Q_EMIT notifyView(); Q_EMIT notifyView();
}; };
bool getDoNetwork() { return _doNetwork; }; bool getDoNetwork() { return _doNetwork; };
void setDoNetwork(bool x) { void setDoNetwork(bool x) {
_doNetwork = x; _doNetwork = x;
_cfg->DoNetwork = x;
Q_EMIT notifyView(); Q_EMIT notifyView();
}; };
...@@ -86,38 +96,14 @@ public slots: ...@@ -86,38 +96,14 @@ public slots:
void setNewSelection(std::string x) { void setNewSelection(std::string x) {
_newSelection = 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: private:
QString _algorithm; QString _algorithm;
bool _UseAbsoluteDifference;
int _BinarizationThreshold; int _BinarizationThreshold;
int _SizeErode; int _SizeErode;
int _SizeDilate; int _SizeDilate;
double _LearningRate; double _LearningRate;
......
...@@ -5,6 +5,18 @@ ...@@ -5,6 +5,18 @@
#include <opencv2/imgproc.hpp> #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) void CustomBackgroundSubtractor::setBinarizationThreshold(int value)
{ {
m_binarizationThreshold = value; m_binarizationThreshold = value;
...@@ -33,7 +45,9 @@ void CustomBackgroundSubtractor::apply(cv::InputArray image, cv::OutputArray fgm ...@@ -33,7 +45,9 @@ void CustomBackgroundSubtractor::apply(cv::InputArray image, cv::OutputArray fgm
auto fgmaskmat = fgmask.getMat(); 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 startingX = x * regionWidth;
const int startingY = y * regionHeight; const int startingY = y * regionHeight;
const cv::Rect subArea = cv::Rect(startingX, startingY, regionWidth, regionHeight); const cv::Rect subArea = cv::Rect(startingX, startingY, regionWidth, regionHeight);
...@@ -41,7 +55,12 @@ void CustomBackgroundSubtractor::apply(cv::InputArray image, cv::OutputArray fgm ...@@ -41,7 +55,12 @@ void CustomBackgroundSubtractor::apply(cv::InputArray image, cv::OutputArray fgm
cv::Mat subImage = image.getMat()(subArea); cv::Mat subImage = image.getMat()(subArea);
cv::Mat subResults = fgmaskmat(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; subBackground = (1.0 - learningRate) * subBackground + learningRate * subImage;
}; };
......
...@@ -5,14 +5,19 @@ ...@@ -5,14 +5,19 @@
class CustomBackgroundSubtractor : public cv::BackgroundSubtractor class CustomBackgroundSubtractor : public cv::BackgroundSubtractor
{ {
public: public:
CustomBackgroundSubtractor();
void apply(cv::InputArray image, cv::OutputArray fgmask, double learningRate = -1) override; void apply(cv::InputArray image, cv::OutputArray fgmask, double learningRate = -1) override;
void getBackgroundImage(cv::OutputArray backgroundImage) const override; void getBackgroundImage(cv::OutputArray backgroundImage) const override;
void setUseAbsoluteDifference(bool value);
void setBinarizationThreshold(int value); void setBinarizationThreshold(int value);
private: private:
cv::Mat m_background; cv::Mat m_background;
bool m_useAbsoluteDifference;
int m_binarizationThreshold; int m_binarizationThreshold;
}; };
...@@ -85,6 +85,7 @@ cv::Mat ImagePreProcessor::backgroundSubtraction(cv::Mat& image) ...@@ -85,6 +85,7 @@ cv::Mat ImagePreProcessor::backgroundSubtraction(cv::Mat& image)
if (m_TrackingParameter->getAlgorithm() != QString("Custom")) { if (m_TrackingParameter->getAlgorithm() != QString("Custom")) {
init(); init();
} }
subtractor->setUseAbsoluteDifference(m_TrackingParameter->getUseAbsoluteDifference());
subtractor->setBinarizationThreshold(m_TrackingParameter->getBinarizationThreshold()); subtractor->setBinarizationThreshold(m_TrackingParameter->getBinarizationThreshold());
} else { } else {
qFatal("Unsupported background subtraction algorithm"); qFatal("Unsupported background subtraction algorithm");
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
TrackerParameterView::TrackerParameterView(QWidget *parent, IController *controller, IModel *model) : IViewWidget(parent, controller, model), TrackerParameterView::TrackerParameterView(QWidget *parent, IController *controller, IModel *model) : IViewWidget(parent, controller, model),
_ui(new Ui::TrackerParameterView), _ui(new Ui::TrackerParameterView),
_useAbsDiff(nullptr),
_binThres(nullptr) _binThres(nullptr)
{ {
_ui->setupUi(this); _ui->setupUi(this);
...@@ -31,6 +32,8 @@ TrackerParameterView::TrackerParameterView(QWidget *parent, IController *control ...@@ -31,6 +32,8 @@ TrackerParameterView::TrackerParameterView(QWidget *parent, IController *control
connect(_ui->lineEdit_7_learningRate, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &TrackerParameterView::parametersChanged); connect(_ui->lineEdit_7_learningRate, qOverload<double>(&QDoubleSpinBox::valueChanged), this, &TrackerParameterView::parametersChanged);
initSubtractorSpecificUI(_ui->algorithmCB->currentText()); initSubtractorSpecificUI(_ui->algorithmCB->currentText());
_ui->algorithmCB->setEnabled(false);
} }
TrackerParameterView::~TrackerParameterView() TrackerParameterView::~TrackerParameterView()
...@@ -46,11 +49,18 @@ void TrackerParameterView::initSubtractorSpecificUI(QString algorithm) ...@@ -46,11 +49,18 @@ void TrackerParameterView::initSubtractorSpecificUI(QString algorithm)
_ui->algorithmSpecificParameterLayout->removeRow(0); _ui->algorithmSpecificParameterLayout->removeRow(0);
} }
if (_binThres) { _useAbsDiff = nullptr;
_binThres = nullptr; _binThres = nullptr;
}
if (algorithm == QString("Custom")) { 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 = new QSpinBox();
_binThres->setMinimum(1); _binThres->setMinimum(1);
_binThres->setMaximum(255); _binThres->setMaximum(255);
...@@ -85,6 +95,10 @@ void TrackerParameterView::getNotified() ...@@ -85,6 +95,10 @@ void TrackerParameterView::getNotified()
_ui->lineEdit_7_learningRate->setValue(parameter->getLearningRate()); _ui->lineEdit_7_learningRate->setValue(parameter->getLearningRate());
if (_useAbsDiff) {
_useAbsDiff->setChecked(parameter->getUseAbsoluteDifference());
}
if (_binThres) { if (_binThres) {
_binThres->setValue(parameter->getBinarizationThreshold()); _binThres->setValue(parameter->getBinarizationThreshold());
} }
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "../Model/TrackerParameter.h" #include "../Model/TrackerParameter.h"
#include <QSpinBox> #include <QSpinBox>
#include <QCheckBox>
namespace Ui { namespace Ui {
class TrackerParameterView; class TrackerParameterView;
...@@ -31,6 +32,8 @@ public: ...@@ -31,6 +32,8 @@ public:
private: private:
Ui::TrackerParameterView *_ui; Ui::TrackerParameterView *_ui;
QCheckBox* _useAbsDiff;
QSpinBox* _binThres; QSpinBox* _binThres;
private slots: private slots:
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment