Add option to throttle object and pattern recognition

This commit is contained in:
WarmUpTill 2021-09-26 19:10:47 +02:00 committed by WarmUpTill
parent b7a0f6c5d0
commit 292adb990d
3 changed files with 87 additions and 0 deletions

View File

@ -132,6 +132,7 @@ AdvSceneSwitcher.condition.video.entry.modelPath="Model data (haar cascade class
AdvSceneSwitcher.condition.video.entry.minNeighbor="Minimum neighbors: {{minNeighbors}}"
AdvSceneSwitcher.condition.video.entry.minSize="Minimum size: {{minSizeX}} x {{minSizeY}}"
AdvSceneSwitcher.condition.video.entry.maxSize="Maximum size: {{maxSizeX}} x {{maxSizeY}}"
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Reduce CPU load by performing check only every {{throttleCount}} milliseconds"
AdvSceneSwitcher.condition.stream="Streaming"
AdvSceneSwitcher.condition.stream.state.start="Stream running"
AdvSceneSwitcher.condition.stream.state.stop="Stream stopped"

View File

@ -5,6 +5,7 @@
#include <QWidget>
#include <QComboBox>
#include <QCheckBox>
#include <QHBoxLayout>
#include <chrono>
#include <opencv2/opencv.hpp>
@ -52,10 +53,14 @@ public:
int _maxSizeX = 0;
int _maxSizeY = 0;
bool _throttleEnabled = false;
int _throttleCount = 3;
private:
bool ScreenshotContainsPattern();
bool ScreenshotContainsObject();
bool Compare();
bool CheckShouldBeSkipped();
std::unique_ptr<AdvSSScreenshotObj> _screenshotData = nullptr;
QImage _matchImage;
@ -64,6 +69,7 @@ private:
std::string(
"/res/cascadeClassifiers/haarcascade_frontalface_alt.xml");
bool _lastMatchResult = false;
int _runCount = 0;
static bool _registered;
static const std::string id;
@ -123,6 +129,8 @@ private slots:
void MaxSizeXChanged(int value);
void MaxSizeYChanged(int value);
void ThrottleEnableChanged(int value);
void ThrottleCountChanged(int value);
void ShowMatchClicked();
signals:
void HeaderInfoChanged(const QString &);
@ -146,6 +154,9 @@ protected:
QSpinBox *_maxSizeX;
QSpinBox *_maxSizeY;
QHBoxLayout *_throttleControlLayout;
QCheckBox *_throttleEnable;
QSpinBox *_throttleCount;
QPushButton *_showMatch;
std::shared_ptr<MacroConditionVideo> _entryData;

View File

@ -45,10 +45,32 @@ bool requiresFileInput(VideoCondition t)
t == VideoCondition::PATTERN;
}
bool MacroConditionVideo::CheckShouldBeSkipped()
{
if (_condition != VideoCondition::PATTERN &&
_condition != VideoCondition::OBJECT) {
return false;
}
if (_throttleEnabled) {
if (_runCount <= _throttleCount) {
_runCount++;
return true;
} else {
_runCount = 0;
}
}
return false;
}
bool MacroConditionVideo::CheckCondition()
{
bool match = false;
if (CheckShouldBeSkipped()) {
return _lastMatchResult;
}
if (_screenshotData && _screenshotData->done) {
match = Compare();
_lastMatchResult = match;
@ -80,6 +102,8 @@ bool MacroConditionVideo::Save(obs_data_t *obj)
obs_data_set_int(obj, "minSizeY", _minSizeY);
obs_data_set_int(obj, "maxSizeX", _maxSizeX);
obs_data_set_int(obj, "maxSizeY", _maxSizeY);
obs_data_set_bool(obj, "throttleEnabled", _throttleEnabled);
obs_data_set_int(obj, "throttleCount", _throttleCount);
return true;
}
@ -116,6 +140,8 @@ bool MacroConditionVideo::Load(obs_data_t *obj)
_minSizeY = obs_data_get_int(obj, "minSizeY");
_maxSizeX = obs_data_get_int(obj, "maxSizeX");
_maxSizeY = obs_data_get_int(obj, "maxSizeY");
_throttleEnabled = obs_data_get_bool(obj, "throttleEnabled");
_throttleCount = obs_data_get_int(obj, "throttleCount");
if (requiresFileInput(_condition)) {
(void)LoadImageFromFile();
@ -353,6 +379,11 @@ MacroConditionVideoEdit::MacroConditionVideoEdit(
_maxSizeX->setMaximum(4096);
_maxSizeY->setMaximum(4096);
_throttleEnable = new QCheckBox();
_throttleCount = new QSpinBox();
_throttleCount->setMinimum(1 * switcher->interval);
_throttleCount->setMaximum(10 * switcher->interval);
_throttleCount->setSingleStep(switcher->interval);
_showMatch = new QPushButton(
obs_module_text("AdvSceneSwitcher.condition.video.showMatch"));
@ -382,6 +413,10 @@ MacroConditionVideoEdit::MacroConditionVideoEdit(
SLOT(MaxSizeYChanged(int)));
QWidget::connect(_modelDataPath, SIGNAL(PathChanged(const QString &)),
this, SLOT(ModelPathChanged(const QString &)));
QWidget::connect(_throttleEnable, SIGNAL(stateChanged(int)), this,
SLOT(ThrottleEnableChanged(int)));
QWidget::connect(_throttleCount, SIGNAL(valueChanged(int)), this,
SLOT(ThrottleCountChanged(int)));
QWidget::connect(_showMatch, SIGNAL(clicked()), this,
SLOT(ShowMatchClicked()));
@ -399,6 +434,8 @@ MacroConditionVideoEdit::MacroConditionVideoEdit(
{"{{maxSizeX}}", _maxSizeX},
{"{{maxSizeY}}", _maxSizeY},
{"{{modelDataPath}}", _modelDataPath},
{"{{throttleEnable}}", _throttleEnable},
{"{{throttleCount}}", _throttleCount},
};
placeWidgets(obs_module_text("AdvSceneSwitcher.condition.video.entry"),
entryLine1Layout, widgetPlaceholders);
@ -425,6 +462,11 @@ MacroConditionVideoEdit::MacroConditionVideoEdit(
"AdvSceneSwitcher.condition.video.entry.maxSize"),
_maxSizeControlLayout, widgetPlaceholders);
_throttleControlLayout = new QHBoxLayout;
placeWidgets(obs_module_text(
"AdvSceneSwitcher.condition.video.entry.throttle"),
_throttleControlLayout, widgetPlaceholders);
QHBoxLayout *showMatchLayout = new QHBoxLayout;
showMatchLayout->addWidget(_showMatch);
showMatchLayout->addStretch();
@ -437,6 +479,7 @@ MacroConditionVideoEdit::MacroConditionVideoEdit(
mainLayout->addLayout(_minSizeControlLayout);
mainLayout->addLayout(_maxSizeControlLayout);
mainLayout->addLayout(showMatchLayout);
mainLayout->addLayout(_throttleControlLayout);
setLayout(mainLayout);
_entryData = entryData;
@ -662,6 +705,27 @@ void MacroConditionVideoEdit::MaxSizeYChanged(int value)
_entryData->_maxSizeY = value;
}
void MacroConditionVideoEdit::ThrottleEnableChanged(int value)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_throttleEnabled = value;
_throttleCount->setEnabled(value);
}
void MacroConditionVideoEdit::ThrottleCountChanged(int value)
{
if (_loading || !_entryData) {
return;
}
std::lock_guard<std::mutex> lock(switcher->m);
_entryData->_throttleCount = value / switcher->interval;
}
QImage markPatterns(cv::Mat &matchResult, QImage &image, QImage &pattern)
{
auto matchImg = QImageToMat(image);
@ -765,6 +829,12 @@ bool needsObjectControls(VideoCondition cond)
return cond == VideoCondition::OBJECT;
}
bool needsThrottleControls(VideoCondition cond)
{
return cond == VideoCondition::PATTERN ||
cond == VideoCondition::OBJECT;
}
void setLayoutVisible(QLayout *layout, bool visible)
{
for (int i = 0; i < layout->count(); ++i) {
@ -791,6 +861,8 @@ void MacroConditionVideoEdit::SetWidgetVisibility()
needsObjectControls(_entryData->_condition));
setLayoutVisible(_modelPathLayout,
needsObjectControls(_entryData->_condition));
setLayoutVisible(_throttleControlLayout,
needsThrottleControls(_entryData->_condition));
adjustSize();
}
@ -812,5 +884,8 @@ void MacroConditionVideoEdit::UpdateEntryData()
_minSizeY->setValue(_entryData->_minSizeY);
_maxSizeX->setValue(_entryData->_maxSizeX);
_maxSizeY->setValue(_entryData->_maxSizeY);
_throttleEnable->setChecked(_entryData->_throttleEnabled);
_throttleCount->setValue(_entryData->_throttleCount *
switcher->interval);
SetWidgetVisibility();
}