我正在编写一个小脚本来自动执行游戏中一项烦人的任务。为此,我需要比较屏幕截图。当我使用 LocateCenterOnScreen 时,它工作得很好,除了它只找到第一次出现的情况。但我想要所有的出现,所以我将其更改为locateAllOnScreen。但是当我这样做时,屏幕上没有任何内容,它会抛出 ImageNotFoundException 并告诉我降低置信度(没有匹配项,我手动检查,所以降低置信度不是我想要的)
我可以以某种方式捕获异常以保持其运行吗?
错误信息:
Exception in thread Thread-1:
Traceback (most recent call last):
File "C:\Users\name\AppData\Local\Programs\Python\Python39\lib\threading.py", line 980, in _bootstrap_inner
self.run()
File "C:\Users\name\AppData\Local\Programs\Python\Python39\lib\threading.py", line 917, in run
self._target(*self._args, **self._kwargs)
File "C:\Users\name\PycharmProjects\LeafBlowerTrade\main.py", line 31, in start
for pos in locs:
File "C:\Users\name\PycharmProjects\LeafBlowerTrade\venv\lib\site-packages\pyscreeze\__init__.py", line 257, in _locateAll_opencv
raise ImageNotFoundException('Could not locate the image (highest confidence = %.3f)' % result.max())
pyscreeze.ImageNotFoundException: Could not locate the image (highest confidence = 0.550)
这是我在代码中尝试的,但它不起作用。当我使用locateCenterOnScreen 时,完全相同的代码有效。
try:
locs = locateAllOnScreen(icon, confidence=0.6)
except ImageNotFoundException:
pass
整个代码是:
from pyautogui import *
import time
import threading
from pynput.mouse import Controller, Button
from pynput.keyboard import Listener, KeyCode
TOGGLE_KEY = KeyCode(char="p")
running = False
mouse = Controller()
def toggle_event(key):
if key == TOGGLE_KEY:
global running
running = not running
print(position())
def start():
icon = 'Gem.png'
while True:
if running:
locs = []
try:
locs = locateAllOnScreen(icon, confidence=0.6)
except ImageNotFoundException:
pass
for pos in locs:
x = pos[0] + int(pos[2] / 2)
y = pos[1] + int(pos[3] / 2)
moveTo(x + 768, y)
mouse.press(Button.left)
time.sleep(0.02)
mouse.release(Button.left)
moveTo(1557, 1124)
mouse.press(Button.left)
time.sleep(0.02)
mouse.release(Button.left)
moveTo(606, 1126)
mouse.press(Button.left)
time.sleep(0.02)
mouse.release(Button.left)
moveTo(2008, 1123)
mouse.press(Button.left)
time.sleep(0.02)
mouse.release(Button.left)
time.sleep(0.1)
run_thread = threading.Thread(target=start)
run_thread.start()
with Listener(on_press=toggle_event) as listener:
listener.join()
locateCenterOnScreen 的工作代码是:
from pyautogui import *
import time
import threading
from pynput.mouse import Controller, Button
from pynput.keyboard import Listener, KeyCode
TOGGLE_KEY = KeyCode(char="p")
running = False
mouse = Controller()
def toggle_event(key):
if key == TOGGLE_KEY:
global running
running = not running
print(position())
def start():
icon = 'Gem.png'
while True:
if running:
try:
position = locateCenterOnScreen(icon, confidence=0.7)
x, y = position
moveTo(x+768, y)
mouse.press(Button.left)
time.sleep(0.02)
mouse.release(Button.left)
moveTo(1557, 1124)
mouse.press(Button.left)
time.sleep(0.02)
mouse.release(Button.left)
moveTo(606, 1126)
mouse.press(Button.left)
time.sleep(0.02)
mouse.release(Button.left)
except ImageNotFoundException:
moveTo(606, 1126)
mouse.press(Button.left)
time.sleep(0.02)
mouse.release(Button.left)
moveTo(2008, 1123)
mouse.press(Button.left)
time.sleep(0.02)
mouse.release(Button.left)
time.sleep(0.1)
run_thread = threading.Thread(target=start)
run_thread.start()
with Listener(on_press=toggle_event) as listener:
listener.join()
首先,尝试做
try:
locs = locateAllOnScreen(icon, confidence=0.6)
except pyscreeze.ImageNotFoundException:
pass
有时,准确指定要避免的异常可以帮助解决问题。
解决问题的另一种方法是使用
locateCenterOnScreen
并创建一个覆盖该区域的新图像。您可以通过使用 cv2.rectangle method
并在循环中提供新图像来实现此目的。这是一种更复杂的方法,并且认为没有必要。
使用
locateCenterOnScreen
时的第二种解决方案是以网格样式检查屏幕。例如:
def start():
icon = 'Gem.png'
# Replace img_x and img_y with Gem.png’s x and y.
# The first region will be [0,0,img_x,img_y].
reg = (0,0,img_x,img_y)
while True:
if running:
try:
position = locateCenterOnScreen(icon, region=reg, confidence=0.7)
x, y = position
# rest of your code here
change_reg = list(reg)
change_reg[0], change_reg[2] = int(change_reg[0]) + img_x, int(change_reg[2]) + img_x
reg = tuple(change_reg)
except ImageNotFoundException:
# rest of your code
change_reg = list(reg)
change_reg[0], change_reg[2] = int(change_reg[0]) + img_x, int(change_reg[2]) + img_x
reg = tuple(change_reg)
这不是确切的代码,但比较接近;一旦超出屏幕,您就必须对其进行修改才能更改 y 值。
我目前没有计算机来尝试这些,因此它们可能无法按预期工作或根本无法工作。对不起!