使用Pytesseract识别游戏截图数字遇阻:数字7被误判为1求助
解决Pytesseract识别游戏数字7误判为1的问题
我之前也碰到过类似的游戏数字识别坑——自定义游戏字体的7和1因为轮廓太像,很容易被Tesseract搞混。结合你的代码和描述,给你几个针对性的调整方案,应该能解决问题:
一、优化Tesseract的识别配置
你的现有配置已经用了字符白名单,但可以针对游戏字体调整PSM(页面分割模式)和OEM(引擎模式),同时增加字符高度的限制,让Tesseract更关注7的独特轮廓:
# 修改后的配置:用LSTM引擎(更适合非标准字体)、单文本行模式,增加最小字符高度限制 custom_config = r'--dpi 300 --psm 7 --oem 1 -c tessedit_char_whitelist=0123456789 -c textord_min_xheight=30'
--oem 1:强制使用LSTM神经网络引擎,比默认的混合引擎更擅长识别自定义字体--psm 7:告诉Tesseract输入是单一行文本,减少分割错误textord_min_xheight=30:根据你缩放后的图像调整,过滤掉高度不够的干扰像素,突出数字的完整轮廓
二、调整图像预处理步骤
你的预处理已经做了不少工作,但过度腐蚀和硬编码的像素调整可能让7的横杠被磨掉,变成1的样子。试试这些修改:
# 1. 灰度加载保留原图像细节 img = cv2.imread("price.png", cv2.IMREAD_GRAYSCALE) # 2. 替换硬编码像素调整为自适应阈值(更适合游戏截图的不均匀色彩) # 先缩放5-7倍(过度缩放会让字符变形) scaled = cv2.resize(img, (0,0), fx=7, fy=7, interpolation = cv2.INTER_LINEAR) # 自适应高斯阈值处理,自动区分数字和背景 thresh = cv2.adaptiveThreshold(scaled, 255, cv2.ADAPTIVE_THRESH_GAUSSIAN_C, cv2.THRESH_BINARY_INV, 11, 2) # 3. 用更小的核做轻度腐蚀,保留7的横杠 kernel = numpy.ones((3,3), numpy.uint8) eroded = cv2.erode(thresh, kernel, iterations = 1) pre_processed = eroded
- 放弃硬编码的
img[img <=150] =231,改用自适应阈值能更好适配不同游戏的数字色彩 - 缩小腐蚀核并减少迭代次数,避免7的顶部横杠被腐蚀消失
- 用
INTER_LINEAR插值缩放,比INTER_CUBIC更不容易让字符边缘模糊
三、终极方案:模板匹配兜底
如果Tesseract还是搞不定游戏的自定义字体,可以用OpenCV的模板匹配直接定位数字7,彻底避免误判:
# 提前截取游戏中数字7的清晰截图作为模板(预处理后的样式) template = cv2.imread('template_7.png', cv2.IMREAD_GRAYSCALE) w, h = template.shape[::-1] # 在预处理后的图像中查找匹配 res = cv2.matchTemplate(pre_processed, template, cv2.TM_CCOEFF_NORMED) threshold = 0.8 # 匹配阈值,根据实际情况调整 loc = numpy.where(res >= threshold) # 如果找到匹配,说明图像中有7,直接修正识别结果 output = pytesseract.image_to_string(pre_processed, config=custom_config) for _ in zip(*loc[::-1]): output = output.replace('1', '7') # 把误判的1替换成7 print(output)
这个方法的核心是用游戏里的真实数字7做模板,直接匹配定位,完全不受Tesseract字体训练库的限制。
四、额外小技巧
- 检查预处理后的
result.png,确保数字7的顶部横杠清晰可见——如果横杠已经消失,说明腐蚀或缩放步骤有问题,需要调整参数 - 如果游戏窗口可以调整分辨率,尽量用更高分辨率截图,原始图像越清晰,预处理和识别的准确率越高
内容的提问来源于stack exchange,提问作者Blainexi
相关产品推荐
相关产品推荐

