From 32d29875ed0b247cb2cd78c283631694893ff32d Mon Sep 17 00:00:00 2001 From: WarmUpTill <19472752+WarmUpTill@users.noreply.github.com> Date: Fri, 23 May 2025 21:27:02 +0200 Subject: [PATCH] Move responsibility of cascade init to ObjDetectParameters --- plugins/video/macro-condition-video.cpp | 45 ++++--------------------- plugins/video/macro-condition-video.hpp | 2 -- plugins/video/parameter-wrappers.cpp | 45 +++++++++++++++++++++++++ plugins/video/parameter-wrappers.hpp | 18 +++++++--- 4 files changed, 65 insertions(+), 45 deletions(-) diff --git a/plugins/video/macro-condition-video.cpp b/plugins/video/macro-condition-video.cpp index 26695493..edd3862b 100644 --- a/plugins/video/macro-condition-video.cpp +++ b/plugins/video/macro-condition-video.cpp @@ -86,18 +86,6 @@ const static std::map pageSegModes = { "AdvSceneSwitcher.condition.video.ocrMode.sparseTextOSD"}, }; -static cv::CascadeClassifier initObjectCascade(std::string &path) -{ - cv::CascadeClassifier cascade; - try { - cascade.load(path); - } catch (...) { - blog(LOG_WARNING, "failed to load model data \"%s\"", - path.c_str()); - } - return cascade; -} - static bool requiresFileInput(VideoCondition t) { return t == VideoCondition::MATCH || t == VideoCondition::DIFFER || @@ -212,10 +200,6 @@ bool MacroConditionVideo::Load(obs_data_t *obj) (void)LoadImageFromFile(); } - if (_condition == VideoCondition::OBJECT) { - LoadModelData(_objMatchParameters.modelPath); - } - return true; } @@ -265,18 +249,6 @@ bool MacroConditionVideo::LoadImageFromFile() return true; } -bool MacroConditionVideo::LoadModelData(std::string &path) -{ - _objMatchParameters.modelPath = path; - _objMatchParameters.cascade = initObjectCascade(path); - return !_objMatchParameters.cascade.empty(); -} - -std::string MacroConditionVideo::GetModelDataPath() const -{ - return _objMatchParameters.modelPath; -} - void MacroConditionVideo::SetPageSegMode(tesseract::PageSegMode mode) { _ocrParameters.SetPageMode(mode); @@ -344,8 +316,11 @@ bool MacroConditionVideo::OutputChanged() bool MacroConditionVideo::ScreenshotContainsObject() { - auto objects = MatchObject(_screenshotData.GetImage(), - _objMatchParameters.cascade, + auto model = _objMatchParameters.GetModel(); + if (!model) { + return false; + } + auto objects = MatchObject(_screenshotData.GetImage(), *model, _objMatchParameters.scaleFactor, _objMatchParameters.minNeighbors, _objMatchParameters.minSize.CV(), @@ -936,7 +911,7 @@ ObjectDetectEdit::ObjectDetectEdit( layout->addLayout(sizeLayout); setLayout(layout); - _modelDataPath->SetPath(_entryData->GetModelDataPath()); + _modelDataPath->SetPath(_entryData->_objMatchParameters.GetModelPath()); _objectScaleThreshold->SetDoubleValue( _entryData->_objMatchParameters.scaleFactor); _minNeighbors->setValue(_entryData->_objMatchParameters.minNeighbors); @@ -987,7 +962,7 @@ void ObjectDetectEdit::ModelPathChanged(const QString &text) { auto lock = LockContext(); std::string path = text.toStdString(); - dataLoaded = _entryData->LoadModelData(path); + dataLoaded = _entryData->_objMatchParameters.SetModelPath(path); } if (!dataLoaded) { DisplayMessage(obs_module_text( @@ -1416,12 +1391,6 @@ void MacroConditionVideoEdit::ConditionChanged(int idx) _previewDialog.PatternMatchParametersChanged( _entryData->_patternMatchParameters); - if (_entryData->GetCondition() == VideoCondition::OBJECT) { - auto path = _entryData->GetModelDataPath(); - _entryData->_objMatchParameters.cascade = - initObjectCascade(path); - } - SetupPreviewDialogParams(); } diff --git a/plugins/video/macro-condition-video.hpp b/plugins/video/macro-condition-video.hpp index f5b50637..f8c319a1 100644 --- a/plugins/video/macro-condition-video.hpp +++ b/plugins/video/macro-condition-video.hpp @@ -42,8 +42,6 @@ public: QImage GetMatchImage() const { return _matchImage; }; void GetScreenshot(bool blocking = false); bool LoadImageFromFile(); - bool LoadModelData(std::string &path); - std::string GetModelDataPath() const; void ResetLastMatch() { _lastMatchResult = false; } double GetCurrentBrightness() const { return _currentBrightness; } void SetPageSegMode(tesseract::PageSegMode); diff --git a/plugins/video/parameter-wrappers.cpp b/plugins/video/parameter-wrappers.cpp index c3784e66..73e7100f 100644 --- a/plugins/video/parameter-wrappers.cpp +++ b/plugins/video/parameter-wrappers.cpp @@ -48,6 +48,31 @@ bool PatternMatchParameters::Load(obs_data_t *obj) return true; } +static std::shared_ptr +initObjectCascade(std::string &path) +{ + auto cascade = std::make_shared(); + try { + cascade->load(path); + } catch (...) { + blog(LOG_WARNING, "failed to load model data \"%s\"", + path.c_str()); + } + return cascade; +} + +bool ObjDetectParameters::LoadModelData() +{ + const auto path = QString::fromStdString(modelPath); + if (!QFileInfo(path).exists(path)) { + cascade.reset(); + return false; + } + + cascade = initObjectCascade(modelPath); + return !cascade->empty(); +} + bool ObjDetectParameters::Save(obs_data_t *obj) const { auto data = obs_data_create(); @@ -107,9 +132,29 @@ bool ObjDetectParameters::Load(obs_data_t *obj) minSize.Load(data, "minSize"); maxSize.Load(data, "maxSize"); obs_data_release(data); + return true; } +bool ObjDetectParameters::SetModelPath(const std::string &path) +{ + modelPath = path; + return LoadModelData(); +} + +std::shared_ptr ObjDetectParameters::GetModel() +{ + if (cascade && !cascade->empty()) { + return cascade; + } + + if (!LoadModelData()) { + return {}; + } + + return cascade; +} + bool AreaParameters::Save(obs_data_t *obj) const { auto data = obs_data_create(); diff --git a/plugins/video/parameter-wrappers.hpp b/plugins/video/parameter-wrappers.hpp index 4d758c35..a2421f27 100644 --- a/plugins/video/parameter-wrappers.hpp +++ b/plugins/video/parameter-wrappers.hpp @@ -68,15 +68,23 @@ public: bool Save(obs_data_t *obj) const; bool Load(obs_data_t *obj); - std::string modelPath = - obs_get_module_data_path(obs_current_module()) + - std::string( - "/res/cascadeClassifiers/haarcascade_frontalface_alt.xml"); - cv::CascadeClassifier cascade; + bool SetModelPath(const std::string &path); + const std::string &GetModelPath() const { return modelPath; } + std::shared_ptr GetModel(); + NumberVariable scaleFactor = defaultScaleFactor; int minNeighbors = minMinNeighbors; Size minSize{0, 0}; Size maxSize{0, 0}; + +private: + bool LoadModelData(); + + std::shared_ptr cascade; + std::string modelPath = + obs_get_module_data_path(obs_current_module()) + + std::string( + "/res/cascadeClassifiers/haarcascade_frontalface_alt.xml"); }; class OCRParameters {