mirror of
https://github.com/WarmUpTill/SceneSwitcher.git
synced 2026-03-21 17:34:57 -05:00
Add tesseract config file support
This commit is contained in:
parent
5490fabf92
commit
0e5f56b562
|
|
@ -194,12 +194,12 @@ AdvSceneSwitcher.condition.video.modelLoadFail="Modelldaten konnten nicht gelade
|
|||
AdvSceneSwitcher.condition.video.type.main="OBS's Haupt-Ausgabe"
|
||||
AdvSceneSwitcher.condition.video.type.source="Quelle"
|
||||
AdvSceneSwitcher.condition.video.type.scene="Szene"
|
||||
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="Modelldaten (Haar-Kaskaden-Klassifikator): {{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="Minimale Anzahl von Nachbarn: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Reduzieren Sie die CPU-Belastung, indem Sie die Prüfung nur alle {{throttleCount}} Millisekunden"
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="Kontrolle nur im Bereich durchführen"
|
||||
AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.layout="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="Modelldaten (Haar-Kaskaden-Klassifikator): {{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="Minimale Anzahl von Nachbarn: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}Reduzieren Sie die CPU-Belastung, indem Sie die Prüfung nur alle {{throttleCount}} Millisekunden"
|
||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="Kontrolle nur im Bereich durchführen"
|
||||
AdvSceneSwitcher.condition.video.layout.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="Minimale Größe:"
|
||||
AdvSceneSwitcher.condition.video.maxSize="Maximale Größe:"
|
||||
AdvSceneSwitcher.condition.video.selectArea="Bereich auswählen"
|
||||
|
|
|
|||
|
|
@ -392,6 +392,13 @@ AdvSceneSwitcher.condition.video.patternMatchSuccessFullImage="Full image matche
|
|||
AdvSceneSwitcher.condition.video.objectMatchFail="Object was not found!"
|
||||
AdvSceneSwitcher.condition.video.objectMatchSuccess="Object is highlighted in red"
|
||||
AdvSceneSwitcher.condition.video.ocrMatchSuccess="Detected text:\n\n%1"
|
||||
AdvSceneSwitcher.condition.video.ocrMatchFail="Could not detect any text!"
|
||||
AdvSceneSwitcher.condition.video.ocrUseConfigFile="Use custom tesseract config file"
|
||||
AdvSceneSwitcher.condition.video.ocrOpenConfigFile="Open"
|
||||
AdvSceneSwitcher.condition.video.ocrOpenConfig.createFailed="Could not create the config file!"
|
||||
AdvSceneSwitcher.condition.video.ocrOpenConfig.openFailed="Could not open the config file!"
|
||||
AdvSceneSwitcher.condition.video.ocrConfigReload="Reload configuration file"
|
||||
AdvSceneSwitcher.condition.video.ocrConfigHint="Tesseract config files consist of lines with parameter-value pairs (space separated).\nFor example:\n\ntessedit_char_blacklist\t\t\t\t\"abc\"\nlanguage_model_penalty_non_dict_word\t0"
|
||||
AdvSceneSwitcher.condition.video.modelLoadFail="Model data could not be loaded!"
|
||||
AdvSceneSwitcher.condition.video.selectColor="Select Color"
|
||||
AdvSceneSwitcher.condition.video.ocrMode.singleColumn="Single column of text of variable sizes"
|
||||
|
|
@ -411,17 +418,18 @@ AdvSceneSwitcher.condition.video.colorDeviationThresholdDescription="How similar
|
|||
AdvSceneSwitcher.condition.video.type.main="OBS's main output"
|
||||
AdvSceneSwitcher.condition.video.type.source="Source"
|
||||
AdvSceneSwitcher.condition.video.type.scene="Scene"
|
||||
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="Model data (haar cascade classifier):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="Minimum neighbors:{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Reduce CPU load by performing check only every{{throttleCount}}milliseconds"
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="Perform check only in area"
|
||||
AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcColorPick="Check for text color:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcTextType="Check for text type:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcBaseDir="Tesseract base directory:{{tesseractBaseDir}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcLanguage="Check for language:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.entry.color="Check for color:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="Model data (haar cascade classifier):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="Minimum neighbors:{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}Reduce CPU load by performing check only every{{throttleCount}}milliseconds"
|
||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="Perform check only in area"
|
||||
AdvSceneSwitcher.condition.video.layout.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrColorPick="Check for text color:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrTextType="Check for text type:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrBaseDir="Tesseract base directory:{{tesseractBaseDir}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrLanguage="Check for language:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrConfig="Config file:{{configFile}}{{openConfigFile}}{{reloadConfig}}{{configFileHint}}"
|
||||
AdvSceneSwitcher.condition.video.layout.color="Check for color:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="Minimum size:"
|
||||
AdvSceneSwitcher.condition.video.maxSize="Maximum size:"
|
||||
AdvSceneSwitcher.condition.video.selectArea="Select area"
|
||||
|
|
|
|||
|
|
@ -154,12 +154,12 @@ AdvSceneSwitcher.condition.video.patternMatchSuccess="El patrón está resaltado
|
|||
AdvSceneSwitcher.condition.video.objectMatchFail="¡No se encontró el objeto!"
|
||||
AdvSceneSwitcher.condition.video.objectMatchSuccess="El objeto está resaltado en rojo"
|
||||
AdvSceneSwitcher.condition.video.modelLoadFail="¡No se pudieron cargar los datos del modelo!"
|
||||
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="Datos del modelo (haar cascade classifier): {{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="Mínimo de vecinos: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Reduzca la carga de la CPU realizando una comprobación solo cada {{throttleCount}} milisegundos"
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="Realizar comprobación solo en el área"
|
||||
AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}Realizar comprobación solo en el área {{checkArea}} {{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.layout="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="Datos del modelo (haar cascade classifier): {{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="Mínimo de vecinos: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}Reduzca la carga de la CPU realizando una comprobación solo cada {{throttleCount}} milisegundos"
|
||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="Realizar comprobación solo en el área"
|
||||
AdvSceneSwitcher.condition.video.layout.checkArea="{{checkAreaEnable}}Realizar comprobación solo en el área {{checkArea}} {{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="Tamaño mínimo:"
|
||||
AdvSceneSwitcher.condition.video.maxSize="Tamaño máximo:"
|
||||
AdvSceneSwitcher.condition.video.selectArea="Seleccionar área"
|
||||
|
|
|
|||
|
|
@ -257,14 +257,14 @@ AdvSceneSwitcher.condition.video.colorDeviationThresholdDescription="À quel poi
|
|||
AdvSceneSwitcher.condition.video.type.main="Sortie principale d'OBS"
|
||||
AdvSceneSwitcher.condition.video.type.source="Source"
|
||||
AdvSceneSwitcher.condition.video.type.scene="Scène"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="Données du modèle (classificateur de cascade de Haar) :{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="Nombre minimum de voisins :{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Réduire la charge CPU en effectuant la vérification uniquement toutes les{{throttleCount}}millisecondes"
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="Effectuer la vérification uniquement dans la zone"
|
||||
AdvSceneSwitcher.condition.video.entry.orcColorPick="Vérifier la couleur du texte :{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcTextType="Vérifier le type de texte :{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcLanguage="Vérifier la langue :{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.entry.color="Vérifier la couleur :{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="Données du modèle (classificateur de cascade de Haar) :{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="Nombre minimum de voisins :{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}Réduire la charge CPU en effectuant la vérification uniquement toutes les{{throttleCount}}millisecondes"
|
||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="Effectuer la vérification uniquement dans la zone"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrColorPick="Vérifier la couleur du texte :{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrTextType="Vérifier le type de texte :{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrLanguage="Vérifier la langue :{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.layout.color="Vérifier la couleur :{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="Taille minimale :"
|
||||
AdvSceneSwitcher.condition.video.maxSize="Taille maximale :"
|
||||
AdvSceneSwitcher.condition.video.selectArea="Sélectionner la zone"
|
||||
|
|
|
|||
|
|
@ -379,16 +379,14 @@ AdvSceneSwitcher.condition.video.colorDeviationThresholdDescription="一致と
|
|||
AdvSceneSwitcher.condition.video.type.main="OBS's main output"
|
||||
AdvSceneSwitcher.condition.video.type.source="ソース"
|
||||
AdvSceneSwitcher.condition.video.type.scene="シーン"
|
||||
; AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="モデルデータ (そのカスケード分類子):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="最小近傍数:{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}:{{throttleCount}}ミリ秒ごとにのみチェックを実行することでCPU負荷を軽減します"
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="エリア内のみチェックを実施"
|
||||
; AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcColorPick="テキストの色の確認:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcTextType="テキストタイプの確認:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcLanguage="言語の確認:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.entry.color="カラーを確認してください:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="モデルデータ (そのカスケード分類子):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="最小近傍数:{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}:{{throttleCount}}ミリ秒ごとにのみチェックを実行することでCPU負荷を軽減します"
|
||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="エリア内のみチェックを実施"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrColorPick="テキストの色の確認:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrTextType="テキストタイプの確認:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrLanguage="言語の確認:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.layout.color="カラーを確認してください:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="最小サイズ:"
|
||||
AdvSceneSwitcher.condition.video.maxSize="最大サイズ:"
|
||||
AdvSceneSwitcher.condition.video.selectArea="範囲指定"
|
||||
|
|
|
|||
|
|
@ -372,16 +372,16 @@ AdvSceneSwitcher.condition.video.colorDeviationThresholdDescription="Quão semel
|
|||
AdvSceneSwitcher.condition.video.type.main="Saída principal do OBS"
|
||||
AdvSceneSwitcher.condition.video.type.source="Fonte"
|
||||
AdvSceneSwitcher.condition.video.type.scene="Cena"
|
||||
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="Dados do modelo (classificador em cascata haar):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="Vizinhos mínimos:{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}Reduzir carga de CPU realizando a verificação apenas a cada {{throttleCount}} milissegundos"
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="Realizar verificação apenas na área"
|
||||
AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcColorPick="Verificar cor do texto:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcTextType="Verificar tipo de texto:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcLanguage="Verificar idioma:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.entry.color="Verificar cor:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="Dados do modelo (classificador em cascata haar):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="Vizinhos mínimos:{{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}Reduzir carga de CPU realizando a verificação apenas a cada {{throttleCount}} milissegundos"
|
||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="Realizar verificação apenas na área"
|
||||
AdvSceneSwitcher.condition.video.layout.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrColorPick="Verificar cor do texto:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrTextType="Verificar tipo de texto:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrLanguage="Verificar idioma:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.layout.color="Verificar cor:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="Tamanho mínimo:"
|
||||
AdvSceneSwitcher.condition.video.maxSize="Tamanho máximo:"
|
||||
AdvSceneSwitcher.condition.video.selectArea="Selecionar área"
|
||||
|
|
|
|||
|
|
@ -139,10 +139,10 @@ AdvSceneSwitcher.condition.video.screenshotFail="Kaynağın ekran görüntüsü
|
|||
AdvSceneSwitcher.condition.video.patternMatchFail="Desen bulunamadı!"
|
||||
AdvSceneSwitcher.condition.video.objectMatchFail="Nesne bulunamadı!"
|
||||
AdvSceneSwitcher.condition.video.modelLoadFail="Model verileri yüklenemedi!"
|
||||
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="Model verileri (haar kademeli sınıflandırıcı):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="Minimum komşular: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}} Yalnızca her seferinde kontrol gerçekleştirerek CPU yükünü azaltın {{throttleCount}} millisaniyeler"
|
||||
AdvSceneSwitcher.condition.video.layout="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="Model verileri (haar kademeli sınıflandırıcı):{{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="Minimum komşular: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}} Yalnızca her seferinde kontrol gerçekleştirerek CPU yükünü azaltın {{throttleCount}} millisaniyeler"
|
||||
AdvSceneSwitcher.condition.stream="Yayınlama"
|
||||
AdvSceneSwitcher.condition.stream.state.start="Yayın çalışıyor"
|
||||
AdvSceneSwitcher.condition.stream.state.stop="Yayın durdu"
|
||||
|
|
|
|||
|
|
@ -395,16 +395,16 @@ AdvSceneSwitcher.condition.video.colorDeviationThresholdDescription="颜色与
|
|||
AdvSceneSwitcher.condition.video.type.main="OBS的主输出"
|
||||
AdvSceneSwitcher.condition.video.type.source="源"
|
||||
AdvSceneSwitcher.condition.video.type.scene="场景"
|
||||
AdvSceneSwitcher.condition.video.entry="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.modelPath="模型数据 (haar级联分类器): {{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.entry.minNeighbor="最小区域: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.entry.throttle="{{throttleEnable}}每隔{{throttleCount}} 毫秒,才执行一次检查,从而减少 CPU 负载."
|
||||
AdvSceneSwitcher.condition.video.entry.checkAreaEnable="仅在区域内执行检查"
|
||||
AdvSceneSwitcher.condition.video.entry.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcColorPick="文本检查颜色:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcTextType="文本检查类型:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.entry.orcLanguage="语言检查:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.entry.color="颜色检查:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout="{{videoInputTypes}}{{sources}}{{scenes}}{{condition}}{{imagePath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.modelPath="模型数据 (haar级联分类器): {{modelDataPath}}"
|
||||
AdvSceneSwitcher.condition.video.layout.minNeighbor="最小区域: {{minNeighbors}}"
|
||||
AdvSceneSwitcher.condition.video.layout.throttle="{{throttleEnable}}每隔{{throttleCount}} 毫秒,才执行一次检查,从而减少 CPU 负载."
|
||||
AdvSceneSwitcher.condition.video.layout.checkAreaEnable="仅在区域内执行检查"
|
||||
AdvSceneSwitcher.condition.video.layout.checkArea="{{checkAreaEnable}}{{checkArea}}{{selectArea}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrColorPick="文本检查颜色:{{textColor}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrTextType="文本检查类型:{{textType}}"
|
||||
AdvSceneSwitcher.condition.video.layout.ocrLanguage="语言检查:{{languageCode}}"
|
||||
AdvSceneSwitcher.condition.video.layout.color="颜色检查:{{color}}{{selectColor}}"
|
||||
AdvSceneSwitcher.condition.video.minSize="最小尺寸:"
|
||||
AdvSceneSwitcher.condition.video.maxSize="最大尺寸:"
|
||||
AdvSceneSwitcher.condition.video.selectArea="选择区域"
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include <plugin-state-helpers.hpp>
|
||||
#include <QBuffer>
|
||||
#include <QColorDialog>
|
||||
#include <QDesktopServices>
|
||||
#include <QFileDialog>
|
||||
#include <QMessageBox>
|
||||
#include <QtGlobal>
|
||||
|
|
@ -370,12 +371,16 @@ bool MacroConditionVideo::CheckOCR()
|
|||
|
||||
auto text = RunOCR(_ocrParameters.GetOCR(), _screenshotData.GetImage(),
|
||||
_ocrParameters.color, _ocrParameters.colorThreshold);
|
||||
SetVariableValue(text);
|
||||
SetTempVarValue("text", text);
|
||||
if (!text) {
|
||||
return false;
|
||||
}
|
||||
|
||||
SetVariableValue(*text);
|
||||
SetTempVarValue("text", *text);
|
||||
if (!_ocrParameters.regex.Enabled()) {
|
||||
return text == std::string(_ocrParameters.text);
|
||||
}
|
||||
return _ocrParameters.regex.Matches(text, _ocrParameters.text);
|
||||
return _ocrParameters.regex.Matches(*text, _ocrParameters.text);
|
||||
}
|
||||
|
||||
bool MacroConditionVideo::CheckColor()
|
||||
|
|
@ -520,7 +525,7 @@ BrightnessEdit::BrightnessEdit(QWidget *parent,
|
|||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.brightnessThresholdDescription"))),
|
||||
_current(new QLabel),
|
||||
_data(data)
|
||||
_entryData(data)
|
||||
{
|
||||
auto layout = new QVBoxLayout;
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
|
@ -538,7 +543,7 @@ BrightnessEdit::BrightnessEdit(QWidget *parent,
|
|||
&BrightnessEdit::UpdateCurrentBrightness);
|
||||
_timer.start(1000);
|
||||
|
||||
_threshold->SetDoubleValue(_data->_brightnessThreshold);
|
||||
_threshold->SetDoubleValue(_entryData->_brightnessThreshold);
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
|
|
@ -546,17 +551,34 @@ void BrightnessEdit::UpdateCurrentBrightness()
|
|||
{
|
||||
QString text = obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.currentBrightness");
|
||||
_current->setText(text.arg(_data->GetCurrentBrightness()));
|
||||
_current->setText(text.arg(_entryData->GetCurrentBrightness()));
|
||||
}
|
||||
|
||||
void BrightnessEdit::BrightnessThresholdChanged(const DoubleVariable &value)
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
return;
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_brightnessThreshold = value;
|
||||
}
|
||||
|
||||
static void openFileInEditor(const std::string &filepath)
|
||||
{
|
||||
const auto path = QString::fromStdString(filepath);
|
||||
const QFileInfo fileInfo(path);
|
||||
if (!fileInfo.exists()) {
|
||||
QFile file(path);
|
||||
if (!file.open(QIODevice::WriteOnly)) {
|
||||
DisplayMessage(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.ocrOpenConfig.createFailed"));
|
||||
return;
|
||||
}
|
||||
file.close();
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_data->_brightnessThreshold = value;
|
||||
QUrl fileUrl = QUrl::fromLocalFile(path);
|
||||
if (!QDesktopServices::openUrl(fileUrl)) {
|
||||
DisplayMessage(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.ocrOpenConfig.openFailed"));
|
||||
}
|
||||
}
|
||||
|
||||
OCREdit::OCREdit(QWidget *parent, PreviewDialog *previewDialog,
|
||||
|
|
@ -577,11 +599,25 @@ OCREdit::OCREdit(QWidget *parent, PreviewDialog *previewDialog,
|
|||
_pageSegMode(new QComboBox()),
|
||||
_tesseractBaseDir(new FileSelection(FileSelection::Type::FOLDER)),
|
||||
_languageCode(new VariableLineEdit(this)),
|
||||
_useConfig(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.ocrUseConfigFile"))),
|
||||
_configFile(new FileSelection(FileSelection::Type::WRITE, this)),
|
||||
_openConfigFile(new QPushButton(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.ocrOpenConfigFile"))),
|
||||
_reloadConfig(new QPushButton()),
|
||||
_configLayout(new QHBoxLayout()),
|
||||
_previewDialog(previewDialog),
|
||||
_data(data)
|
||||
_entryData(data)
|
||||
{
|
||||
populatePageSegModeSelection(_pageSegMode);
|
||||
|
||||
_reloadConfig->setMaximumWidth(22);
|
||||
SetButtonIcon(_reloadConfig, GetThemeTypeName() == "Light"
|
||||
? ":res/images/refresh.svg"
|
||||
: "theme:Dark/refresh.svg");
|
||||
_reloadConfig->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.ocrConfigReload"));
|
||||
|
||||
QWidget::connect(_selectColor, SIGNAL(clicked()), this,
|
||||
SLOT(SelectColorClicked()));
|
||||
QWidget::connect(
|
||||
|
|
@ -601,6 +637,29 @@ OCREdit::OCREdit(QWidget *parent, PreviewDialog *previewDialog,
|
|||
SLOT(TesseractBaseDirChanged(const QString &)));
|
||||
QWidget::connect(_languageCode, SIGNAL(editingFinished()), this,
|
||||
SLOT(LanguageChanged()));
|
||||
QWidget::connect(_useConfig, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(UseConfigChanged(int)));
|
||||
QWidget::connect(_configFile, SIGNAL(PathChanged(const QString &)),
|
||||
this, SLOT(ConfigFileChanged(const QString &)));
|
||||
QWidget::connect(_openConfigFile, &QPushButton::clicked, [this](bool) {
|
||||
openFileInEditor(
|
||||
_entryData->_ocrParameters.GetCustomConfigFile());
|
||||
});
|
||||
QWidget::connect(_reloadConfig, &QPushButton::clicked, [this](bool) {
|
||||
_entryData->_ocrParameters.EnableCustomConfig(true);
|
||||
_previewDialog->OCRParametersChanged(
|
||||
_entryData->_ocrParameters);
|
||||
});
|
||||
|
||||
auto configFileHint = new QLabel();
|
||||
const QString path = GetThemeTypeName() == "Light"
|
||||
? ":/res/images/help.svg"
|
||||
: ":/res/images/help_light.svg";
|
||||
const QIcon icon(path);
|
||||
const QPixmap pixmap = icon.pixmap(QSize(16, 16));
|
||||
configFileHint->setPixmap(pixmap);
|
||||
configFileHint->setToolTip(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.ocrConfigHint"));
|
||||
|
||||
const std::unordered_map<std::string, QWidget *> widgetPlaceholders = {
|
||||
{"{{textColor}}", _textColor},
|
||||
|
|
@ -608,6 +667,10 @@ OCREdit::OCREdit(QWidget *parent, PreviewDialog *previewDialog,
|
|||
{"{{textType}}", _pageSegMode},
|
||||
{"{{tesseractBaseDir}}", _tesseractBaseDir},
|
||||
{"{{languageCode}}", _languageCode},
|
||||
{"{{configFile}}", _configFile},
|
||||
{"{{openConfigFile}}", _openConfigFile},
|
||||
{"{{reloadConfig}}", _reloadConfig},
|
||||
{"{{configFileHint}}", configFileHint},
|
||||
};
|
||||
|
||||
auto layout = new QVBoxLayout();
|
||||
|
|
@ -620,39 +683,51 @@ OCREdit::OCREdit(QWidget *parent, PreviewDialog *previewDialog,
|
|||
auto pageModeSegLayout = new QHBoxLayout();
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.entry.orcTextType"),
|
||||
"AdvSceneSwitcher.condition.video.layout.ocrTextType"),
|
||||
pageModeSegLayout, widgetPlaceholders);
|
||||
layout->addLayout(pageModeSegLayout);
|
||||
auto baseDirLayout = new QHBoxLayout();
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.entry.orcBaseDir"),
|
||||
"AdvSceneSwitcher.condition.video.layout.ocrBaseDir"),
|
||||
baseDirLayout, widgetPlaceholders, false);
|
||||
layout->addLayout(baseDirLayout);
|
||||
auto languageLayout = new QHBoxLayout();
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.entry.orcLanguage"),
|
||||
"AdvSceneSwitcher.condition.video.layout.ocrLanguage"),
|
||||
languageLayout, widgetPlaceholders);
|
||||
layout->addLayout(languageLayout);
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.layout.ocrConfig"),
|
||||
_configLayout, widgetPlaceholders, false);
|
||||
layout->addWidget(_useConfig);
|
||||
layout->addLayout(_configLayout);
|
||||
auto colorPickLayout = new QHBoxLayout();
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.entry.orcColorPick"),
|
||||
"AdvSceneSwitcher.condition.video.layout.ocrColorPick"),
|
||||
colorPickLayout, widgetPlaceholders);
|
||||
layout->addLayout(colorPickLayout);
|
||||
layout->addWidget(_colorThreshold);
|
||||
setLayout(layout);
|
||||
|
||||
_matchText->setPlainText(_data->_ocrParameters.text);
|
||||
_regex->SetRegexConfig(_data->_ocrParameters.regex);
|
||||
SetupColorLabel(_data->_ocrParameters.color);
|
||||
_colorThreshold->SetDoubleValue(_data->_ocrParameters.colorThreshold);
|
||||
_matchText->setPlainText(_entryData->_ocrParameters.text);
|
||||
_regex->SetRegexConfig(_entryData->_ocrParameters.regex);
|
||||
SetupColorLabel(_entryData->_ocrParameters.color);
|
||||
_colorThreshold->SetDoubleValue(
|
||||
_entryData->_ocrParameters.colorThreshold);
|
||||
_pageSegMode->setCurrentIndex(_pageSegMode->findData(
|
||||
static_cast<int>(_data->_ocrParameters.GetPageMode())));
|
||||
static_cast<int>(_entryData->_ocrParameters.GetPageMode())));
|
||||
_tesseractBaseDir->SetPath(
|
||||
_data->_ocrParameters.GetTesseractBasePath());
|
||||
_languageCode->setText(_data->_ocrParameters.GetLanguageCode());
|
||||
_entryData->_ocrParameters.GetTesseractBasePath());
|
||||
_languageCode->setText(_entryData->_ocrParameters.GetLanguageCode());
|
||||
_useConfig->setChecked(
|
||||
_entryData->_ocrParameters.CustomConfigIsEnabled());
|
||||
_configFile->SetPath(_entryData->_ocrParameters.GetCustomConfigFile());
|
||||
SetLayoutVisible(_configLayout,
|
||||
_entryData->_ocrParameters.CustomConfigIsEnabled());
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
|
|
@ -665,12 +740,12 @@ void OCREdit::SetupColorLabel(const QColor &color)
|
|||
|
||||
void OCREdit::SelectColorClicked()
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QColor color = QColorDialog::getColor(
|
||||
_data->_ocrParameters.color, this,
|
||||
_entryData->_ocrParameters.color, this,
|
||||
obs_module_text("AdvSceneSwitcher.condition.video.selectColor"),
|
||||
QColorDialog::ColorDialogOption());
|
||||
|
||||
|
|
@ -680,73 +755,54 @@ void OCREdit::SelectColorClicked()
|
|||
|
||||
SetupColorLabel(color);
|
||||
auto lock = LockContext();
|
||||
_data->_ocrParameters.color = color;
|
||||
_entryData->_ocrParameters.color = color;
|
||||
|
||||
_previewDialog->OCRParametersChanged(_data->_ocrParameters);
|
||||
_previewDialog->OCRParametersChanged(_entryData->_ocrParameters);
|
||||
}
|
||||
|
||||
void OCREdit::ColorThresholdChanged(const DoubleVariable &value)
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
return;
|
||||
}
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_ocrParameters.colorThreshold = value;
|
||||
|
||||
auto lock = LockContext();
|
||||
_data->_ocrParameters.colorThreshold = value;
|
||||
|
||||
_previewDialog->OCRParametersChanged(_data->_ocrParameters);
|
||||
_previewDialog->OCRParametersChanged(_entryData->_ocrParameters);
|
||||
}
|
||||
|
||||
void OCREdit::MatchTextChanged()
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_data->_ocrParameters.text =
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_ocrParameters.text =
|
||||
_matchText->toPlainText().toUtf8().constData();
|
||||
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
|
||||
_previewDialog->OCRParametersChanged(_data->_ocrParameters);
|
||||
_previewDialog->OCRParametersChanged(_entryData->_ocrParameters);
|
||||
}
|
||||
|
||||
void OCREdit::RegexChanged(const RegexConfig &conf)
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_data->_ocrParameters.regex = conf;
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_ocrParameters.regex = conf;
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
|
||||
_previewDialog->OCRParametersChanged(_data->_ocrParameters);
|
||||
_previewDialog->OCRParametersChanged(_entryData->_ocrParameters);
|
||||
}
|
||||
|
||||
void OCREdit::PageSegModeChanged(int idx)
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_data->SetPageSegMode(static_cast<tesseract::PageSegMode>(
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->SetPageSegMode(static_cast<tesseract::PageSegMode>(
|
||||
_pageSegMode->itemData(idx).toInt()));
|
||||
|
||||
_previewDialog->OCRParametersChanged(_data->_ocrParameters);
|
||||
_previewDialog->OCRParametersChanged(_entryData->_ocrParameters);
|
||||
}
|
||||
|
||||
void OCREdit::TesseractBaseDirChanged(const QString &path){
|
||||
if (_loading || !_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
if (!_data->SetTesseractBaseDir(path.toStdString())) {
|
||||
void OCREdit::TesseractBaseDirChanged(const QString &path)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
if (!_entryData->SetTesseractBaseDir(path.toStdString())) {
|
||||
const QString message(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.ocrLanguageNotFound"));
|
||||
const QDir dataDir(path);
|
||||
|
|
@ -755,34 +811,48 @@ void OCREdit::TesseractBaseDirChanged(const QString &path){
|
|||
|
||||
// Reset to previous value
|
||||
const QSignalBlocker b(this);
|
||||
_tesseractBaseDir->SetPath(_data->_ocrParameters.GetTesseractBasePath());
|
||||
_tesseractBaseDir->SetPath(
|
||||
_entryData->_ocrParameters.GetTesseractBasePath());
|
||||
return;
|
||||
}
|
||||
_previewDialog->OCRParametersChanged(_data->_ocrParameters);
|
||||
_previewDialog->OCRParametersChanged(_entryData->_ocrParameters);
|
||||
}
|
||||
|
||||
|
||||
void OCREdit::LanguageChanged()
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
if (!_data->SetLanguageCode(_languageCode->text().toStdString())) {
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
if (!_entryData->SetLanguageCode(_languageCode->text().toStdString())) {
|
||||
const QString message(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.ocrLanguageNotFound"));
|
||||
const QDir dataDir(QString::fromStdString(
|
||||
_data->_ocrParameters.GetTesseractBasePath()));
|
||||
_entryData->_ocrParameters.GetTesseractBasePath()));
|
||||
const QString fileName(_languageCode->text() + ".traineddata");
|
||||
DisplayMessage(message.arg(fileName, dataDir.absolutePath()));
|
||||
|
||||
// Reset to previous value
|
||||
const QSignalBlocker b(this);
|
||||
_languageCode->setText(_data->_ocrParameters.GetLanguageCode());
|
||||
_languageCode->setText(
|
||||
_entryData->_ocrParameters.GetLanguageCode());
|
||||
return;
|
||||
}
|
||||
_previewDialog->OCRParametersChanged(_data->_ocrParameters);
|
||||
_previewDialog->OCRParametersChanged(_entryData->_ocrParameters);
|
||||
}
|
||||
|
||||
void OCREdit::UseConfigChanged(int value)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_ocrParameters.EnableCustomConfig(value);
|
||||
SetLayoutVisible(_configLayout, value);
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
_previewDialog->OCRParametersChanged(_entryData->_ocrParameters);
|
||||
}
|
||||
|
||||
void OCREdit::ConfigFileChanged(const QString &path)
|
||||
{
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_ocrParameters.SetCustomConfigFile(path.toStdString());
|
||||
_previewDialog->OCRParametersChanged(_entryData->_ocrParameters);
|
||||
}
|
||||
|
||||
ObjectDetectEdit::ObjectDetectEdit(
|
||||
|
|
@ -802,7 +872,7 @@ ObjectDetectEdit::ObjectDetectEdit(
|
|||
_minSize(new SizeSelection(0, 1024)),
|
||||
_maxSize(new SizeSelection(0, 4096)),
|
||||
_previewDialog(previewDialog),
|
||||
_data(data)
|
||||
_entryData(data)
|
||||
{
|
||||
_minNeighbors->setMinimum(minMinNeighbors);
|
||||
_minNeighbors->setMaximum(maxMinNeighbors);
|
||||
|
|
@ -833,14 +903,14 @@ ObjectDetectEdit::ObjectDetectEdit(
|
|||
pathLayout->setContentsMargins(0, 0, 0, 0);
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.entry.modelPath"),
|
||||
"AdvSceneSwitcher.condition.video.layout.modelPath"),
|
||||
pathLayout, widgetPlaceholders);
|
||||
|
||||
auto neighborsLayout = new QHBoxLayout;
|
||||
neighborsLayout->setContentsMargins(0, 0, 0, 0);
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.entry.minNeighbor"),
|
||||
"AdvSceneSwitcher.condition.video.layout.minNeighbor"),
|
||||
neighborsLayout, widgetPlaceholders);
|
||||
|
||||
auto sizeGrid = new QGridLayout;
|
||||
|
|
@ -866,62 +936,50 @@ ObjectDetectEdit::ObjectDetectEdit(
|
|||
layout->addLayout(sizeLayout);
|
||||
setLayout(layout);
|
||||
|
||||
_modelDataPath->SetPath(_data->GetModelDataPath());
|
||||
_modelDataPath->SetPath(_entryData->GetModelDataPath());
|
||||
_objectScaleThreshold->SetDoubleValue(
|
||||
_data->_objMatchParameters.scaleFactor);
|
||||
_minNeighbors->setValue(_data->_objMatchParameters.minNeighbors);
|
||||
_minSize->SetSize(_data->_objMatchParameters.minSize);
|
||||
_maxSize->SetSize(_data->_objMatchParameters.maxSize);
|
||||
_entryData->_objMatchParameters.scaleFactor);
|
||||
_minNeighbors->setValue(_entryData->_objMatchParameters.minNeighbors);
|
||||
_minSize->SetSize(_entryData->_objMatchParameters.minSize);
|
||||
_maxSize->SetSize(_entryData->_objMatchParameters.maxSize);
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void ObjectDetectEdit::ObjectScaleThresholdChanged(const DoubleVariable &value)
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_data->_objMatchParameters.scaleFactor = value;
|
||||
_previewDialog->ObjDetectParametersChanged(_data->_objMatchParameters);
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_objMatchParameters.scaleFactor = value;
|
||||
_previewDialog->ObjDetectParametersChanged(
|
||||
_entryData->_objMatchParameters);
|
||||
}
|
||||
|
||||
void ObjectDetectEdit::MinNeighborsChanged(int value)
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_data->_objMatchParameters.minNeighbors = value;
|
||||
_previewDialog->ObjDetectParametersChanged(_data->_objMatchParameters);
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_objMatchParameters.minNeighbors = value;
|
||||
_previewDialog->ObjDetectParametersChanged(
|
||||
_entryData->_objMatchParameters);
|
||||
}
|
||||
|
||||
void ObjectDetectEdit::MinSizeChanged(advss::Size value)
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_data->_objMatchParameters.minSize = value;
|
||||
_previewDialog->ObjDetectParametersChanged(_data->_objMatchParameters);
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_objMatchParameters.minSize = value;
|
||||
_previewDialog->ObjDetectParametersChanged(
|
||||
_entryData->_objMatchParameters);
|
||||
}
|
||||
|
||||
void ObjectDetectEdit::MaxSizeChanged(advss::Size value)
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_data->_objMatchParameters.maxSize = value;
|
||||
_previewDialog->ObjDetectParametersChanged(_data->_objMatchParameters);
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_objMatchParameters.maxSize = value;
|
||||
_previewDialog->ObjDetectParametersChanged(
|
||||
_entryData->_objMatchParameters);
|
||||
}
|
||||
|
||||
void ObjectDetectEdit::ModelPathChanged(const QString &text)
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -929,13 +987,14 @@ void ObjectDetectEdit::ModelPathChanged(const QString &text)
|
|||
{
|
||||
auto lock = LockContext();
|
||||
std::string path = text.toStdString();
|
||||
dataLoaded = _data->LoadModelData(path);
|
||||
dataLoaded = _entryData->LoadModelData(path);
|
||||
}
|
||||
if (!dataLoaded) {
|
||||
DisplayMessage(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.modelLoadFail"));
|
||||
}
|
||||
_previewDialog->ObjDetectParametersChanged(_data->_objMatchParameters);
|
||||
_previewDialog->ObjDetectParametersChanged(
|
||||
_entryData->_objMatchParameters);
|
||||
}
|
||||
|
||||
ColorEdit::ColorEdit(QWidget *parent,
|
||||
|
|
@ -958,7 +1017,7 @@ ColorEdit::ColorEdit(QWidget *parent,
|
|||
_color(new QLabel),
|
||||
_selectColor(new QPushButton(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.selectColor"))),
|
||||
_data(data)
|
||||
_entryData(data)
|
||||
{
|
||||
QWidget::connect(_selectColor, SIGNAL(clicked()), this,
|
||||
SLOT(SelectColorClicked()));
|
||||
|
|
@ -979,9 +1038,9 @@ ColorEdit::ColorEdit(QWidget *parent,
|
|||
};
|
||||
|
||||
auto colorLayout = new QHBoxLayout;
|
||||
PlaceWidgets(
|
||||
obs_module_text("AdvSceneSwitcher.condition.video.entry.color"),
|
||||
colorLayout, widgetPlaceholders);
|
||||
PlaceWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.layout.color"),
|
||||
colorLayout, widgetPlaceholders);
|
||||
|
||||
auto layout = new QVBoxLayout;
|
||||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
|
|
@ -990,9 +1049,11 @@ ColorEdit::ColorEdit(QWidget *parent,
|
|||
layout->addWidget(_matchThreshold);
|
||||
setLayout(layout);
|
||||
|
||||
_matchThreshold->SetDoubleValue(_data->_colorParameters.matchThreshold);
|
||||
_colorThreshold->SetDoubleValue(_data->_colorParameters.colorThreshold);
|
||||
SetupColorLabel(_data->_colorParameters.color);
|
||||
_matchThreshold->SetDoubleValue(
|
||||
_entryData->_colorParameters.matchThreshold);
|
||||
_colorThreshold->SetDoubleValue(
|
||||
_entryData->_colorParameters.colorThreshold);
|
||||
SetupColorLabel(_entryData->_colorParameters.color);
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
|
|
@ -1005,32 +1066,24 @@ void ColorEdit::SetupColorLabel(const QColor &color)
|
|||
|
||||
void ColorEdit::MatchThresholdChanged(const DoubleVariable &value)
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_data->_colorParameters.matchThreshold = value;
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_colorParameters.matchThreshold = value;
|
||||
}
|
||||
|
||||
void ColorEdit::ColorThresholdChanged(const DoubleVariable &value)
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_data->_colorParameters.colorThreshold = value;
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_colorParameters.colorThreshold = value;
|
||||
}
|
||||
|
||||
void ColorEdit::SelectColorClicked()
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
const QColor color = QColorDialog::getColor(
|
||||
_data->_colorParameters.color, this,
|
||||
_entryData->_colorParameters.color, this,
|
||||
obs_module_text("AdvSceneSwitcher.condition.video.selectColor"),
|
||||
QColorDialog::ColorDialogOption());
|
||||
|
||||
|
|
@ -1040,19 +1093,19 @@ void ColorEdit::SelectColorClicked()
|
|||
|
||||
SetupColorLabel(color);
|
||||
auto lock = LockContext();
|
||||
_data->_colorParameters.color = color;
|
||||
_entryData->_colorParameters.color = color;
|
||||
}
|
||||
|
||||
AreaEdit::AreaEdit(QWidget *parent, PreviewDialog *previewDialog,
|
||||
const std::shared_ptr<MacroConditionVideo> &data)
|
||||
: QWidget(parent),
|
||||
_checkAreaEnable(new QCheckBox(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.entry.checkAreaEnable"))),
|
||||
"AdvSceneSwitcher.condition.video.layout.checkAreaEnable"))),
|
||||
_checkArea(new AreaSelection(0, 99999)),
|
||||
_selectArea(new QPushButton(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.selectArea"))),
|
||||
_previewDialog(previewDialog),
|
||||
_data(data)
|
||||
_entryData(data)
|
||||
{
|
||||
QWidget::connect(_checkAreaEnable, SIGNAL(stateChanged(int)), this,
|
||||
SLOT(CheckAreaEnableChanged(int)));
|
||||
|
|
@ -1073,20 +1126,20 @@ AreaEdit::AreaEdit(QWidget *parent, PreviewDialog *previewDialog,
|
|||
layout->setContentsMargins(0, 0, 0, 0);
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.entry.checkArea"),
|
||||
"AdvSceneSwitcher.condition.video.layout.checkArea"),
|
||||
layout, widgetPlaceholders);
|
||||
setLayout(layout);
|
||||
|
||||
_checkAreaEnable->setChecked(_data->_areaParameters.enable);
|
||||
_checkArea->SetArea(_data->_areaParameters.area);
|
||||
_checkAreaEnable->setChecked(_entryData->_areaParameters.enable);
|
||||
_checkArea->SetArea(_entryData->_areaParameters.area);
|
||||
SetWidgetVisibility();
|
||||
_loading = false;
|
||||
}
|
||||
|
||||
void AreaEdit::SetWidgetVisibility()
|
||||
{
|
||||
_checkArea->setVisible(_data->_areaParameters.enable);
|
||||
_selectArea->setVisible(_data->_areaParameters.enable);
|
||||
_checkArea->setVisible(_entryData->_areaParameters.enable);
|
||||
_selectArea->setVisible(_entryData->_areaParameters.enable);
|
||||
adjustSize();
|
||||
updateGeometry();
|
||||
}
|
||||
|
|
@ -1101,26 +1154,18 @@ void AreaEdit::SelectAreaClicked()
|
|||
|
||||
void AreaEdit::CheckAreaEnableChanged(int value)
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_data->_areaParameters.enable = value;
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_areaParameters.enable = value;
|
||||
SetWidgetVisibility();
|
||||
_previewDialog->AreaParametersChanged(_data->_areaParameters);
|
||||
_previewDialog->AreaParametersChanged(_entryData->_areaParameters);
|
||||
emit Resized();
|
||||
}
|
||||
|
||||
void AreaEdit::CheckAreaChanged(Area value)
|
||||
{
|
||||
if (_loading || !_data) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
_data->_areaParameters.area = value;
|
||||
_previewDialog->AreaParametersChanged(_data->_areaParameters);
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_areaParameters.area = value;
|
||||
_previewDialog->AreaParametersChanged(_entryData->_areaParameters);
|
||||
}
|
||||
|
||||
void AreaEdit::CheckAreaChanged(QRect rect)
|
||||
|
|
@ -1261,15 +1306,16 @@ MacroConditionVideoEdit::MacroConditionVideoEdit(
|
|||
{"{{throttleCount}}", _throttleCount},
|
||||
{"{{patternMatchingModes}}", _patternMatchMode},
|
||||
};
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.condition.video.entry"),
|
||||
PlaceWidgets(obs_module_text("AdvSceneSwitcher.condition.video.layout"),
|
||||
entryLine1Layout, widgetPlaceholders);
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.patternMatchMode"),
|
||||
_patternMatchModeLayout, widgetPlaceholders);
|
||||
PlaceWidgets(obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.entry.throttle"),
|
||||
_throttleControlLayout, widgetPlaceholders);
|
||||
PlaceWidgets(
|
||||
obs_module_text(
|
||||
"AdvSceneSwitcher.condition.video.layout.throttle"),
|
||||
_throttleControlLayout, widgetPlaceholders);
|
||||
|
||||
QHBoxLayout *showMatchLayout = new QHBoxLayout;
|
||||
showMatchLayout->addWidget(_showMatch);
|
||||
|
|
@ -1323,33 +1369,21 @@ void MacroConditionVideoEdit::UpdatePreviewTooltip()
|
|||
|
||||
void MacroConditionVideoEdit::SourceChanged(const SourceSelection &source)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_video.source = source;
|
||||
HandleVideoInputUpdate();
|
||||
}
|
||||
|
||||
void MacroConditionVideoEdit::SceneChanged(const SceneSelection &scene)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_video.scene = scene;
|
||||
HandleVideoInputUpdate();
|
||||
}
|
||||
|
||||
void MacroConditionVideoEdit::VideoInputTypeChanged(int type)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_video.type = static_cast<VideoInput::Type>(type);
|
||||
HandleVideoInputUpdate();
|
||||
SetWidgetVisibility();
|
||||
|
|
@ -1365,11 +1399,7 @@ void MacroConditionVideoEdit::HandleVideoInputUpdate()
|
|||
|
||||
void MacroConditionVideoEdit::ConditionChanged(int idx)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->SetCondition(
|
||||
static_cast<VideoCondition>(_condition->itemData(idx).toInt()));
|
||||
_entryData->ResetLastMatch();
|
||||
|
|
@ -1397,11 +1427,7 @@ void MacroConditionVideoEdit::ConditionChanged(int idx)
|
|||
|
||||
void MacroConditionVideoEdit::ImagePathChanged(const QString &text)
|
||||
{
|
||||
if (_loading || !_entryData) {
|
||||
return;
|
||||
}
|
||||
|
||||
auto lock = LockContext();
|
||||
GUARD_LOADING_AND_LOCK();
|
||||
_entryData->_file = text.toUtf8().constData();
|
||||
_entryData->ResetLastMatch();
|
||||
if (_entryData->LoadImageFromFile()) {
|
||||
|
|
|
|||
|
|
@ -128,7 +128,7 @@ private:
|
|||
QLabel *_current;
|
||||
QTimer _timer;
|
||||
|
||||
std::shared_ptr<MacroConditionVideo> _data;
|
||||
std::shared_ptr<MacroConditionVideo> _entryData;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
|
|
@ -147,6 +147,8 @@ private slots:
|
|||
void PageSegModeChanged(int);
|
||||
void TesseractBaseDirChanged(const QString &);
|
||||
void LanguageChanged();
|
||||
void UseConfigChanged(int);
|
||||
void ConfigFileChanged(const QString &);
|
||||
|
||||
private:
|
||||
void SetupColorLabel(const QColor &);
|
||||
|
|
@ -159,10 +161,15 @@ private:
|
|||
QComboBox *_pageSegMode;
|
||||
FileSelection *_tesseractBaseDir;
|
||||
VariableLineEdit *_languageCode;
|
||||
QCheckBox *_useConfig;
|
||||
FileSelection *_configFile;
|
||||
QPushButton *_openConfigFile;
|
||||
QPushButton *_reloadConfig;
|
||||
QHBoxLayout *_configLayout;
|
||||
|
||||
PreviewDialog *_previewDialog;
|
||||
|
||||
std::shared_ptr<MacroConditionVideo> _data;
|
||||
std::shared_ptr<MacroConditionVideo> _entryData;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
|
|
@ -190,7 +197,7 @@ private:
|
|||
|
||||
PreviewDialog *_previewDialog;
|
||||
|
||||
std::shared_ptr<MacroConditionVideo> _data;
|
||||
std::shared_ptr<MacroConditionVideo> _entryData;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
|
|
@ -214,7 +221,7 @@ private:
|
|||
QLabel *_color;
|
||||
QPushButton *_selectColor;
|
||||
|
||||
std::shared_ptr<MacroConditionVideo> _data;
|
||||
std::shared_ptr<MacroConditionVideo> _entryData;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
|
|
@ -243,7 +250,7 @@ private:
|
|||
|
||||
PreviewDialog *_previewDialog;
|
||||
|
||||
std::shared_ptr<MacroConditionVideo> _data;
|
||||
std::shared_ptr<MacroConditionVideo> _entryData;
|
||||
bool _loading = true;
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -202,14 +202,15 @@ cv::Mat PreprocessForOCR(const QImage &image, const QColor &textColor,
|
|||
return result;
|
||||
}
|
||||
|
||||
std::string RunOCR(tesseract::TessBaseAPI *ocr, const QImage &image,
|
||||
const QColor &color, double colorDiff)
|
||||
std::optional<std::string> RunOCR(tesseract::TessBaseAPI *ocr,
|
||||
const QImage &image, const QColor &color,
|
||||
double colorDiff)
|
||||
{
|
||||
(void)ocr;
|
||||
(void)color;
|
||||
(void)colorDiff;
|
||||
if (image.isNull()) {
|
||||
return "";
|
||||
return {};
|
||||
}
|
||||
|
||||
#ifdef OCR_SUPPORT
|
||||
|
|
@ -221,12 +222,12 @@ std::string RunOCR(tesseract::TessBaseAPI *ocr, const QImage &image,
|
|||
std::unique_ptr<char[]> detectedText(ocr->GetUTF8Text());
|
||||
|
||||
if (!detectedText) {
|
||||
return "";
|
||||
return {};
|
||||
}
|
||||
return detectedText.get();
|
||||
|
||||
#else
|
||||
return "";
|
||||
return {};
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -27,10 +27,23 @@ enum PageSegMode {
|
|||
PSM_COUNT
|
||||
};
|
||||
|
||||
enum OcrEngineMode {
|
||||
OEM_TESSERACT_ONLY,
|
||||
OEM_LSTM_ONLY,
|
||||
OEM_TESSERACT_LSTM_COMBINED,
|
||||
OEM_DEFAULT,
|
||||
OEM_COUNT // Number of OEMs
|
||||
};
|
||||
|
||||
class TessBaseAPI {
|
||||
public:
|
||||
void SetPageSegMode(PageSegMode) {}
|
||||
int Init(const char *, const char *) { return 0; }
|
||||
int Init(const char *, const char *, OcrEngineMode, char **, int,
|
||||
const std::vector<std::string> *,
|
||||
const std::vector<std::string> *, bool)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
void End() {}
|
||||
};
|
||||
} // namespace tesseract
|
||||
|
|
@ -62,8 +75,8 @@ std::vector<cv::Rect> MatchObject(QImage &img, cv::CascadeClassifier &cascade,
|
|||
uchar GetAvgBrightness(QImage &img);
|
||||
cv::Mat PreprocessForOCR(const QImage &image, const QColor &color,
|
||||
double colorDiff);
|
||||
std::string RunOCR(tesseract::TessBaseAPI *, const QImage &, const QColor &,
|
||||
double colorDiff);
|
||||
std::optional<std::string> RunOCR(tesseract::TessBaseAPI *, const QImage &,
|
||||
const QColor &, double colorDiff);
|
||||
bool ContainsPixelsInColorRange(const QImage &image, const QColor &color,
|
||||
double colorDeviationThreshold,
|
||||
double totalPixelMatchThreshold);
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "parameter-wrappers.hpp"
|
||||
#include "log-helper.hpp"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <source-helpers.hpp>
|
||||
|
|
@ -253,14 +254,13 @@ OCRParameters::OCRParameters(const OCRParameters &other)
|
|||
colorThreshold(other.colorThreshold),
|
||||
pageSegMode(other.pageSegMode),
|
||||
tesseractBasePath(other.tesseractBasePath),
|
||||
languageCode(other.languageCode)
|
||||
languageCode(other.languageCode),
|
||||
useConfig(other.useConfig),
|
||||
configFile(other.configFile)
|
||||
{
|
||||
if (!initDone) {
|
||||
Setup();
|
||||
}
|
||||
if (initDone) {
|
||||
ocr->SetPageSegMode(pageSegMode);
|
||||
}
|
||||
}
|
||||
|
||||
OCRParameters &OCRParameters::operator=(const OCRParameters &other)
|
||||
|
|
@ -272,12 +272,11 @@ OCRParameters &OCRParameters::operator=(const OCRParameters &other)
|
|||
pageSegMode = other.pageSegMode;
|
||||
tesseractBasePath = other.tesseractBasePath;
|
||||
languageCode = other.languageCode;
|
||||
useConfig = other.useConfig;
|
||||
configFile = other.configFile;
|
||||
if (!initDone) {
|
||||
Setup();
|
||||
}
|
||||
if (initDone) {
|
||||
ocr->SetPageSegMode(pageSegMode);
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
@ -288,6 +287,8 @@ bool OCRParameters::Save(obs_data_t *obj) const
|
|||
regex.Save(data);
|
||||
tesseractBasePath.Save(data, "tesseractBasePath");
|
||||
languageCode.Save(data, "language");
|
||||
obs_data_set_bool(data, "useConfig", useConfig);
|
||||
obs_data_set_string(data, "configFile", configFile.c_str());
|
||||
SaveColor(data, "textColor", color);
|
||||
colorThreshold.Save(data, "colorThreshold");
|
||||
obs_data_set_int(data, "pageSegMode", static_cast<int>(pageSegMode));
|
||||
|
|
@ -311,6 +312,8 @@ bool OCRParameters::Load(obs_data_t *obj)
|
|||
obs_current_module())) +
|
||||
"/res/ocr/";
|
||||
}
|
||||
useConfig = obs_data_get_bool(data, "useConfig");
|
||||
configFile = obs_data_get_string(data, "configFile");
|
||||
|
||||
color = LoadColor(data, "textColor");
|
||||
if (obs_data_has_user_value(data, "version")) {
|
||||
|
|
@ -320,9 +323,6 @@ bool OCRParameters::Load(obs_data_t *obj)
|
|||
obs_data_get_int(data, "pageSegMode"));
|
||||
obs_data_release(data);
|
||||
|
||||
if (initDone) {
|
||||
ocr->SetPageSegMode(pageSegMode);
|
||||
}
|
||||
Setup();
|
||||
return true;
|
||||
}
|
||||
|
|
@ -330,7 +330,9 @@ bool OCRParameters::Load(obs_data_t *obj)
|
|||
void OCRParameters::SetPageMode(tesseract::PageSegMode mode)
|
||||
{
|
||||
pageSegMode = mode;
|
||||
ocr->SetPageSegMode(mode);
|
||||
if (ocr) {
|
||||
ocr->SetPageSegMode(mode);
|
||||
}
|
||||
}
|
||||
|
||||
bool OCRParameters::SetLanguageCode(const std::string &value)
|
||||
|
|
@ -343,7 +345,6 @@ bool OCRParameters::SetLanguageCode(const std::string &value)
|
|||
}
|
||||
languageCode = value;
|
||||
Setup();
|
||||
ocr->SetPageSegMode(pageSegMode);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -363,7 +364,6 @@ bool OCRParameters::SetTesseractBasePath(const std::string &value)
|
|||
}
|
||||
tesseractBasePath = value;
|
||||
Setup();
|
||||
ocr->SetPageSegMode(pageSegMode);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -372,6 +372,18 @@ std::string OCRParameters::GetTesseractBasePath() const
|
|||
return tesseractBasePath;
|
||||
}
|
||||
|
||||
void OCRParameters::EnableCustomConfig(bool enable)
|
||||
{
|
||||
useConfig = enable;
|
||||
Setup();
|
||||
}
|
||||
|
||||
void OCRParameters::SetCustomConfigFile(const std::string &filename)
|
||||
{
|
||||
configFile = filename;
|
||||
Setup();
|
||||
}
|
||||
|
||||
void OCRParameters::Setup()
|
||||
{
|
||||
ocr = std::make_unique<tesseract::TessBaseAPI>();
|
||||
|
|
@ -383,18 +395,41 @@ void OCRParameters::Setup()
|
|||
const std::string dataPath = std::string(tesseractBasePath) + "/";
|
||||
const std::string modelFile =
|
||||
std::string(languageCode) + ".traineddata";
|
||||
const auto fullPath = QString::fromStdString(dataPath) +
|
||||
QString::fromStdString(modelFile);
|
||||
QFileInfo fileInfo(fullPath);
|
||||
if (!fileInfo.exists(fullPath)) {
|
||||
const auto modelFullPath = QString::fromStdString(dataPath) +
|
||||
QString::fromStdString(modelFile);
|
||||
QFileInfo modelFileInfo(modelFullPath);
|
||||
if (!modelFileInfo.exists(modelFullPath)) {
|
||||
initDone = false;
|
||||
blog(LOG_WARNING,
|
||||
"cannot init tesseract! Model path does not exists: %s",
|
||||
modelFileInfo.absoluteFilePath().toStdString().c_str());
|
||||
return;
|
||||
}
|
||||
|
||||
auto configPath = QString::fromStdString(configFile);
|
||||
QFileInfo configFileInfo(configPath);
|
||||
bool configFileExists = configFileInfo.exists(configPath);
|
||||
|
||||
bool setupWithConfig = useConfig;
|
||||
if (useConfig && !configFileExists) {
|
||||
blog(LOG_WARNING,
|
||||
"tesseract config file will be ignored! File does not exists: %s",
|
||||
configFileInfo.absoluteFilePath().toStdString().c_str());
|
||||
setupWithConfig = false;
|
||||
}
|
||||
|
||||
char *configs[] = {configFile.data()};
|
||||
if (ocr->Init(dataPath.c_str(), languageCode.c_str(),
|
||||
tesseract::OEM_DEFAULT,
|
||||
setupWithConfig ? configs : nullptr,
|
||||
setupWithConfig ? 1 : 0, nullptr, nullptr, false) != 0) {
|
||||
blog(LOG_WARNING, "tesseract init failed!");
|
||||
initDone = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (ocr->Init(dataPath.c_str(), languageCode.c_str()) != 0) {
|
||||
initDone = false;
|
||||
return;
|
||||
}
|
||||
ocr->SetPageSegMode(pageSegMode);
|
||||
|
||||
initDone = true;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -95,6 +95,10 @@ public:
|
|||
std::string GetLanguageCode() const;
|
||||
bool SetTesseractBasePath(const std::string &);
|
||||
std::string GetTesseractBasePath() const;
|
||||
void EnableCustomConfig(bool enable);
|
||||
bool CustomConfigIsEnabled() const { return useConfig; }
|
||||
void SetCustomConfigFile(const std::string &);
|
||||
std::string GetCustomConfigFile() const { return configFile; }
|
||||
tesseract::PageSegMode GetPageMode() const { return pageSegMode; }
|
||||
tesseract::TessBaseAPI *GetOCR() const { return ocr.get(); }
|
||||
|
||||
|
|
@ -111,6 +115,8 @@ private:
|
|||
obs_get_module_data_path(obs_current_module()) +
|
||||
std::string("/res/ocr");
|
||||
StringVariable languageCode = "eng";
|
||||
bool useConfig = false;
|
||||
std::string configFile = "config.txt";
|
||||
std::unique_ptr<tesseract::TessBaseAPI> ocr;
|
||||
bool initDone = false;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -353,9 +353,15 @@ void PreviewImage::MarkMatch(QImage &screenshot,
|
|||
} else if (condition == VideoCondition::OCR) {
|
||||
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)));
|
||||
emit StatusUpdate(status.arg(QString::fromStdString(*text)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user