diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index edcf147e..fd467760 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -2196,6 +2196,8 @@ AdvSceneSwitcher.tempVar.recording.durationSeconds.description="Recording durati AdvSceneSwitcher.tempVar.recording.lastSavePath="Last save path" AdvSceneSwitcher.tempVar.recording.lastSavePath.description="The file path of the last saved recording." +AdvSceneSwitcher.tempVar.video.similarity="Similarity Rating" +AdvSceneSwitcher.tempVar.video.similarity.description="Values range from 0 to 1, where 0 means dissimilar and 1 means highly similar." AdvSceneSwitcher.tempVar.video.patternCount="Pattern count" AdvSceneSwitcher.tempVar.video.patternCount.description="The number of times the given pattern has been found in a given video input frame." AdvSceneSwitcher.tempVar.video.objectCount="Object count" diff --git a/plugins/video/macro-condition-video.cpp b/plugins/video/macro-condition-video.cpp index e83ab9cf..425d5704 100644 --- a/plugins/video/macro-condition-video.cpp +++ b/plugins/video/macro-condition-video.cpp @@ -273,15 +273,18 @@ void MacroConditionVideo::SetCondition(VideoCondition condition) bool MacroConditionVideo::ScreenshotContainsPattern() { cv::Mat result; - MatchPattern(_screenshotData.GetImage(), _patternImageData, - _patternMatchParameters.threshold, result, nullptr, - _patternMatchParameters.useAlphaAsMask, - _patternMatchParameters.matchMode); + double bestMatchValue = + MatchPattern(_screenshotData.GetImage(), _patternImageData, + _patternMatchParameters.threshold, result, + _patternMatchParameters.useAlphaAsMask, + _patternMatchParameters.matchMode); if (result.total() == 0) { + SetTempVarValue("similarity", std::to_string(bestMatchValue)); SetTempVarValue("patternCount", "0"); return false; } const auto count = countNonZero(result); + SetTempVarValue("similarity", std::to_string(bestMatchValue)); SetTempVarValue("patternCount", std::to_string(count)); return count > 0; } @@ -304,10 +307,12 @@ bool MacroConditionVideo::OutputChanged() cv::Mat result; _patternImageData = CreatePatternData(_matchImage); - MatchPattern(_screenshotData.GetImage(), _patternImageData, - _patternMatchParameters.threshold, result, nullptr, - _patternMatchParameters.useAlphaAsMask, - _patternMatchParameters.matchMode); + double bestMatchValue = + MatchPattern(_screenshotData.GetImage(), _patternImageData, + _patternMatchParameters.threshold, result, + _patternMatchParameters.useAlphaAsMask, + _patternMatchParameters.matchMode); + SetTempVarValue("similarity", std::to_string(bestMatchValue)); if (result.total() == 0) { return false; } @@ -411,7 +416,25 @@ void MacroConditionVideo::SetupTempVars() { MacroCondition::SetupTempVars(); switch (_condition) { + case VideoCondition::HAS_CHANGED: + case VideoCondition::HAS_NOT_CHANGED: + if (!_patternMatchParameters.useForChangedCheck) { + break; + } + AddTempvar( + "similarity", + obs_module_text( + "AdvSceneSwitcher.tempVar.video.similarity"), + obs_module_text( + "AdvSceneSwitcher.tempVar.video.similarity.description")); + break; case VideoCondition::PATTERN: + AddTempvar( + "similarity", + obs_module_text( + "AdvSceneSwitcher.tempVar.video.similarity"), + obs_module_text( + "AdvSceneSwitcher.tempVar.video.similarity.description")); AddTempvar( "patternCount", obs_module_text( @@ -451,8 +474,6 @@ void MacroConditionVideo::SetupTempVars() break; case VideoCondition::MATCH: case VideoCondition::DIFFER: - case VideoCondition::HAS_NOT_CHANGED: - case VideoCondition::HAS_CHANGED: case VideoCondition::NO_IMAGE: default: break; @@ -1477,6 +1498,7 @@ void MacroConditionVideoEdit::UsePatternForChangedCheckChanged(int value) { GUARD_LOADING_AND_LOCK(); _entryData->_patternMatchParameters.useForChangedCheck = value; + _entryData->SetupTempVars(); SetWidgetVisibility(); } diff --git a/plugins/video/macro-condition-video.hpp b/plugins/video/macro-condition-video.hpp index f8c319a1..f274fe97 100644 --- a/plugins/video/macro-condition-video.hpp +++ b/plugins/video/macro-condition-video.hpp @@ -50,6 +50,7 @@ public: void SetCondition(VideoCondition); VideoCondition GetCondition() const { return _condition; } + void SetupTempVars(); VideoInput _video; std::string _file = obs_module_text("AdvSceneSwitcher.enterPath"); @@ -89,8 +90,6 @@ private: bool Compare(); bool CheckShouldBeSkipped(); - void SetupTempVars(); - VideoCondition _condition = VideoCondition::MATCH; bool _getNextScreenshot = true; diff --git a/plugins/video/opencv-helpers.cpp b/plugins/video/opencv-helpers.cpp index ffacc256..63a920d0 100644 --- a/plugins/video/opencv-helpers.cpp +++ b/plugins/video/opencv-helpers.cpp @@ -48,20 +48,18 @@ static void preprocessPatternMatchResult(cv::Mat &mat, bool invert) } } -void MatchPattern(QImage &img, const PatternImageData &patternData, - double threshold, cv::Mat &result, double *pBestFitValue, - bool useAlphaAsMask, cv::TemplateMatchModes matchMode) +double MatchPattern(QImage &img, const PatternImageData &patternData, + double threshold, cv::Mat &result, bool useAlphaAsMask, + cv::TemplateMatchModes matchMode) { + double bestFitValue = std::numeric_limits::signaling_NaN(); result = cv::Mat(0, 0, CV_32F); - if (pBestFitValue) { - *pBestFitValue = std::numeric_limits::signaling_NaN(); - } if (img.isNull() || patternData.rgbaPattern.empty()) { - return; + return bestFitValue; } if (img.height() < patternData.rgbaPattern.rows || img.width() < patternData.rgbaPattern.cols) { - return; + return bestFitValue; } auto input = QImageToMat(img); @@ -94,20 +92,18 @@ void MatchPattern(QImage &img, const PatternImageData &patternData, // -> Invert TM_SQDIFF_NORMED in the preprocess step preprocessPatternMatchResult(result, matchMode == cv::TM_SQDIFF_NORMED); - if (pBestFitValue) { - cv::minMaxLoc(result, nullptr, pBestFitValue); - } - + cv::minMaxLoc(result, nullptr, &bestFitValue); cv::threshold(result, result, threshold, 0.0, cv::THRESH_TOZERO); + return bestFitValue; } -void MatchPattern(QImage &img, QImage &pattern, double threshold, - cv::Mat &result, double *pBestFitValue, bool useAlphaAsMask, - cv::TemplateMatchModes matchColor) +double MatchPattern(QImage &img, QImage &pattern, double threshold, + cv::Mat &result, bool useAlphaAsMask, + cv::TemplateMatchModes matchColor) { auto data = CreatePatternData(pattern); - MatchPattern(img, data, threshold, result, pBestFitValue, - useAlphaAsMask, matchColor); + return MatchPattern(img, data, threshold, result, useAlphaAsMask, + matchColor); } std::vector MatchObject(QImage &img, cv::CascadeClassifier &cascade, diff --git a/plugins/video/opencv-helpers.hpp b/plugins/video/opencv-helpers.hpp index 5293c23e..5f95d545 100644 --- a/plugins/video/opencv-helpers.hpp +++ b/plugins/video/opencv-helpers.hpp @@ -62,12 +62,12 @@ struct PatternImageData { }; PatternImageData CreatePatternData(const QImage &pattern); -void MatchPattern(QImage &img, const PatternImageData &patternData, - double threshold, cv::Mat &result, double *pBestFitValue, - bool useAlphaAsMask, cv::TemplateMatchModes matchMode); -void MatchPattern(QImage &img, QImage &pattern, double threshold, - cv::Mat &result, double *pBestFitValue, bool useAlphaAsMask, - cv::TemplateMatchModes matchMode); +double MatchPattern(QImage &img, const PatternImageData &patternData, + double threshold, cv::Mat &result, bool useAlphaAsMask, + cv::TemplateMatchModes matchMode); +double MatchPattern(QImage &img, QImage &pattern, double threshold, + cv::Mat &result, bool useAlphaAsMask, + cv::TemplateMatchModes matchMode); std::vector MatchObject(QImage &img, cv::CascadeClassifier &cascade, double scaleFactor, int minNeighbors, const cv::Size &minSize, diff --git a/plugins/video/preview-dialog.cpp b/plugins/video/preview-dialog.cpp index 3383fa9d..844ccebd 100644 --- a/plugins/video/preview-dialog.cpp +++ b/plugins/video/preview-dialog.cpp @@ -329,10 +329,10 @@ void PreviewImage::MarkPatternMatch( const PatternImageData &patternImageData) { cv::Mat result; - double matchValue = std::numeric_limits::signaling_NaN(); - MatchPattern(screenshot, patternImageData, patternMatchParams.threshold, - result, &matchValue, patternMatchParams.useAlphaAsMask, - patternMatchParams.matchMode); + double matchValue = MatchPattern(screenshot, patternImageData, + patternMatchParams.threshold, result, + patternMatchParams.useAlphaAsMask, + patternMatchParams.matchMode); emit ValueUpdate(matchValue); if (result.total() == 0 || countNonZero(result) == 0) { emit StatusUpdate(obs_module_text(