mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-04-26 00:01:13 -05:00
Rework preview dialog to improve performance
Object detection and OCR models were constantly being re-initialized each frame due to copy in the signal / slot handling
This commit is contained in:
parent
32d29875ed
commit
721a786e79
|
|
@ -134,13 +134,13 @@ void PreviewDialog::PatternMatchParametersChanged(
|
||||||
void PreviewDialog::ObjDetectParametersChanged(const ObjDetectParameters ¶ms)
|
void PreviewDialog::ObjDetectParametersChanged(const ObjDetectParameters ¶ms)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(_mtx);
|
std::unique_lock<std::mutex> lock(_mtx);
|
||||||
_objDetectParams = params;
|
_objDetectParams = std::make_shared<ObjDetectParameters>(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreviewDialog::OCRParametersChanged(const OCRParameters ¶ms)
|
void PreviewDialog::OCRParametersChanged(const OCRParameters ¶ms)
|
||||||
{
|
{
|
||||||
std::unique_lock<std::mutex> lock(_mtx);
|
std::unique_lock<std::mutex> lock(_mtx);
|
||||||
_ocrParams = params;
|
_ocrParams = std::make_shared<OCRParameters>(params);
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreviewDialog::VideoSelectionChanged(const VideoInput &video)
|
void PreviewDialog::VideoSelectionChanged(const VideoInput &video)
|
||||||
|
|
@ -262,13 +262,13 @@ static void markObjects(QImage &image, std::vector<cv::Rect> &objects)
|
||||||
|
|
||||||
PreviewImage::PreviewImage(std::mutex &mtx) : _mtx(mtx) {}
|
PreviewImage::PreviewImage(std::mutex &mtx) : _mtx(mtx) {}
|
||||||
|
|
||||||
void PreviewImage::CreateImage(const VideoInput &video, PreviewType type,
|
void PreviewImage::CreateImage(
|
||||||
const PatternMatchParameters &patternMatchParams,
|
const VideoInput &video, PreviewType type,
|
||||||
const PatternImageData &patternImageData,
|
const PatternMatchParameters &patternMatchParams,
|
||||||
ObjDetectParameters objDetectParams,
|
const PatternImageData &patternImageData,
|
||||||
OCRParameters ocrParams,
|
std::shared_ptr<ObjDetectParameters> objDetectParams,
|
||||||
const AreaParameters &areaParams,
|
std::shared_ptr<OCRParameters> ocrParams,
|
||||||
VideoCondition condition)
|
const AreaParameters &areaParams, VideoCondition condition)
|
||||||
{
|
{
|
||||||
auto source = obs_weak_source_get_source(video.GetVideo());
|
auto source = obs_weak_source_get_source(video.GetVideo());
|
||||||
QRect screenshotArea;
|
QRect screenshotArea;
|
||||||
|
|
@ -308,61 +308,94 @@ void PreviewImage::CreateImage(const VideoInput &video, PreviewType type,
|
||||||
emit ImageReady(QPixmap::fromImage(screenshot.GetImage()));
|
emit ImageReady(QPixmap::fromImage(screenshot.GetImage()));
|
||||||
}
|
}
|
||||||
|
|
||||||
void PreviewImage::MarkMatch(QImage &screenshot,
|
void PreviewImage::MarkMatch(
|
||||||
const PatternMatchParameters &patternMatchParams,
|
QImage &screenshot, const PatternMatchParameters &patternMatchParams,
|
||||||
const PatternImageData &patternImageData,
|
const PatternImageData &patternImageData,
|
||||||
ObjDetectParameters &objDetectParams,
|
std::shared_ptr<ObjDetectParameters> objDetectParams,
|
||||||
const OCRParameters &ocrParams,
|
std::shared_ptr<OCRParameters> ocrParams, VideoCondition condition)
|
||||||
VideoCondition condition)
|
|
||||||
{
|
{
|
||||||
if (condition == VideoCondition::PATTERN) {
|
if (condition == VideoCondition::PATTERN) {
|
||||||
cv::Mat result;
|
MarkPatternMatch(screenshot, patternMatchParams,
|
||||||
double matchValue =
|
patternImageData);
|
||||||
std::numeric_limits<double>::signaling_NaN();
|
|
||||||
MatchPattern(screenshot, patternImageData,
|
|
||||||
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"));
|
|
||||||
} else if (result.cols == 1 && result.rows == 1) {
|
|
||||||
emit StatusUpdate(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.condition.video.patternMatchSuccessFullImage"));
|
|
||||||
} else {
|
|
||||||
emit StatusUpdate(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.condition.video.patternMatchSuccess"));
|
|
||||||
markPatterns(result, screenshot,
|
|
||||||
patternImageData.rgbaPattern);
|
|
||||||
}
|
|
||||||
} else if (condition == VideoCondition::OBJECT) {
|
} else if (condition == VideoCondition::OBJECT) {
|
||||||
auto objects = MatchObject(screenshot, objDetectParams.cascade,
|
MarkObjectMatch(screenshot, objDetectParams);
|
||||||
objDetectParams.scaleFactor,
|
|
||||||
objDetectParams.minNeighbors,
|
|
||||||
objDetectParams.minSize.CV(),
|
|
||||||
objDetectParams.maxSize.CV());
|
|
||||||
if (objects.empty()) {
|
|
||||||
emit StatusUpdate(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.condition.video.objectMatchFail"));
|
|
||||||
} else {
|
|
||||||
emit StatusUpdate(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.condition.video.objectMatchSuccess"));
|
|
||||||
markObjects(screenshot, objects);
|
|
||||||
}
|
|
||||||
} else if (condition == VideoCondition::OCR) {
|
} else if (condition == VideoCondition::OCR) {
|
||||||
auto text = RunOCR(ocrParams.GetOCR(), screenshot,
|
MarkOCRMatch(screenshot, ocrParams);
|
||||||
ocrParams.color, ocrParams.colorThreshold);
|
|
||||||
|
|
||||||
if (!text) {
|
|
||||||
emit StatusUpdate(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.condition.video.ocrMatchFail"));
|
|
||||||
}
|
|
||||||
|
|
||||||
QString status(obs_module_text(
|
|
||||||
"AdvSceneSwitcher.condition.video.ocrMatchSuccess"));
|
|
||||||
emit StatusUpdate(status.arg(QString::fromStdString(*text)));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void PreviewImage::MarkPatternMatch(
|
||||||
|
QImage &screenshot, const PatternMatchParameters &patternMatchParams,
|
||||||
|
const PatternImageData &patternImageData)
|
||||||
|
{
|
||||||
|
cv::Mat result;
|
||||||
|
double matchValue = std::numeric_limits<double>::signaling_NaN();
|
||||||
|
MatchPattern(screenshot, patternImageData, 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"));
|
||||||
|
} else if (result.cols == 1 && result.rows == 1) {
|
||||||
|
emit StatusUpdate(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.condition.video.patternMatchSuccessFullImage"));
|
||||||
|
} else {
|
||||||
|
emit StatusUpdate(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.condition.video.patternMatchSuccess"));
|
||||||
|
markPatterns(result, screenshot, patternImageData.rgbaPattern);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreviewImage::MarkObjectMatch(
|
||||||
|
QImage &screenshot,
|
||||||
|
const std::shared_ptr<ObjDetectParameters> &objDetectParams)
|
||||||
|
{
|
||||||
|
if (!objDetectParams) {
|
||||||
|
emit StatusUpdate(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.condition.video.objectMatchFail"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto model = objDetectParams->GetModel();
|
||||||
|
if (!model) {
|
||||||
|
emit StatusUpdate(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.condition.video.objectMatchFail"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto objects = MatchObject(screenshot, *model,
|
||||||
|
objDetectParams->scaleFactor,
|
||||||
|
objDetectParams->minNeighbors,
|
||||||
|
objDetectParams->minSize.CV(),
|
||||||
|
objDetectParams->maxSize.CV());
|
||||||
|
if (objects.empty()) {
|
||||||
|
emit StatusUpdate(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.condition.video.objectMatchFail"));
|
||||||
|
} else {
|
||||||
|
emit StatusUpdate(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.condition.video.objectMatchSuccess"));
|
||||||
|
markObjects(screenshot, objects);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void PreviewImage::MarkOCRMatch(QImage &screenshot,
|
||||||
|
const std::shared_ptr<OCRParameters> &ocrParams)
|
||||||
|
{
|
||||||
|
if (!ocrParams) {
|
||||||
|
emit StatusUpdate(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.condition.video.ocrMatchFail"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
auto text = RunOCR(ocrParams->GetOCR(), screenshot, ocrParams->color,
|
||||||
|
ocrParams->colorThreshold);
|
||||||
|
|
||||||
|
if (!text) {
|
||||||
|
emit StatusUpdate(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.condition.video.ocrMatchFail"));
|
||||||
|
}
|
||||||
|
|
||||||
|
QString status(obs_module_text(
|
||||||
|
"AdvSceneSwitcher.condition.video.ocrMatchSuccess"));
|
||||||
|
emit StatusUpdate(status.arg(QString::fromStdString(*text)));
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace advss
|
} // namespace advss
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,10 @@ public:
|
||||||
public slots:
|
public slots:
|
||||||
void CreateImage(const VideoInput &, PreviewType,
|
void CreateImage(const VideoInput &, PreviewType,
|
||||||
const PatternMatchParameters &,
|
const PatternMatchParameters &,
|
||||||
const PatternImageData &, ObjDetectParameters,
|
const PatternImageData &,
|
||||||
OCRParameters, const AreaParameters &, VideoCondition);
|
std::shared_ptr<ObjDetectParameters>,
|
||||||
|
std::shared_ptr<OCRParameters>, const AreaParameters &,
|
||||||
|
VideoCondition);
|
||||||
signals:
|
signals:
|
||||||
void ImageReady(const QPixmap &);
|
void ImageReady(const QPixmap &);
|
||||||
void ValueUpdate(double);
|
void ValueUpdate(double);
|
||||||
|
|
@ -35,8 +37,14 @@ signals:
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void MarkMatch(QImage &screenshot, const PatternMatchParameters &,
|
void MarkMatch(QImage &screenshot, const PatternMatchParameters &,
|
||||||
const PatternImageData &, ObjDetectParameters &,
|
const PatternImageData &,
|
||||||
const OCRParameters &, VideoCondition);
|
std::shared_ptr<ObjDetectParameters>,
|
||||||
|
std::shared_ptr<OCRParameters>, VideoCondition);
|
||||||
|
void MarkPatternMatch(QImage &, const PatternMatchParameters &,
|
||||||
|
const PatternImageData &);
|
||||||
|
void MarkObjectMatch(QImage &,
|
||||||
|
const std::shared_ptr<ObjDetectParameters> &);
|
||||||
|
void MarkOCRMatch(QImage &, const std::shared_ptr<OCRParameters> &);
|
||||||
|
|
||||||
std::mutex &_mtx;
|
std::mutex &_mtx;
|
||||||
};
|
};
|
||||||
|
|
@ -67,8 +75,9 @@ signals:
|
||||||
void SelectionAreaChanged(QRect area);
|
void SelectionAreaChanged(QRect area);
|
||||||
void NeedImage(const VideoInput &, PreviewType,
|
void NeedImage(const VideoInput &, PreviewType,
|
||||||
const PatternMatchParameters &, const PatternImageData &,
|
const PatternMatchParameters &, const PatternImageData &,
|
||||||
ObjDetectParameters, OCRParameters,
|
std::shared_ptr<ObjDetectParameters>,
|
||||||
const AreaParameters &, VideoCondition);
|
std::shared_ptr<OCRParameters>, const AreaParameters &,
|
||||||
|
VideoCondition);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void Start();
|
void Start();
|
||||||
|
|
@ -81,8 +90,8 @@ private:
|
||||||
VideoInput _video;
|
VideoInput _video;
|
||||||
PatternMatchParameters _patternMatchParams;
|
PatternMatchParameters _patternMatchParams;
|
||||||
PatternImageData _patternImageData;
|
PatternImageData _patternImageData;
|
||||||
ObjDetectParameters _objDetectParams;
|
std::shared_ptr<ObjDetectParameters> _objDetectParams;
|
||||||
OCRParameters _ocrParams;
|
std::shared_ptr<OCRParameters> _ocrParams;
|
||||||
AreaParameters _areaParams;
|
AreaParameters _areaParams;
|
||||||
|
|
||||||
VideoCondition _condition = VideoCondition::PATTERN;
|
VideoCondition _condition = VideoCondition::PATTERN;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user