使用pytesseract识别游戏截图文本遇异常问题求助
游戏HP截图数字识别问题解决思路
问题现状
- 识别含数字11275的截图时,结果不稳定:有时能正确识别完整数字,有时仅识别出末尾三位275
- 另一张截图的数字完全无法识别
- 当前使用的代码如下:
for count_check_hp in range(0,3): screenshot = ImageGrab.grab(bbox=(580, 554, 640, 577)) screenshot_cv = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR) preprocessed_image = cv2.cvtColor(screenshot_cv, cv2.COLOR_BGR2GRAY) screenshot.close() extracted_text = pytesseract.image_to_string(preprocessed_image, lang='eng') QtTest.QTest.qWait(300) if len(extracted_text) > 0: break try: value_hp = extracted_text.replace("\n", "") number_hp = re.findall(r'\d+', value_hp) number = int(''.join(number_hp)) if len(number) > 0: return number else: return 99999 except Exception as error_get_hp: print(f'check hp error: {error_get_hp}') return 99999
核心优化方案
1. 强化图像预处理
游戏截图的背景干扰、字体过小是识别失败的主要原因,需增加以下步骤:
- 二值化:将图像转为黑白高对比度格式,彻底分离数字与背景
- 降噪:清除截图中的微小噪点,避免干扰识别
- 放大:将图像放大1-2倍,提升Tesseract对小字体的识别精度
示例预处理代码:
# 转灰度后执行以下步骤 gray = cv2.cvtColor(screenshot_cv, cv2.COLOR_BGR2GRAY) # 二值化(阈值根据截图实际调整,这里150为示例) _, binary_img = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY_INV) # 降噪 kernel = np.ones((1,1), np.uint8) clean_img = cv2.morphologyEx(binary_img, cv2.MORPH_OPEN, kernel) # 放大2倍 scaled_img = cv2.resize(clean_img, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC)
2. 定制Tesseract识别规则
针对数字识别场景,限定识别范围并优化参数:
# 仅识别数字,指定文本块模式 extracted_text = pytesseract.image_to_string( scaled_img, lang='eng', config='--psm 6 --oem 3 -c tessedit_char_whitelist=0123456789' )
--psm 6:告知Tesseract图像为单一文本块,适合固定位置的HP数字tessedit_char_whitelist:只允许识别0-9,过滤无关字符干扰
3. 修复代码逻辑错误
原代码中len(number) > 0是错误的(number为整数,无法用len()),改为检查数字列表是否非空:
number_hp = re.findall(r'\d+', value_hp) if number_hp: number = int(''.join(number_hp)) return number else: return 99999
4. 增加结果验证机制
多次截图后筛选符合预期长度的结果(比如HP是5位数,就只保留长度为5的识别结果),提升稳定性:
expected_length = 5 # 根据游戏实际HP位数设置 valid_results = [] # 在循环中添加: if extracted_text: number_str = ''.join(re.findall(r'\d+', extracted_text)) if len(number_str) == expected_length: valid_results.append(int(number_str)) # 最终取有效结果中出现次数最多的 if valid_results: return max(set(valid_results), key=valid_results.count)
完整优化代码
import cv2 import numpy as np from PIL import ImageGrab import pytesseract import re from PyQt5.QtTest import QtTest def get_hp(): expected_hp_length = 5 valid_results = [] for _ in range(3): # 截图 screenshot = ImageGrab.grab(bbox=(580, 554, 640, 577)) screenshot_cv = cv2.cvtColor(np.array(screenshot), cv2.COLOR_RGB2BGR) screenshot.close() # 预处理 gray = cv2.cvtColor(screenshot_cv, cv2.COLOR_BGR2GRAY) _, binary = cv2.threshold(gray, 150, 255, cv2.THRESH_BINARY_INV) cleaned = cv2.morphologyEx(binary, cv2.MORPH_OPEN, np.ones((1,1), np.uint8)) scaled = cv2.resize(cleaned, None, fx=2, fy=2, interpolation=cv2.INTER_CUBIC) # 识别 text = pytesseract.image_to_string( scaled, lang='eng', config='--psm 6 --oem 3 -c tessedit_char_whitelist=0123456789' ).strip().replace("\n", "") # 验证结果 if text and len(text) == expected_hp_length: valid_results.append(int(text)) break # 拿到有效结果直接退出循环 QtTest.QTest.qWait(300) try: return valid_results[0] if valid_results else 99999 except Exception as e: print(f'check hp error: {e}') return 99999
内容的提问来源于stack exchange,提问作者Master-Event
相关产品推荐
相关产品推荐

