修复: OCR 图像预处理 2x 放大+锐化+对比度 + 增强 normalize 纠错

1. 图像预处理(截图保存后、OCR 前):
   - 2x LANCZOS 放大:Windows OCR 对高 DPI 输入识别更好
   - 锐化 1.8x + 对比度 1.4x:字符边缘更清晰,减少 CJK 空格/字符混淆
   预期:减少《→<错误、减少 CJK 间空格残留、减少字符分裂(什→亻牛)

2. 增强 _normalize_ocr_text:
   - 《》→ <> 修复:Minecraft 聊天 <player> 被 OCR 误读为中文书名号
   - l→| 管道分隔符修复:|quiz| 误读为 lquizl,使用 (?<=\s)l(...)l(?=\s) 模式
   - .→ . 全角点→半角数字小数点(0.45 → 0.45)
   这些修复只在非 md 文本上运行(md 被 pre-split check 提前过滤)
This commit is contained in:
youpaishidifu
2026-07-26 21:55:55 +08:00
parent 5d0cedcab4
commit 20cdeeb15c
+27 -1
View File
@@ -17,7 +17,7 @@ import difflib
import os
from datetime import datetime
import signal
from PIL import ImageGrab
from PIL import ImageGrab, ImageEnhance, ImageFilter
from winrt.windows.media.ocr import OcrEngine
from winrt.windows.globalization import Language
from winrt.windows.graphics.imaging import SoftwareBitmap, BitmapPixelFormat
@@ -523,6 +523,9 @@ class MessageMonitor:
"问 题 1 : 你 答 : 你 好" → "问题1:你答:你好"
"你 好 he llo" → "你好 he llo"(ASCII 词内空格保留)
此外修复常见 Windows OCR 字符混淆错误(只在非 md 文本上运行,
md 文档由 pre-split check 提前过滤,不受影响)。
"""
# 所有紧邻 CJK/全角字符的空格全部去掉
# CJK 范围:汉字 (u4e00-) + 扩展 (u3400-) + 全角/兼容 (uff00-)
@@ -536,6 +539,17 @@ class MessageMonitor:
r'(?=[\u4e00-\u9fff\u3400-\u4dbf\uff00-\uffef\u3000-\u303f])',
'', text
)
# ⭐ Windows OCR 字符混淆修复
# 《》→ <>:Minecraft 聊天大量使用 <player> 等尖括号,OCR 误读为中文书名号
text = text.replace('《', '<').replace('》', '>')
# l→| 管道分隔符:|quiz| / |start| / |info| 误读为 lquizl / lstartl / linfol
text = re.sub(r'(?<=\s)l([A-Za-z]\w*?)l(?=\s)', r'|\1|', text)
# .→ . 全角点→半角数字小数点 (0.45 → 0.45)
text = re.sub(r'(\d)[.](\d)', r'\1.\2', text)
return text.strip()
@staticmethod
@@ -697,6 +711,18 @@ class MessageMonitor:
_clean_old_ocr_debug(script_dir, keep=20)
except Exception as e:
logger.debug(f"[ocr] 保存截屏失败: {e}")
# 图像预处理:提升 Windows OCR 识别准确率
# Windows OCR 对低 DPI/未处理截图识别差——CJK 空格、字符混淆
# 2x LANCZOS 放大 + 锐化 + 对比度增强
try:
im = im.resize((im.width * 2, im.height * 2), Image.LANCZOS)
im = ImageEnhance.Sharpness(im).enhance(1.8)
im = ImageEnhance.Contrast(im).enhance(1.4)
logger.debug(f"[ocr] 预处理: resize 2x + sharpen(1.8) + contrast(1.4)")
except Exception as e:
logger.debug(f"[ocr] 预处理失败(跳过): {e}")
if im.mode != 'RGBA':
im = im.convert('RGBA')
sb = SoftwareBitmap(BitmapPixelFormat.RGBA8, im.width, im.height)