Cleanup video condition

* Style changes
* Separate functionality into different widgets
* Fix typos
This commit is contained in:
WarmUpTill 2023-05-18 10:09:08 +02:00 committed by WarmUpTill
parent 4315d309f2
commit 2eca2cc2e9
8 changed files with 647 additions and 514 deletions

File diff suppressed because it is too large Load Diff

View File

@ -56,8 +56,8 @@ public:
NumberVariable<double> _brightnessThreshold = 0.5;
PatternMatchParameters _patternMatchParameters;
ObjDetectParameters _objMatchParameters;
OCRParameters _ocrParamters;
AreaParamters _areaParameters;
OCRParameters _ocrParameters;
AreaParameters _areaParameters;
bool _throttleEnabled = false;
int _throttleCount = 3;
@ -84,6 +84,111 @@ private:
static const std::string id;
};
class BrightnessEdit : public QWidget {
Q_OBJECT
public:
BrightnessEdit(QWidget *parent,
const std::shared_ptr<MacroConditionVideo> &);
private slots:
void BrightnessThresholdChanged(const NumberVariable<double> &);
void UpdateCurrentBrightness();
private:
SliderSpinBox *_threshold;
QLabel *_current;
QTimer _timer;
std::shared_ptr<MacroConditionVideo> _data;
bool _loading = true;
};
class OCREdit : public QWidget {
Q_OBJECT
public:
OCREdit(QWidget *parent, PreviewDialog *,
const std::shared_ptr<MacroConditionVideo> &);
private slots:
void SelectColorClicked();
void MatchTextChanged();
void RegexChanged(RegexConfig conf);
void PageSegModeChanged(int);
private:
void SetupColorLabel(const QColor &);
VariableTextEdit *_matchText;
RegexConfigWidget *_regex;
QLabel *_textColor;
QPushButton *_selectColor;
QComboBox *_pageSegMode;
PreviewDialog *_previewDialog;
std::shared_ptr<MacroConditionVideo> _data;
bool _loading = true;
};
class ObjectDetectEdit : public QWidget {
Q_OBJECT
public:
ObjectDetectEdit(QWidget *parent, PreviewDialog *,
const std::shared_ptr<MacroConditionVideo> &);
private slots:
void ModelPathChanged(const QString &text);
void ObjectScaleThresholdChanged(const NumberVariable<double> &);
void MinNeighborsChanged(int value);
void MinSizeChanged(Size value);
void MaxSizeChanged(Size value);
private:
FileSelection *_modelDataPath;
SliderSpinBox *_objectScaleThreshold;
QSpinBox *_minNeighbors;
QLabel *_minNeighborsDescription;
SizeSelection *_minSize;
SizeSelection *_maxSize;
PreviewDialog *_previewDialog;
std::shared_ptr<MacroConditionVideo> _data;
bool _loading = true;
};
class AreaEdit : public QWidget {
Q_OBJECT
public:
AreaEdit(QWidget *parent, PreviewDialog *,
const std::shared_ptr<MacroConditionVideo> &);
private slots:
void CheckAreaEnableChanged(int value);
void CheckAreaChanged(Area);
void CheckAreaChanged(QRect area);
void SelectAreaClicked();
signals:
void Resized();
private:
void SetWidgetVisibility();
QCheckBox *_checkAreaEnable;
AreaSelection *_checkArea;
QPushButton *_selectArea;
PreviewDialog *_previewDialog;
std::shared_ptr<MacroConditionVideo> _data;
bool _loading = true;
};
class MacroConditionVideoEdit : public QWidget {
Q_OBJECT
@ -117,38 +222,20 @@ private slots:
void UseAlphaAsMaskChanged(int value);
void PatternMatchModeChanged(int value);
void BrightnessThresholdChanged(const NumberVariable<double> &);
void ModelPathChanged(const QString &text);
void ObjectScaleThresholdChanged(const NumberVariable<double> &);
void MinNeighborsChanged(int value);
void MinSizeChanged(Size value);
void MaxSizeChanged(Size value);
void SelectColorClicked();
void MatchTextChanged();
void RegexChanged(RegexConfig conf);
void PageSegModeChanged(int);
void CheckAreaEnableChanged(int value);
void CheckAreaChanged(Area);
void CheckAreaChanged(QRect area);
void SelectAreaClicked();
void ThrottleEnableChanged(int value);
void ThrottleCountChanged(int value);
void ShowMatchClicked();
void UpdateCurrentBrightness();
void SetWidgetVisibility();
void Resize();
signals:
void VideoSelectionChanged(const VideoInput &);
void HeaderInfoChanged(const QString &);
private:
void SetWidgetVisibility();
void HandleVideoInputUpdate();
void SetupPreviewDialogParams();
void SetupColorLabel(const QColor &);
QComboBox *_videoInputTypes;
SceneSelectionWidget *_scenes;
@ -165,40 +252,18 @@ private:
QHBoxLayout *_patternMatchModeLayout;
QComboBox *_patternMatchMode;
SliderSpinBox *_brightnessThreshold;
QLabel *_currentBrightness;
QPushButton *_showMatch;
PreviewDialog _previewDialog;
QVBoxLayout *_ocrLayout;
VariableTextEdit *_matchText;
RegexConfigWidget *_regex;
QLabel *_textColor;
QPushButton *_selectColor;
QComboBox *_pageSegMode;
FileSelection *_modelDataPath;
QHBoxLayout *_modelPathLayout;
SliderSpinBox *_objectScaleThreshold;
QHBoxLayout *_neighborsControlLayout;
QSpinBox *_minNeighbors;
QLabel *_minNeighborsDescription;
QHBoxLayout *_sizeLayout;
SizeSelection *_minSize;
SizeSelection *_maxSize;
QHBoxLayout *_checkAreaControlLayout;
QCheckBox *_checkAreaEnable;
AreaSelection *_checkArea;
QPushButton *_selectArea;
BrightnessEdit *_brightness;
OCREdit *_ocr;
ObjectDetectEdit *_objectDetect;
AreaEdit *_area;
QHBoxLayout *_throttleControlLayout;
QCheckBox *_throttleEnable;
QSpinBox *_throttleCount;
QPushButton *_showMatch;
PreviewDialog _previewDialog;
QTimer _updateBrightnessTimer;
std::shared_ptr<MacroConditionVideo> _entryData;
bool _loading = true;
};

View File

@ -2,7 +2,7 @@
namespace advss {
PatternImageData createPatternData(QImage &pattern)
PatternImageData CreatePatternData(QImage &pattern)
{
PatternImageData data{};
if (pattern.isNull()) {
@ -30,7 +30,7 @@ static void invertPatternMatchResult(cv::Mat &mat)
}
}
void matchPattern(QImage &img, const PatternImageData &patternData,
void MatchPattern(QImage &img, const PatternImageData &patternData,
double threshold, cv::Mat &result, bool useAlphaAsMask,
cv::TemplateMatchModes matchMode)
{
@ -74,17 +74,18 @@ void matchPattern(QImage &img, const PatternImageData &patternData,
cv::threshold(result, result, threshold, 0.0, cv::THRESH_TOZERO);
}
void matchPattern(QImage &img, QImage &pattern, double threshold,
void MatchPattern(QImage &img, QImage &pattern, double threshold,
cv::Mat &result, bool useAlphaAsMask,
cv::TemplateMatchModes matchColor)
{
auto data = createPatternData(pattern);
matchPattern(img, data, threshold, result, useAlphaAsMask, matchColor);
auto data = CreatePatternData(pattern);
MatchPattern(img, data, threshold, result, useAlphaAsMask, matchColor);
}
std::vector<cv::Rect> matchObject(QImage &img, cv::CascadeClassifier &cascade,
std::vector<cv::Rect> MatchObject(QImage &img, cv::CascadeClassifier &cascade,
double scaleFactor, int minNeighbors,
cv::Size minSize, cv::Size maxSize)
const cv::Size &minSize,
const cv::Size &maxSize)
{
if (img.isNull() || cascade.empty()) {
return {};
@ -93,14 +94,14 @@ std::vector<cv::Rect> matchObject(QImage &img, cv::CascadeClassifier &cascade,
auto i = QImageToMat(img);
cv::Mat frameGray;
cv::cvtColor(i, frameGray, cv::COLOR_RGBA2GRAY);
equalizeHist(frameGray, frameGray);
cv::equalizeHist(frameGray, frameGray);
std::vector<cv::Rect> objects;
cascade.detectMultiScale(frameGray, objects, scaleFactor, minNeighbors,
0, minSize, maxSize);
return objects;
}
uchar getAvgBrightness(QImage &img)
uchar GetAvgBrightness(QImage &img)
{
if (img.isNull()) {
return 0;
@ -119,7 +120,7 @@ uchar getAvgBrightness(QImage &img)
return brightnessSum / (hsvImage.rows * hsvImage.cols);
}
cv::Mat preprocessForOCR(const QImage &image, const QColor &color)
cv::Mat PreprocessForOCR(const QImage &image, const QColor &color)
{
auto mat = QImageToMat(image);
@ -150,7 +151,7 @@ cv::Mat preprocessForOCR(const QImage &image, const QColor &color)
return mat;
}
std::string runOCR(tesseract::TessBaseAPI *ocr, const QImage &image,
std::string RunOCR(tesseract::TessBaseAPI *ocr, const QImage &image,
const QColor &color)
{
if (image.isNull()) {
@ -158,7 +159,7 @@ std::string runOCR(tesseract::TessBaseAPI *ocr, const QImage &image,
}
#ifdef OCR_SUPPORT
auto mat = preprocessForOCR(image, color);
auto mat = PreprocessForOCR(image, color);
ocr->SetImage(mat.data, mat.cols, mat.rows, 1, mat.step);
ocr->Recognize(0);
std::unique_ptr<char[]> detectedText(ocr->GetUTF8Text());

View File

@ -47,19 +47,20 @@ struct PatternImageData {
cv::Mat1b mask;
};
PatternImageData createPatternData(QImage &pattern);
void matchPattern(QImage &img, const PatternImageData &patternData,
PatternImageData CreatePatternData(QImage &pattern);
void MatchPattern(QImage &img, const PatternImageData &patternData,
double threshold, cv::Mat &result, bool useAlphaAsMask,
cv::TemplateMatchModes matchMode);
void matchPattern(QImage &img, QImage &pattern, double threshold,
void MatchPattern(QImage &img, QImage &pattern, double threshold,
cv::Mat &result, bool useAlphaAsMask,
cv::TemplateMatchModes matchMode);
std::vector<cv::Rect> matchObject(QImage &img, cv::CascadeClassifier &cascade,
std::vector<cv::Rect> MatchObject(QImage &img, cv::CascadeClassifier &cascade,
double scaleFactor, int minNeighbors,
cv::Size minSize, cv::Size maxSize);
uchar getAvgBrightness(QImage &img);
cv::Mat preprocessForOCR(const QImage &image, const QColor &color);
std::string runOCR(tesseract::TessBaseAPI *, const QImage &, const QColor &);
const cv::Size &minSize,
const cv::Size &maxSize);
uchar GetAvgBrightness(QImage &img);
cv::Mat PreprocessForOCR(const QImage &image, const QColor &color);
std::string RunOCR(tesseract::TessBaseAPI *, const QImage &, const QColor &);
cv::Mat QImageToMat(const QImage &img);
QImage MatToQImage(const cv::Mat &mat);

View File

@ -106,7 +106,7 @@ bool ObjDetectParameters::Load(obs_data_t *obj)
return true;
}
bool AreaParamters::Save(obs_data_t *obj) const
bool AreaParameters::Save(obs_data_t *obj) const
{
auto data = obs_data_create();
obs_data_set_bool(data, "enabled", enable);
@ -116,7 +116,7 @@ bool AreaParamters::Save(obs_data_t *obj) const
return true;
}
bool AreaParamters::Load(obs_data_t *obj)
bool AreaParameters::Load(obs_data_t *obj)
{
// TODO: Remove this fallback in a future version
if (!obs_data_has_user_value(obj, "areaData")) {

View File

@ -104,7 +104,7 @@ private:
bool initDone = false;
};
class AreaParamters {
class AreaParameters {
public:
bool Save(obs_data_t *obj) const;
bool Load(obs_data_t *obj);

View File

@ -117,21 +117,21 @@ void PreviewDialog::closeEvent(QCloseEvent *event)
Stop();
}
void PreviewDialog::PatternMatchParamtersChanged(
void PreviewDialog::PatternMatchParametersChanged(
const PatternMatchParameters &params)
{
std::unique_lock<std::mutex> lock(_mtx);
_patternMatchParams = params;
_patternImageData = createPatternData(_patternMatchParams.image);
_patternImageData = CreatePatternData(_patternMatchParams.image);
}
void PreviewDialog::ObjDetectParamtersChanged(const ObjDetectParameters &params)
void PreviewDialog::ObjDetectParametersChanged(const ObjDetectParameters &params)
{
std::unique_lock<std::mutex> lock(_mtx);
_objDetectParams = params;
}
void PreviewDialog::OCRParamtersChanged(const OCRParameters &params)
void PreviewDialog::OCRParametersChanged(const OCRParameters &params)
{
std::unique_lock<std::mutex> lock(_mtx);
_ocrParams = params;
@ -143,7 +143,7 @@ void PreviewDialog::VideoSelectionChanged(const VideoInput &video)
_video = video;
}
void PreviewDialog::AreaParamtersChanged(const AreaParamters &params)
void PreviewDialog::AreaParametersChanged(const AreaParameters &params)
{
std::unique_lock<std::mutex> lock(_mtx);
_areaParams = params;
@ -249,7 +249,7 @@ void PreviewImage::CreateImage(const VideoInput &video, PreviewType type,
const PatternImageData &patternImageData,
ObjDetectParameters objDetectParams,
OCRParameters ocrParams,
const AreaParamters &areaParams,
const AreaParameters &areaParams,
VideoCondition condition)
{
auto source = obs_weak_source_get_source(video.GetVideo());
@ -295,7 +295,7 @@ void PreviewImage::MarkMatch(QImage &screenshot,
{
if (condition == VideoCondition::PATTERN) {
cv::Mat result;
matchPattern(screenshot, patternImageData,
MatchPattern(screenshot, patternImageData,
patternMatchParams.threshold, result,
patternMatchParams.useAlphaAsMask,
patternMatchParams.matchMode);
@ -309,7 +309,7 @@ void PreviewImage::MarkMatch(QImage &screenshot,
patternImageData.rgbaPattern);
}
} else if (condition == VideoCondition::OBJECT) {
auto objects = matchObject(screenshot, objDetectParams.cascade,
auto objects = MatchObject(screenshot, objDetectParams.cascade,
objDetectParams.scaleFactor,
objDetectParams.minNeighbors,
objDetectParams.minSize.CV(),
@ -324,7 +324,7 @@ void PreviewImage::MarkMatch(QImage &screenshot,
}
} else if (condition == VideoCondition::OCR) {
auto text =
runOCR(ocrParams.GetOCR(), screenshot, ocrParams.color);
RunOCR(ocrParams.GetOCR(), screenshot, ocrParams.color);
QString status(obs_module_text(
"AdvSceneSwitcher.condition.video.ocrMatchSuccess"));
emit StatusUpdate(status.arg(QString::fromStdString(text)));

View File

@ -24,7 +24,7 @@ public slots:
void CreateImage(const VideoInput &, PreviewType,
const PatternMatchParameters &,
const PatternImageData &, ObjDetectParameters,
OCRParameters, const AreaParamters &, VideoCondition);
OCRParameters, const AreaParameters &, VideoCondition);
signals:
void ImageReady(const QPixmap &);
void StatusUpdate(const QString &);
@ -47,11 +47,11 @@ public:
void closeEvent(QCloseEvent *event) override;
public slots:
void PatternMatchParamtersChanged(const PatternMatchParameters &);
void ObjDetectParamtersChanged(const ObjDetectParameters &);
void OCRParamtersChanged(const OCRParameters &);
void PatternMatchParametersChanged(const PatternMatchParameters &);
void ObjDetectParametersChanged(const ObjDetectParameters &);
void OCRParametersChanged(const OCRParameters &);
void VideoSelectionChanged(const VideoInput &);
void AreaParamtersChanged(const AreaParamters &);
void AreaParametersChanged(const AreaParameters &);
void ConditionChanged(int cond);
private slots:
void UpdateImage(const QPixmap &);
@ -61,7 +61,7 @@ signals:
void NeedImage(const VideoInput &, PreviewType,
const PatternMatchParameters &, const PatternImageData &,
ObjDetectParameters, OCRParameters,
const AreaParamters &, VideoCondition);
const AreaParameters &, VideoCondition);
private:
void Start();
@ -76,7 +76,7 @@ private:
PatternImageData _patternImageData;
ObjDetectParameters _objDetectParams;
OCRParameters _ocrParams;
AreaParamters _areaParams;
AreaParameters _areaParams;
VideoCondition _condition = VideoCondition::PATTERN;
QScrollArea *_scrollArea;