This commit is contained in:
恍兮惚兮 2024-08-21 08:57:14 +08:00
parent ba1b9c977b
commit 80e1899466
26 changed files with 287 additions and 79 deletions

View File

@ -10,12 +10,16 @@ from gui.usefulwidget import (
yuitsu_switch,
D_getcolorbutton,
D_getsimpleswitch,
clearlayout,
getboxlayout,
selectcolor,
)
import gobject
from gui.dynalang import LFormLayout
from myutils.ocrutil import ocr_end, ocr_init
from myutils.wrapper import threader
def __label1(self):
self.threshold1label = QLabel()
return self.threshold1label
@ -83,6 +87,98 @@ def initgridsources(self, names):
return grids_source
def _ocrparam_create(self, idx):
clearlayout(self._ocrparaml)
if idx in [1, 2]:
self._ocrparaml.addRow(
"执行周期(s)",
getboxlayout(
[
D_getspinbox(
0.1,
100,
globalconfig,
"ocr_interval",
double=True,
step=0.1,
),
QLabel,
]
),
)
if idx in [3]:
self._ocrparaml.addRow(
"延迟(s)",
getboxlayout(
[
D_getspinbox(
0,
100,
globalconfig,
"ocr_trigger_delay",
double=True,
step=0.1,
),
QLabel,
]
),
)
if idx in [0, 2, 3]:
self._ocrparaml.addRow(
"图像稳定性阈值",
getboxlayout(
[
D_getspinbox(
0,
1,
globalconfig,
("ocr_stable_sim", "ocr_stable_sim2")[idx == 3],
double=True,
step=0.001,
dec=3,
),
functools.partial(__label1, self),
]
),
)
if idx in [0, 2]:
self._ocrparaml.addRow(
"图像一致性阈值",
getboxlayout(
[
D_getspinbox(
0,
1,
globalconfig,
"ocr_diff_sim",
double=True,
step=0.001,
dec=3,
),
functools.partial(__label2, self),
]
),
)
if idx in [0, 1, 2]:
self._ocrparaml.addRow(
"文本相似度阈值",
getboxlayout(
[D_getspinbox(0, 100000, globalconfig, "ocr_text_diff"), QLabel]
),
)
def _ocrparam(self):
self._ocrparam = QGroupBox()
self._ocrparam.setStyleSheet(
"QGroupBox{ margin-top:0px;} QGroupBox:title {margin-top: 0px;}"
)
self._ocrparaml = LFormLayout()
self._ocrparam.setLayout(self._ocrparaml)
_ocrparam_create(self, globalconfig["ocr_auto_method"])
return self._ocrparam
def getocrgrid(self):
grids = []
@ -181,7 +277,7 @@ def getocrgrid(self):
type="grid",
grid=[
[
("自动化执行方法", 7),
"自动化执行方法",
D_getIconButton(
callback=lambda: gobject.baseobject.openlink(
dynamiclink("{docs_server}/#/zh/ocrparam")
@ -194,63 +290,16 @@ def getocrgrid(self):
"分析图像更新",
"周期执行",
"分析图像更新+周期执行",
"鼠标键盘触发+等待稳定",
],
globalconfig,
"ocr_auto_method",
callback=functools.partial(_ocrparam_create, self),
),
12,
),
],
[
(("执行周期(s)"), 8),
(
D_getspinbox(
0.1,
100,
globalconfig,
"ocr_interval",
double=True,
step=0.1,
),
4,
),
],
[
(("图像稳定性阈值"), 8),
(
D_getspinbox(
0,
1,
globalconfig,
"ocr_stable_sim",
double=True,
step=0.01,
dec=3,
),
4,
),
(functools.partial(__label1, self), 0),
],
[
(("图像一致性阈值"), 8),
(
D_getspinbox(
0,
1,
globalconfig,
"ocr_diff_sim",
double=True,
step=0.01,
dec=3,
),
4,
),
(functools.partial(__label2, self), 0),
],
[
(("文本相似度阈值"), 8),
(D_getspinbox(0, 100000, globalconfig, "ocr_text_diff"), 4),
],
[(functools.partial(_ocrparam, self), 0)],
],
),
0,
@ -306,6 +355,10 @@ def getocrgrid(self):
globalconfig, "showrangeafterrangeselect"
),
],
[
"选取OCR范围后自动绑定窗口",
D_getsimpleswitch(globalconfig, "ocrautobindhwnd"),
],
],
),
0,

View File

@ -62,6 +62,8 @@ class ocrtext(basetext):
h4 = windows.WindowFromPoint(windows.POINT(p2[0], p1[1]))
self.range_ui[-1].setrect(rect)
if not globalconfig["ocrautobindhwnd"]:
return
if gobject.baseobject.hwnd:
return
usehwnds = []
@ -96,17 +98,82 @@ class ocrtext(basetext):
@threader
def gettextthread(self):
laststate = (0, 0, 0, 0, 0)
while not self.ending:
time.sleep(0.1)
if not self.isautorunning:
continue
t = self.getallres(True)
if t:
self.dispatchtext(t)
if globalconfig["ocr_auto_method"] == 3:
triggered = False
this = (
windows.GetAsyncKeyState(windows.VK_LBUTTON),
windows.GetAsyncKeyState(windows.VK_RETURN),
windows.GetAsyncKeyState(windows.VK_CONTROL),
windows.GetAsyncKeyState(windows.VK_SHIFT),
windows.GetAsyncKeyState(windows.VK_MENU),
)
if any(((this[_] and (laststate[_] == 0)) for _ in (0, 1))):
# 按下
triggered = True
elif any(((this[_] == 0 and laststate[_]) for _ in (2, 3, 4))):
# 松开
triggered = True
laststate = this
if triggered and gobject.baseobject.hwnd:
p1 = windows.GetWindowThreadProcessId(gobject.baseobject.hwnd)
p2 = windows.GetWindowThreadProcessId(windows.GetForegroundWindow())
triggered = p1 == p2
if triggered:
time.sleep(globalconfig["ocr_trigger_delay"])
for _ in range(len(self.savelastimg)):
self.savelastimg[_] = None
while (not self.ending) and (globalconfig["ocr_auto_method"] == 3):
if self.waitforstablex():
break
time.sleep(0.1)
t = self.getallres(False)
if t:
self.dispatchtext(t)
time.sleep(0.01)
else:
laststate = (0, 0, 0, 0, 0)
t = self.getallres(True)
if t:
self.dispatchtext(t)
time.sleep(0.1)
def waitforstable(self, i, imgr):
imgr1 = qimge2np(imgr)
if self.savelastimg[i] is not None and (
imgr1.shape == self.savelastimg[i].shape
):
image_score = compareImage(imgr1, self.savelastimg[i])
else:
image_score = 0
if i == 0:
try:
gobject.baseobject.settin_ui.threshold1label.setText(str(image_score))
except:
pass
self.savelastimg[i] = imgr1
ok = image_score > globalconfig["ocr_stable_sim2"]
return ok
def waitforstablex(self):
for i, range_ui in enumerate(self.range_ui):
rect = range_ui.getrect()
if rect is None:
continue
img = imageCut(
gobject.baseobject.hwnd, rect[0][0], rect[0][1], rect[1][0], rect[1][1]
)
if not self.waitforstable(i, img):
return False
return True
def getresauto(self, i, imgr):
ok = True
if globalconfig["ocr_auto_method"] in [0, 2]:
imgr1 = qimge2np(imgr)
h, w, c = imgr1.shape

View File

@ -135,6 +135,10 @@ WM_HOTKEY = 786
VK_LBUTTON = 1
VK_RBUTTON = 2
VK_RETURN = 0xD
VK_SHIFT = 0x10
VK_CONTROL = 0x11
VK_MENU = 0x12
WNDENUMPROC = WINFUNCTYPE(c_bool, c_void_p, c_void_p)
@ -739,6 +743,8 @@ def IsUserAnAdmin():
_GetKeyState = _user32.GetKeyState
_GetKeyState.restype = c_short
GetAsyncKeyState = _user32.GetAsyncKeyState
def GetKeyState(key):
return _GetKeyState(key)

View File

@ -5,6 +5,7 @@
"excule_from_exe": [],
"only_from_exe": [],
"showrangeafterrangeselect": true,
"ocrautobindhwnd": true,
"autodisappear": false,
"WindowBackdrop": 3,
"WindowEffect": 0,
@ -432,6 +433,7 @@
"multiregion": false,
"ocrregions": [],
"ocr_stable_sim": 0,
"ocr_stable_sim2": 0,
"ocr_diff_sim": 0.95,
"ocr_text_diff": 3,
"autorun": true,
@ -2015,6 +2017,7 @@
"time_period": false,
"ocr_auto_method": 0,
"ocr_interval": 5,
"ocr_trigger_delay": 0,
"mustocr_interval": 5,
"ocrmininterval": 1,
"selectable": false,

View File

@ -833,5 +833,8 @@
"文件翻译": "ترجمة الوثائق",
"文件": "الوثائق",
"最大结果条数": "أقصى عدد من النتائج",
"再次进行OCR": "التعرف الضوئي على الحروف مرة أخرى"
"再次进行OCR": "التعرف الضوئي على الحروف مرة أخرى",
"选取OCR范围后自动绑定窗口": "تلقائيا ملزمة نافذة بعد تحديد نطاق التعرف الضوئي على الحروف",
"延迟(s)": "تأخير ( ق )",
"鼠标键盘触发+等待稳定": "الماوس لوحة المفاتيح الزناد + انتظار الاستقرار"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "檔案翻譯",
"文件": "文件",
"最大结果条数": "最大結果條數",
"再次进行OCR": "再次進行OCR"
"再次进行OCR": "再次進行OCR",
"选取OCR范围后自动绑定窗口": "選取OCR範圍後自動綁定視窗",
"延迟(s)": "延遲s",
"鼠标键盘触发+等待稳定": "滑鼠鍵盤觸發+等待穩定"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "dokumentární překlad",
"文件": "soubor",
"最大结果条数": "Maximální počet výsledků",
"再次进行OCR": "Proveďte znovu OCR"
"再次进行OCR": "Proveďte znovu OCR",
"选取OCR范围后自动绑定窗口": "Automaticky vázat okno po výběru rozsahu OCR",
"延迟(s)": "Zpoždění (s)",
"鼠标键盘触发+等待稳定": "Spouštěč myši a klávesnice+čekání na stabilizaci"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "Übersetzung von Dokumenten",
"文件": "Datei",
"最大结果条数": "Maximale Anzahl der Ergebnisse",
"再次进行OCR": "OCR erneut ausführen"
"再次进行OCR": "OCR erneut ausführen",
"选取OCR范围后自动绑定窗口": "Fenster nach Auswahl des OCR-Bereichs automatisch binden",
"延迟(s)": "Verzögerung (s)",
"鼠标键盘触发+等待稳定": "Maus und Tastatur Trigger+warten auf Stabilisierung"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "documentary translation",
"文件": "file",
"最大结果条数": "Maximum number of results",
"再次进行OCR": "Perform OCR again"
"再次进行OCR": "Perform OCR again",
"选取OCR范围后自动绑定窗口": "Automatically bind window after selecting OCR range",
"延迟(s)": "Delay (s)",
"鼠标键盘触发+等待稳定": "Mouse and keyboard trigger+waiting for stabilization"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "Traducción de documentos",
"文件": "Documentos",
"最大结果条数": "Número máximo de resultados",
"再次进行OCR": "Volver a realizar OCR"
"再次进行OCR": "Volver a realizar OCR",
"选取OCR范围后自动绑定窗口": "Vincular automáticamente la ventana después de seleccionar el rango OCR",
"延迟(s)": "Retraso (s)",
"鼠标键盘触发+等待稳定": "Activación del ratón y el teclado + espera para estabilizarse"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "Traduction de documents",
"文件": "Documents",
"最大结果条数": "Nombre maximal de barres de résultats",
"再次进行OCR": "OCR à nouveau"
"再次进行OCR": "OCR à nouveau",
"选取OCR范围后自动绑定窗口": "Fenêtre de liaison automatique après sélection de la plage ocr",
"延迟(s)": "Retard (s)",
"鼠标键盘触发+等待稳定": "Déclenchement du clavier de la souris + attente de stabilisation"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "traduzione documentaria",
"文件": "file",
"最大结果条数": "Numero massimo di risultati",
"再次进行OCR": "Esegui nuovamente OCR"
"再次进行OCR": "Esegui nuovamente OCR",
"选取OCR范围后自动绑定窗口": "Associa automaticamente la finestra dopo aver selezionato l'intervallo OCR",
"延迟(s)": "Ritardo (s)",
"鼠标键盘触发+等待稳定": "Mouse e tastiera trigger + attesa di stabilizzazione"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "ファイル翻訳",
"文件": "ファイル",
"最大结果条数": "最大結果バー数",
"再次进行OCR": "OCRを再実行"
"再次进行OCR": "OCRを再実行",
"选取OCR范围后自动绑定窗口": "OCR範囲を選択するとウィンドウが自動的にバインドされます",
"延迟(s)": "遅延s",
"鼠标键盘触发+等待稳定": "マウスのキーボードトリガ+待機安定"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "파일 번역",
"文件": "파일",
"最大结果条数": "최대 결과 개수",
"再次进行OCR": "다시 OCR을 진행하도록 하겠습니다."
"再次进行OCR": "다시 OCR을 진행하도록 하겠습니다.",
"选取OCR范围后自动绑定窗口": "OCR 범위 선택 후 창 자동 바인딩",
"延迟(s)": "지연 (s)",
"鼠标键盘触发+等待稳定": "마우스 키보드 트리거 + 안정 대기 중"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "documentaire vertaling",
"文件": "bestand",
"最大结果条数": "Maximaal aantal resultaten",
"再次进行OCR": "OCR opnieuw uitvoeren"
"再次进行OCR": "OCR opnieuw uitvoeren",
"选取OCR范围后自动绑定窗口": "Venster automatisch binden na het selecteren van OCR-bereik",
"延迟(s)": "Vertraging (s)",
"鼠标键盘触发+等待稳定": "Muis en toetsenbord trigger+wachten op stabilisatie"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "tłumaczenie dokumentów",
"文件": "plik",
"最大结果条数": "Maksymalna liczba wyników",
"再次进行OCR": "Wykonaj ponownie OCR"
"再次进行OCR": "Wykonaj ponownie OCR",
"选取OCR范围后自动绑定窗口": "Automatycznie wiąże okno po wybraniu zakresu OCR",
"延迟(s)": "Opóźnienie (s)",
"鼠标键盘触发+等待稳定": "Wyzwalacz myszy i klawiatury+oczekiwanie na stabilizację"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "tradução documental",
"文件": "ficheiro",
"最大结果条数": "Número máximo de resultados",
"再次进行OCR": "Executar OCR novamente"
"再次进行OCR": "Executar OCR novamente",
"选取OCR范围后自动绑定窗口": "Vincular automaticamente a janela após selecionar o intervalo de OCR",
"延迟(s)": "Atraso (s)",
"鼠标键盘触发+等待稳定": "Mouse e teclado gatilho + aguardando estabilização"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "Перевод документов",
"文件": "Документация",
"最大结果条数": "Максимальное число итоговых полос",
"再次进行OCR": "Повторить OCR"
"再次进行OCR": "Повторить OCR",
"选取OCR范围后自动绑定窗口": "Выберите диапазон OCR и автоматически свяжите окно",
"延迟(s)": "Задержка (s)",
"鼠标键盘触发+等待稳定": "Запуск клавиатуры мыши + Ожидание стабилизации"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "dokumentär översättning",
"文件": "fil",
"最大结果条数": "Maximalt antal resultat",
"再次进行OCR": "Utför OCR igen"
"再次进行OCR": "Utför OCR igen",
"选取OCR范围后自动绑定窗口": "Bind automatiskt fönster efter markerat OCR-område",
"延迟(s)": "Försening (s)",
"鼠标键盘触发+等待稳定": "Mus och tangentbord trigger + väntar på stabilisering"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "แปลเอกสาร",
"文件": "แฟ้ม",
"最大结果条数": "จำนวนแถบผลลัพธ์สูงสุด",
"再次进行OCR": "OCR อีกครั้ง"
"再次进行OCR": "OCR อีกครั้ง",
"选取OCR范围后自动绑定窗口": "ผูกหน้าต่างโดยอัตโนมัติหลังจากเลือกช่วง OCR",
"延迟(s)": "ความล่าช้า (s)",
"鼠标键盘触发+等待稳定": "เมาส์คีย์บอร์ดทริกเกอร์ + รอความมั่นคง"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "belgeler çeviri",
"文件": "dosya",
"最大结果条数": "En yüksek sonuçların sayısı",
"再次进行OCR": "OCR tekrar yap"
"再次进行OCR": "OCR tekrar yap",
"选取OCR范围后自动绑定窗口": "OCR menzili seçmeden sonra pencereyi otomatik bağlayın",
"延迟(s)": "Geç",
"鼠标键盘触发+等待稳定": "Fare ve klavye tetikleyici+stabilizasyonu bekliyor"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "документарний переклад",
"文件": "файл",
"最大结果条数": "Максимальна кількість результатів",
"再次进行OCR": "Виконати OCR знову"
"再次进行OCR": "Виконати OCR знову",
"选取OCR范围后自动绑定窗口": "Автоматично зв’ язати вікно після вибору діапазону OCR",
"延迟(s)": "Затримка (с)",
"鼠标键盘触发+等待稳定": "Пуск миші і клавіатури+чекає на стабілізацію"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "Dịch tài liệu",
"文件": "Tài liệu",
"最大结果条数": "Số thanh kết quả tối đa",
"再次进行OCR": "OCR lần nữa"
"再次进行OCR": "OCR lần nữa",
"选取OCR范围后自动绑定窗口": "Tự động ràng buộc cửa sổ sau khi chọn phạm vi OCR",
"延迟(s)": "Độ trễ (s)",
"鼠标键盘触发+等待稳定": "Kích hoạt bàn phím chuột+chờ ổn định"
}

View File

@ -833,5 +833,8 @@
"文件翻译": "",
"文件": "",
"最大结果条数": "",
"再次进行OCR": ""
"再次进行OCR": "",
"选取OCR范围后自动绑定窗口": "",
"延迟(s)": "",
"鼠标键盘触发+等待稳定": ""
}

View File

@ -16,7 +16,7 @@ OCR的结果是不稳定的经常对于图片的微小扰动会使文本发
#### 1. 图像稳定性阈值
当游戏文本不是立即出现或者游戏有动态背景或live2d时截取的图片是会不停的发生变化的。
当游戏文本不是立即出现(文本速度不是最快)或者游戏有动态背景或live2d时截取的图片是会不停的发生变化的。
每次截图时,和上一次截图进行比较,计算相似度。当相似度大于阈值时,认为图片是处于稳定状态,进行下一步判断。
@ -37,4 +37,23 @@ OCR的结果是不稳定的经常对于图片的微小扰动会使文本发
### 分析图像更新+周期执行
结合上述两种方法当根据至少每“执行周期”的时间间隔都会执行一次OCR。且也会根据“分析图像更新”在间隔内进行OCR间隔内的OCR会重置间隔的计时。
结合上述两种方法当根据至少每“执行周期”的时间间隔都会执行一次OCR。且也会根据“分析图像更新”在间隔内进行OCR间隔内的OCR会重置间隔的计时。
### 鼠标键盘触发+等待稳定
以下鼠标键盘事件将触发该方法按下鼠标左键、按下Enter、松开Ctrl、松开Shift、松开Alt
触发该方法后,由于需要等待游戏渲染新的文本,或文本可能不是立即出现(文本速度不是最快),因此需要稍微等待一小段时间,直到显示的文本稳定。
如果文本速度是最快的则可以将两个参数都设置为0。否则判断需要等待的时间需要以下参数
#### 1. 延迟(s)
等待一个固定的延迟时间内置有0.1s的固有延迟时间,以满足游戏引擎的内部逻辑处理)。
#### 2. 图像稳定性阈值
这个值和上面的同名参数类似。不过这个仅用来判定文本是否绘制完毕,因此和上面的同名参数不共用配置。
由于慢速文本的绘制时间不固定,因此使用指定的固定延迟可能不能满足需要。当图像与上次截图相似度大于阈值时,执行本次触发事件。

View File

@ -28,7 +28,7 @@ set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_SOURCE_DIR}/version)
include(generate_product_version)
set(VERSION_MAJOR 5)
set(VERSION_MINOR 29)
set(VERSION_MINOR 30)
set(VERSION_PATCH 0)
add_library(pch pch.cpp)