mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-10-17 22:18:49 -05:00
Fix video condition not supporting variables properly
This commit is contained in:
@@ -133,7 +133,7 @@ bool MacroConditionVideo::Save(obs_data_t *obj) const
|
||||
_video.Save(obj);
|
||||
obs_data_set_bool(obj, "keepActive", _keepActive);
|
||||
obs_data_set_int(obj, "condition", static_cast<int>(_condition));
|
||||
obs_data_set_string(obj, "filePath", _file.c_str());
|
||||
_file.Save(obj, "filePath");
|
||||
obs_data_set_bool(obj, "blockUntilScreenshotDone",
|
||||
_blockUntilScreenshotDone);
|
||||
_brightnessThreshold.Save(obj, "brightnessThreshold");
|
||||
@@ -154,7 +154,7 @@ bool MacroConditionVideo::Load(obs_data_t *obj)
|
||||
_keepActive = obs_data_get_bool(obj, "keepActive");
|
||||
SetCondition(static_cast<VideoCondition>(
|
||||
obs_data_get_int(obj, "condition")));
|
||||
_file = obs_data_get_string(obj, "filePath");
|
||||
_file.Load(obj, "filePath");
|
||||
_blockUntilScreenshotDone =
|
||||
obs_data_get_bool(obj, "blockUntilScreenshotDone");
|
||||
// TODO: Remove this fallback in a future version
|
||||
@@ -202,12 +202,13 @@ void MacroConditionVideo::GetScreenshot(bool blocking)
|
||||
|
||||
bool MacroConditionVideo::LoadImageFromFile()
|
||||
{
|
||||
const QFileInfo info(QString::fromStdString(_file));
|
||||
const std::string file = _file;
|
||||
const QFileInfo info(QString::fromStdString(file));
|
||||
_loadedFileLastModified = info.lastModified();
|
||||
_loadedFile = _file;
|
||||
_loadedFile = file;
|
||||
if (!_matchImage.load(info.absoluteFilePath())) {
|
||||
blog(LOG_WARNING, "Cannot load image data from file '%s'",
|
||||
_file.c_str());
|
||||
file.c_str());
|
||||
(&_matchImage)->~QImage();
|
||||
new (&_matchImage) QImage();
|
||||
_patternImageData = {};
|
||||
@@ -304,9 +305,10 @@ bool MacroConditionVideo::FileInputIsUpToDate() const
|
||||
if (!requiresFileInput(_condition)) {
|
||||
return true;
|
||||
}
|
||||
const QFileInfo info(QString::fromStdString(_file));
|
||||
const std::string file = _file;
|
||||
const QFileInfo info(QString::fromStdString(file));
|
||||
return (_loadedFileLastModified == info.lastModified()) &&
|
||||
(_file == _loadedFile);
|
||||
(file == _loadedFile);
|
||||
}
|
||||
|
||||
bool MacroConditionVideo::OutputChanged()
|
||||
@@ -1099,7 +1101,7 @@ void MacroConditionVideoEdit::UpdateEntryData()
|
||||
_condition->setCurrentIndex(_condition->findData(
|
||||
static_cast<int>(_entryData->GetCondition())));
|
||||
_reduceLatency->setChecked(_entryData->_blockUntilScreenshotDone);
|
||||
_imagePath->SetPath(QString::fromStdString(_entryData->_file));
|
||||
_imagePath->SetPath(_entryData->_file);
|
||||
_usePatternForChangedCheck->setChecked(
|
||||
_entryData->_patternMatchParameters.useForChangedCheck);
|
||||
_patternThreshold->SetDoubleValue(
|
||||
|
||||
@@ -60,7 +60,7 @@ public:
|
||||
|
||||
VideoInput _video;
|
||||
bool _keepActive = false;
|
||||
std::string _file = obs_module_text("AdvSceneSwitcher.enterPath");
|
||||
StringVariable _file = obs_module_text("AdvSceneSwitcher.enterPath");
|
||||
// Enabling this will reduce matching latency, but slow down the
|
||||
// the condition checks of all macros overall.
|
||||
//
|
||||
|
||||
@@ -62,13 +62,14 @@ static bool isMinNeighborsValid(int minNeighbors)
|
||||
|
||||
bool CascadeClassifierParameters::LoadModelData()
|
||||
{
|
||||
const auto path = QString::fromStdString(_modelPath);
|
||||
_loadedModelPath = _modelPath;
|
||||
const auto path = QString::fromStdString(_loadedModelPath);
|
||||
if (!QFileInfo(path).exists(path)) {
|
||||
_detector.reset();
|
||||
return false;
|
||||
}
|
||||
auto det = std::make_unique<CascadeClassifierDetector>();
|
||||
if (!det->Load(_modelPath)) {
|
||||
if (!det->Load(_loadedModelPath)) {
|
||||
_detector.reset();
|
||||
return false;
|
||||
}
|
||||
@@ -79,7 +80,7 @@ bool CascadeClassifierParameters::LoadModelData()
|
||||
bool CascadeClassifierParameters::Save(obs_data_t *obj) const
|
||||
{
|
||||
auto data = obs_data_create();
|
||||
obs_data_set_string(data, "modelPath", _modelPath.c_str());
|
||||
_modelPath.Save(data, "modelPath");
|
||||
scaleFactor.Save(data, "scaleFactor");
|
||||
obs_data_set_int(data, "minNeighbors", minNeighbors);
|
||||
minSize.Save(data, "minSize");
|
||||
@@ -108,7 +109,7 @@ bool CascadeClassifierParameters::Load(obs_data_t *obj)
|
||||
return true;
|
||||
}
|
||||
auto data = obs_data_get_obj(obj, "objectMatchData");
|
||||
_modelPath = obs_data_get_string(data, "modelPath");
|
||||
_modelPath.Load(data, "modelPath");
|
||||
scaleFactor.Load(data, "scaleFactor");
|
||||
// TODO: Remove this fallback in a future version
|
||||
if (!obs_data_has_user_value(data, "version")) {
|
||||
@@ -121,11 +122,12 @@ bool CascadeClassifierParameters::Load(obs_data_t *obj)
|
||||
// which invalidates previously saved default model paths.
|
||||
const std::string oldPrefix =
|
||||
"../../data/obs-plugins/advanced-scene-switcher/res/cascadeClassifiers/";
|
||||
if (_modelPath.substr(0, oldPrefix.size()) == oldPrefix) {
|
||||
const std::string oldPath = _modelPath.UnresolvedValue();
|
||||
if (oldPath.substr(0, oldPrefix.size()) == oldPrefix) {
|
||||
_modelPath = std::string(obs_get_module_data_path(
|
||||
obs_current_module())) +
|
||||
"/res/cascadeClassifiers/" +
|
||||
_modelPath.substr(oldPrefix.size());
|
||||
oldPath.substr(oldPrefix.size());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
@@ -150,7 +152,8 @@ bool CascadeClassifierParameters::SetModelPath(const std::string &path)
|
||||
|
||||
ObjectDetector *CascadeClassifierParameters::GetDetector()
|
||||
{
|
||||
if (!_detector || !_detector->IsLoaded()) {
|
||||
if (!_detector || !_detector->IsLoaded() ||
|
||||
std::string(_modelPath) != _loadedModelPath) {
|
||||
if (!LoadModelData()) {
|
||||
return nullptr;
|
||||
}
|
||||
@@ -316,7 +319,7 @@ bool OCRParameters::Save(obs_data_t *obj) const
|
||||
tesseractBasePath.Save(data, "tesseractBasePath");
|
||||
languageCode.Save(data, "language");
|
||||
obs_data_set_bool(data, "useConfig", useConfig);
|
||||
obs_data_set_string(data, "configFile", configFile.c_str());
|
||||
configFile.Save(data, "configFile");
|
||||
color.Save(data, "textColor");
|
||||
colorThreshold.Save(data, "colorThreshold");
|
||||
obs_data_set_int(data, "pageSegMode", static_cast<int>(pageSegMode));
|
||||
@@ -358,7 +361,7 @@ bool OCRParameters::Load(obs_data_t *obj)
|
||||
#endif
|
||||
}
|
||||
useConfig = obs_data_get_bool(data, "useConfig");
|
||||
configFile = obs_data_get_string(data, "configFile");
|
||||
configFile.Load(data, "configFile");
|
||||
|
||||
color.Load(data, "textColor");
|
||||
if (obs_data_has_user_value(data, "version")) {
|
||||
@@ -382,18 +385,31 @@ void OCRParameters::SetPageMode(tesseract::PageSegMode mode)
|
||||
|
||||
tesseract::TessBaseAPI *OCRParameters::GetOCR()
|
||||
{
|
||||
if (!initDone) {
|
||||
if (!initDone || !SetupIsUpToDate()) {
|
||||
Setup();
|
||||
}
|
||||
return initDone ? ocr.get() : nullptr;
|
||||
}
|
||||
|
||||
static bool containsVariables(const std::string &value)
|
||||
{
|
||||
return std::string(StringVariable(value)) != value;
|
||||
}
|
||||
|
||||
static bool modelFileExists(const std::string &basePath,
|
||||
const std::string &languageCode)
|
||||
{
|
||||
const auto dataPath = QString::fromStdString(basePath) + "/" +
|
||||
QString::fromStdString(languageCode) +
|
||||
".traineddata";
|
||||
return QFileInfo::exists(dataPath);
|
||||
}
|
||||
|
||||
bool OCRParameters::SetLanguageCode(const std::string &value)
|
||||
{
|
||||
const auto dataPath = QString::fromStdString(tesseractBasePath) + "/" +
|
||||
QString::fromStdString(value) + ".traineddata";
|
||||
QFileInfo fileInfo(dataPath);
|
||||
if (!fileInfo.exists(dataPath)) {
|
||||
// Variable values can change later, so only fixed values are validated
|
||||
if (!containsVariables(value) &&
|
||||
!modelFileExists(tesseractBasePath, value)) {
|
||||
return false;
|
||||
}
|
||||
languageCode = value;
|
||||
@@ -401,18 +417,10 @@ bool OCRParameters::SetLanguageCode(const std::string &value)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string OCRParameters::GetLanguageCode() const
|
||||
{
|
||||
return languageCode;
|
||||
}
|
||||
|
||||
bool OCRParameters::SetTesseractBasePath(const std::string &value)
|
||||
{
|
||||
const auto dataPath = QString::fromStdString(value) + "/" +
|
||||
QString::fromStdString(languageCode) +
|
||||
".traineddata";
|
||||
QFileInfo fileInfo(dataPath);
|
||||
if (!fileInfo.exists(dataPath)) {
|
||||
if (!containsVariables(value) &&
|
||||
!modelFileExists(value, languageCode)) {
|
||||
return false;
|
||||
}
|
||||
tesseractBasePath = value;
|
||||
@@ -420,11 +428,6 @@ bool OCRParameters::SetTesseractBasePath(const std::string &value)
|
||||
return true;
|
||||
}
|
||||
|
||||
std::string OCRParameters::GetTesseractBasePath() const
|
||||
{
|
||||
return tesseractBasePath;
|
||||
}
|
||||
|
||||
void OCRParameters::EnableCustomConfig(bool enable)
|
||||
{
|
||||
useConfig = enable;
|
||||
@@ -437,17 +440,27 @@ void OCRParameters::SetCustomConfigFile(const std::string &filename)
|
||||
initDone = false;
|
||||
}
|
||||
|
||||
bool OCRParameters::SetupIsUpToDate() const
|
||||
{
|
||||
return setupBasePath == std::string(tesseractBasePath) &&
|
||||
setupLanguageCode == std::string(languageCode) &&
|
||||
setupConfigFile == std::string(configFile);
|
||||
}
|
||||
|
||||
void OCRParameters::Setup()
|
||||
{
|
||||
setupBasePath = tesseractBasePath;
|
||||
setupLanguageCode = languageCode;
|
||||
setupConfigFile = configFile;
|
||||
|
||||
ocr = std::make_unique<tesseract::TessBaseAPI>();
|
||||
if (!ocr) {
|
||||
initDone = false;
|
||||
return;
|
||||
}
|
||||
|
||||
const std::string dataPath = std::string(tesseractBasePath) + "/";
|
||||
const std::string modelFile =
|
||||
std::string(languageCode) + ".traineddata";
|
||||
const std::string dataPath = setupBasePath + "/";
|
||||
const std::string modelFile = setupLanguageCode + ".traineddata";
|
||||
const auto modelFullPath = QString::fromStdString(dataPath) +
|
||||
QString::fromStdString(modelFile);
|
||||
QFileInfo modelFileInfo(modelFullPath);
|
||||
@@ -459,7 +472,7 @@ void OCRParameters::Setup()
|
||||
return;
|
||||
}
|
||||
|
||||
auto configPath = QString::fromStdString(configFile);
|
||||
auto configPath = QString::fromStdString(setupConfigFile);
|
||||
QFileInfo configFileInfo(configPath);
|
||||
bool configFileExists = configFileInfo.exists(configPath);
|
||||
|
||||
@@ -471,8 +484,8 @@ void OCRParameters::Setup()
|
||||
setupWithConfig = false;
|
||||
}
|
||||
|
||||
char *configs[] = {configFile.data()};
|
||||
if (ocr->Init(dataPath.c_str(), languageCode.c_str(),
|
||||
char *configs[] = {setupConfigFile.data()};
|
||||
if (ocr->Init(dataPath.c_str(), setupLanguageCode.c_str(),
|
||||
tesseract::OEM_DEFAULT,
|
||||
setupWithConfig ? configs : nullptr,
|
||||
setupWithConfig ? 1 : 0, nullptr, nullptr, false) != 0) {
|
||||
|
||||
@@ -94,7 +94,7 @@ public:
|
||||
}
|
||||
|
||||
bool SetModelPath(const std::string &path);
|
||||
const std::string &GetModelPath() const { return _modelPath; }
|
||||
const StringVariable &GetModelPath() const { return _modelPath; }
|
||||
ObjectDetector *GetDetector();
|
||||
|
||||
NumberVariable<double> scaleFactor = defaultScaleFactor;
|
||||
@@ -106,10 +106,11 @@ private:
|
||||
bool LoadModelData();
|
||||
|
||||
std::unique_ptr<ObjectDetector> _detector;
|
||||
std::string _modelPath =
|
||||
StringVariable _modelPath =
|
||||
obs_get_module_data_path(obs_current_module()) +
|
||||
std::string(
|
||||
"/res/cascadeClassifiers/haarcascade_frontalface_alt.xml");
|
||||
std::string _loadedModelPath;
|
||||
};
|
||||
|
||||
class OCRParameters {
|
||||
@@ -125,13 +126,16 @@ public:
|
||||
bool Initialized() const { return initDone; }
|
||||
void SetPageMode(tesseract::PageSegMode);
|
||||
bool SetLanguageCode(const std::string &);
|
||||
std::string GetLanguageCode() const;
|
||||
const StringVariable &GetLanguageCode() const { return languageCode; }
|
||||
bool SetTesseractBasePath(const std::string &);
|
||||
std::string GetTesseractBasePath() const;
|
||||
const StringVariable &GetTesseractBasePath() const
|
||||
{
|
||||
return tesseractBasePath;
|
||||
}
|
||||
void EnableCustomConfig(bool enable);
|
||||
bool CustomConfigIsEnabled() const { return useConfig; }
|
||||
void SetCustomConfigFile(const std::string &);
|
||||
std::string GetCustomConfigFile() const { return configFile; }
|
||||
const StringVariable &GetCustomConfigFile() const { return configFile; }
|
||||
tesseract::PageSegMode GetPageMode() const { return pageSegMode; }
|
||||
tesseract::TessBaseAPI *GetOCR();
|
||||
|
||||
@@ -142,6 +146,7 @@ public:
|
||||
|
||||
private:
|
||||
void Setup();
|
||||
bool SetupIsUpToDate() const;
|
||||
|
||||
tesseract::PageSegMode pageSegMode = tesseract::PSM_SINGLE_BLOCK;
|
||||
StringVariable tesseractBasePath =
|
||||
@@ -149,9 +154,12 @@ private:
|
||||
std::string("/res/ocr");
|
||||
StringVariable languageCode = "eng";
|
||||
bool useConfig = false;
|
||||
std::string configFile = "config.txt";
|
||||
StringVariable configFile = "config.txt";
|
||||
std::unique_ptr<tesseract::TessBaseAPI> ocr;
|
||||
bool initDone = false;
|
||||
std::string setupBasePath;
|
||||
std::string setupLanguageCode;
|
||||
std::string setupConfigFile;
|
||||
};
|
||||
|
||||
class ColorParameters {
|
||||
|
||||
Reference in New Issue
Block a user