fix: 降低OCR预处理锐化/对比度,增强偏旁碎片检测

This commit is contained in:
youpaishidifu
2026-07-31 12:45:48 +08:00
parent b065f8d707
commit 435f729589
+41 -9
View File
@@ -1376,12 +1376,13 @@ class MessageMonitor:
# 图像预处理:提升 Windows OCR 识别准确率
# Windows OCR 对低 DPI/未处理截图识别差——CJK 空格、字符混淆
# 2x LANCZOS 放大 + 锐化 + 对比度增强
# ⚠️ 锐化/对比度过高会导致汉字边缘断裂成偏旁部首
im_original = im # 保留原图,bad allocation 时降级
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)")
im = ImageEnhance.Sharpness(im).enhance(1.2) # 降低锐化,防字符断裂
im = ImageEnhance.Contrast(im).enhance(1.2) # 降低对比度,保持笔画连贯
logger.debug(f"[ocr] 预处理: resize 2x + sharpen(1.2) + contrast(1.2)")
except Exception as e:
logger.debug(f"[ocr] 预处理失败(跳过): {e}")
@@ -1485,11 +1486,12 @@ class MessageMonitor:
self._ocr_unchanged.pop("wechat", None)
# 图像预处理(同 QQ)
# ⚠️ 锐化/对比度过高会导致汉字边缘断裂成偏旁部首
im_original = im # 保留原图,bad allocation 时降级
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)
im = ImageEnhance.Sharpness(im).enhance(1.2) # 降低锐化,防字符断裂
im = ImageEnhance.Contrast(im).enhance(1.2) # 降低对比度,保持笔画连贯
except Exception as e:
logger.debug(f"[wechat] OCR 预处理失败(跳过): {e}")
@@ -1976,10 +1978,25 @@ class MessageMonitor:
# —— OCR 偏旁碎片过滤:氵、亻、讠、扌等 CJK 偏旁不是完整汉字 ——
# 从 unicode_radicals.md 加载偏旁字符集,统计出现次数
# ≥1 个偏旁字符 → 判定为 OCR 把汉字拆碎了,整段丢弃
# ⚠️ 增强:连续偏旁检测(如"亻乍弊")—— 偏旁数≥2 且文本短(<20字)时更严格
radical_cnt = sum(1 for c in line if c in _RADICAL_CHARS)
if radical_cnt >= 1:
logger.debug(f"[{platform}] OCR 过滤: 偏旁碎片(radical={radical_cnt}) line={line!r}")
continue
# 计算非空格文本长度
text_len = len(line.replace(' ', ''))
# 短文本(<20字)出现偏旁 → 高概率碎片
if text_len < 20:
logger.debug(f"[{platform}] OCR 过滤: 偏旁碎片(短文本radical={radical_cnt},len={text_len}) line={line!r}")
continue
# 长文本但偏旁比例高(>10%)→ 碎片
elif text_len > 0 and radical_cnt / text_len > 0.1:
logger.debug(f"[{platform}] OCR 过滤: 偏旁碎片(比例{radical_cnt}/{text_len}) line={line!r}")
continue
# 单个偏旁但文本很长(>50字)→ 可能是正常文本包含偏旁字符(罕见),放行
elif radical_cnt == 1 and text_len > 50:
pass # 放行
else:
logger.debug(f"[{platform}] OCR 过滤: 偏旁碎片(radical={radical_cnt}) line={line!r}")
continue
# —— 系统配置内容过滤:SMTP/邮件地址/代码片段不是用户消息 ——
if re.search(r'@example|smtp|\.py\b|\.bat\b|\.sh\b|//.*\.\w{2,4}\b', line, re.IGNORECASE):
logger.debug(f"[{platform}] OCR 过滤: 系统配置内容 line={line!r}")
@@ -3659,10 +3676,25 @@ class MessageMonitor:
# === 偏旁碎片过滤:氵、亻、讠、扌等 CJK 偏旁不是完整汉字 ===
# 从 unicode_radicals.md 加载偏旁字符集,统计出现次数
# ≥1 个偏旁字符 → 判定为 OCR 把汉字拆碎了,整段丢弃
# ⚠️ 增强:连续偏旁检测(如"亻乍弊")—— 偏旁数≥2 且文本短(<20字)时更严格
radical_cnt = sum(1 for c in ts if c in _RADICAL_CHARS)
if radical_cnt >= 1:
logger.debug(f"[{platform}] Poll过滤: 偏旁碎片(radical={radical_cnt}) ts={ts!r}")
continue
# 计算非空格文本长度
text_len = len(ts.replace(' ', ''))
# 短文本(<20字)出现偏旁 → 高概率碎片
if text_len < 20:
logger.debug(f"[{platform}] Poll过滤: 偏旁碎片(短文本radical={radical_cnt},len={text_len}) ts={ts!r}")
continue
# 长文本但偏旁比例高(>10%)→ 碎片
elif text_len > 0 and radical_cnt / text_len > 0.1:
logger.debug(f"[{platform}] Poll过滤: 偏旁碎片(比例{radical_cnt}/{text_len}) ts={ts!r}")
continue
# 单个偏旁但文本很长(>50字)→ 可能是正常文本包含偏旁字符(罕见),放行
elif radical_cnt == 1 and text_len > 50:
pass # 放行
else:
logger.debug(f"[{platform}] Poll过滤: 偏旁碎片(radical={radical_cnt}) ts={ts!r}")
continue
# === 系统配置内容过滤:SMTP/邮件地址/代码片段不是用户消息 ===
if re.search(r'@example|smtp|\.py\b|\.bat\b|\.sh\b|//.*\.\w{2,4}\b', ts, re.IGNORECASE):
logger.debug(f"[{platform}] Poll过滤: 系统配置内容 ts={ts!r}")