You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让pyautogui.locateOnScreen在循环中实时更新识别结果?

问题:循环中PyAutoGUI图像识别始终返回首次结果

问题描述

我是编程新手(刚通过相关考试),首次发帖。我编写了一个程序,用于检测游戏中5个20面骰子的点数之和是否大于指定值(如95)。我使用pyautogui识别数字所在区域的匹配图像,将其转换为整数输出。手动单次运行程序时功能正常,但放入while循环后,始终保留屏幕上的第一个识别结果。我已尝试在循环内重置digit1和digit2,也调整过识别区域与置信度,但问题仍未解决。相关代码如下:

import time
import cv2
import pyautogui as aut

time.sleep(3)
roll = 0
while int(roll) <= 95:
    time.sleep(0.5)
    aut.click(872,807)
    digit1, digit2 = None, None

    for digit in range(10):
        region1 = aut.locateOnScreen('D:\Documents\OpenCV\images\%s.png' % digit, grayscale=True, confidence=0.8, region=(800, 720, 30, 50))
        region2 = aut.locateOnScreen('D:\Documents\OpenCV\images\%s.png' % digit, grayscale=True, confidence=0.8, region=(825, 720, 30, 50))

        if region1 is not None:
            digit1 = digit

        if region2 is not None:
            digit2 = digit

    roll = int("%s%s" % (digit1, digit2))
    print(roll)

问题原因及修复方案

1. 核心问题

  • 点击后等待时间过短,游戏还未刷新骰子点数就启动识别,读取的仍是旧画面。
  • locateOnScreen可能复用之前的屏幕缓存,未获取最新画面。
  • 数字识别循环未在找到匹配后终止,后续数字的误匹配可能覆盖正确结果。

2. 修复后的代码

import time
import pyautogui as aut

time.sleep(3)
roll = 0
# 定义数字图片路径模板,减少重复拼接
img_path_template = r'D:\Documents\OpenCV\images\%s.png'

while int(roll) <= 95:
    aut.click(872, 807)
    # 延长等待时间,确保游戏完成画面刷新(可根据实际游戏速度调整)
    time.sleep(2)
    
    digit1, digit2 = None, None
    # 主动获取当前屏幕截图,基于最新画面识别,避免缓存干扰
    screen = aut.screenshot()

    # 单独识别第一个数字
    for digit in range(10):
        img_path = img_path_template % digit
        region1 = aut.locateOnScreen(img_path, grayscale=True, confidence=0.8, 
                                     region=(800, 720, 30, 50), image=screen)
        if region1 is not None:
            digit1 = digit
            break  # 找到匹配后立即终止循环,避免后续覆盖
    
    # 单独识别第二个数字
    for digit in range(10):
        img_path = img_path_template % digit
        region2 = aut.locateOnScreen(img_path, grayscale=True, confidence=0.8, 
                                     region=(825, 720, 30, 50), image=screen)
        if region2 is not None:
            digit2 = digit
            break

    # 增加容错处理,避免识别失败导致程序崩溃
    if digit1 is not None and digit2 is not None:
        roll = int(f"{digit1}{digit2}")
        print(roll)
    else:
        print("识别失败,重试")
        roll = 0  # 重置roll,避免因识别失败终止循环

3. 关键修改说明

  • 延长等待时间:将点击后的等待从0.5秒调整为2秒(可按需修改),确保骰子点数完全更新。
  • 实时截图识别:通过aut.screenshot()获取最新屏幕画面,传递给locateOnScreen的image参数,强制使用当前画面识别。
  • 拆分识别循环:将两个数字的识别分开进行,找到匹配后立即break,避免互相干扰和结果覆盖。
  • 容错处理:识别失败时输出提示并重置roll,防止程序崩溃或提前终止循环。

内容的提问来源于stack exchange,提问作者DangerousBoo

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.10 20:25:23