diff --git a/data/locale/en-US.ini b/data/locale/en-US.ini index 7b81df7e..94ad5c7a 100644 --- a/data/locale/en-US.ini +++ b/data/locale/en-US.ini @@ -245,6 +245,7 @@ AdvSceneSwitcher.condition.video.showMatch="Show match" AdvSceneSwitcher.condition.video.showMatch.loading="Checking for match" AdvSceneSwitcher.condition.video.screenshotFail="Failed to get screenshot of source!" AdvSceneSwitcher.condition.video.screenshotEmpty="Screenshot is empty - Is the source visible?" +AdvSceneSwitcher.condition.video.patternMatchValue="Current matching value: " AdvSceneSwitcher.condition.video.patternMatchFail="Pattern was not found!" AdvSceneSwitcher.condition.video.patternMatchSuccess="Pattern is highlighted in red" AdvSceneSwitcher.condition.video.patternMatchSuccessFullImage="Full image matches the pattern" diff --git a/src/macro-external/video/macro-condition-video.cpp b/src/macro-external/video/macro-condition-video.cpp index 8d4e75b7..1049f6ac 100644 --- a/src/macro-external/video/macro-condition-video.cpp +++ b/src/macro-external/video/macro-condition-video.cpp @@ -278,7 +278,7 @@ bool MacroConditionVideo::ScreenshotContainsPattern() { cv::Mat result; MatchPattern(_screenshotData.image, _patternImageData, - _patternMatchParameters.threshold, result, + _patternMatchParameters.threshold, result, nullptr, _patternMatchParameters.useAlphaAsMask, _patternMatchParameters.matchMode); if (result.total() == 0) { @@ -299,7 +299,7 @@ bool MacroConditionVideo::OutputChanged() cv::Mat result; _patternImageData = CreatePatternData(_matchImage); MatchPattern(_screenshotData.image, _patternImageData, - _patternMatchParameters.threshold, result, + _patternMatchParameters.threshold, result, nullptr, _patternMatchParameters.useAlphaAsMask, _patternMatchParameters.matchMode); if (result.total() == 0) { diff --git a/src/macro-external/video/opencv-helpers.cpp b/src/macro-external/video/opencv-helpers.cpp index b012e1e3..8b9623af 100644 --- a/src/macro-external/video/opencv-helpers.cpp +++ b/src/macro-external/video/opencv-helpers.cpp @@ -32,8 +32,8 @@ static void invertPatternMatchResult(cv::Mat &mat) } void MatchPattern(QImage &img, const PatternImageData &patternData, - double threshold, cv::Mat &result, bool useAlphaAsMask, - cv::TemplateMatchModes matchMode) + double threshold, cv::Mat &result, double *pBestFitValue, + bool useAlphaAsMask, cv::TemplateMatchModes matchMode) { if (img.isNull() || patternData.rgbaPattern.empty()) { return; @@ -72,15 +72,21 @@ void MatchPattern(QImage &img, const PatternImageData &patternData, if (matchMode == cv::TM_SQDIFF_NORMED) { invertPatternMatchResult(result); } + + if (pBestFitValue) { + cv::minMaxLoc(result, nullptr, pBestFitValue); + } + cv::threshold(result, result, threshold, 0.0, cv::THRESH_TOZERO); } void MatchPattern(QImage &img, QImage &pattern, double threshold, - cv::Mat &result, bool useAlphaAsMask, + cv::Mat &result, double *pBestFitValue, bool useAlphaAsMask, cv::TemplateMatchModes matchColor) { auto data = CreatePatternData(pattern); - MatchPattern(img, data, threshold, result, useAlphaAsMask, matchColor); + MatchPattern(img, data, threshold, result, pBestFitValue, + useAlphaAsMask, matchColor); } std::vector MatchObject(QImage &img, cv::CascadeClassifier &cascade, diff --git a/src/macro-external/video/opencv-helpers.hpp b/src/macro-external/video/opencv-helpers.hpp index 57a73470..9632147b 100644 --- a/src/macro-external/video/opencv-helpers.hpp +++ b/src/macro-external/video/opencv-helpers.hpp @@ -49,10 +49,10 @@ struct PatternImageData { PatternImageData CreatePatternData(const QImage &pattern); void MatchPattern(QImage &img, const PatternImageData &patternData, - double threshold, cv::Mat &result, bool useAlphaAsMask, - cv::TemplateMatchModes matchMode); + double threshold, cv::Mat &result, double *pBestFitValue, + bool useAlphaAsMask, cv::TemplateMatchModes matchMode); void MatchPattern(QImage &img, QImage &pattern, double threshold, - cv::Mat &result, bool useAlphaAsMask, + cv::Mat &result, double *pBestFitValue, bool useAlphaAsMask, cv::TemplateMatchModes matchMode); std::vector MatchObject(QImage &img, cv::CascadeClassifier &cascade, double scaleFactor, int minNeighbors, diff --git a/src/macro-external/video/preview-dialog.cpp b/src/macro-external/video/preview-dialog.cpp index e8b2c8ae..249cdda4 100644 --- a/src/macro-external/video/preview-dialog.cpp +++ b/src/macro-external/video/preview-dialog.cpp @@ -17,6 +17,7 @@ PreviewDialog::PreviewDialog(QWidget *parent) setWindowFlags(windowFlags() | Qt::WindowMaximizeButtonHint | Qt::WindowCloseButtonHint); + _valueLabel = new QLabel(""); _statusLabel = new QLabel(obs_module_text( "AdvSceneSwitcher.condition.video.showMatch.loading")); resize(parent->window()->size()); @@ -37,6 +38,7 @@ PreviewDialog::PreviewDialog(QWidget *parent) _scrollArea->setWidget(wrapper); _scrollArea->setWidgetResizable(true); QVBoxLayout *layout = new QVBoxLayout; + layout->addWidget(_valueLabel); layout->addWidget(_statusLabel); layout->addWidget(_scrollArea); setLayout(layout); @@ -93,13 +95,17 @@ void PreviewDialog::ShowMatch() { _type = PreviewType::SHOW_MATCH; _rubberBand->hide(); + _valueLabel->show(); Start(); + _statusLabel->setText(""); } void PreviewDialog::SelectArea() { _selectingArea = false; _type = PreviewType::SELECT_AREA; + _rubberBand->show(); + _valueLabel->hide(); Start(); DrawFrame(); _statusLabel->setText(obs_module_text( @@ -158,6 +164,14 @@ void PreviewDialog::ConditionChanged(int cond) _condition = static_cast(cond); } +void PreviewDialog::UpdateValue(double matchValue) +{ + std::string temp = obs_module_text( + "AdvSceneSwitcher.condition.video.patternMatchValue"); + temp += "%.3f"; + _valueLabel->setText(QString::asprintf(temp.c_str(), matchValue)); +} + void PreviewDialog::UpdateStatus(const QString &status) { _statusLabel->setText(status); @@ -194,6 +208,8 @@ void PreviewDialog::Start() &PreviewDialog::UpdateImage); connect(worker, &PreviewImage::StatusUpdate, this, &PreviewDialog::UpdateStatus); + connect(worker, &PreviewImage::ValueUpdate, this, + &PreviewDialog::UpdateValue); connect(this, &PreviewDialog::NeedImage, worker, &PreviewImage::CreateImage); _thread.start(); @@ -285,7 +301,8 @@ void PreviewImage::CreateImage(const VideoInput &video, PreviewType type, patternImageData, objDetectParams, ocrParams, condition); } else { - emit StatusUpdate(""); + emit StatusUpdate(obs_module_text( + "AdvSceneSwitcher.condition.video.selectArea.status")); } emit ImageReady(QPixmap::fromImage(screenshot.image)); } @@ -299,10 +316,13 @@ void PreviewImage::MarkMatch(QImage &screenshot, { if (condition == VideoCondition::PATTERN) { cv::Mat result; + double matchValue = + std::numeric_limits::signaling_NaN(); MatchPattern(screenshot, patternImageData, - patternMatchParams.threshold, result, + patternMatchParams.threshold, result, &matchValue, patternMatchParams.useAlphaAsMask, patternMatchParams.matchMode); + emit ValueUpdate(matchValue); if (result.total() == 0 || countNonZero(result) == 0) { emit StatusUpdate(obs_module_text( "AdvSceneSwitcher.condition.video.patternMatchFail")); diff --git a/src/macro-external/video/preview-dialog.hpp b/src/macro-external/video/preview-dialog.hpp index a55eef17..4cd739b8 100644 --- a/src/macro-external/video/preview-dialog.hpp +++ b/src/macro-external/video/preview-dialog.hpp @@ -30,6 +30,7 @@ public slots: OCRParameters, const AreaParameters &, VideoCondition); signals: void ImageReady(const QPixmap &); + void ValueUpdate(double); void StatusUpdate(const QString &); private: @@ -60,6 +61,7 @@ public slots: void ConditionChanged(int cond); private slots: void UpdateImage(const QPixmap &); + void UpdateValue(double); void UpdateStatus(const QString &); signals: void SelectionAreaChanged(QRect area); @@ -85,6 +87,7 @@ private: VideoCondition _condition = VideoCondition::PATTERN; QScrollArea *_scrollArea; + QLabel *_valueLabel; QLabel *_statusLabel; QLabel *_imageLabel;