python大神帮我看看这个识图点击的代码要怎么优化,占用cpu太高了
本帖最后由 lizoshan 于 2023-8-16 17:05 编辑用chatgpt写的,但是打包出来运行后占用很高的cpu,也不知道该怎么优化了,求助大神帮我看看
不知道需要哪段代码,下面是全部的代码大神们可以帮我看看
import cv2
import pyautogui
import numpy as np
import time
import os
import random
import threading
import tkinter as tk
from pynput import keyboard
import base64
# 图像数据的 Base64 编码
embedded_image_base64 = """
Base64 编码
"""
# 解码 Base64 编码的图像数据
image_data = base64.b64decode(embedded_image_base64)
# 保存解码后的图像数据为临时文件
image_path = os.path.join(os.path.dirname(os.path.abspath(__file__)), 'embedded_image.bmp')
with open(image_path, 'wb') as f:
f.write(image_data)
# 读取目标图像
target_image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
# 设置匹配阈值
threshold = 0.8# 修改为0.8
# 创建GUI窗口
root = tk.Tk()
root.title("自动点击")
root.geometry("300x160")# 调整窗口尺寸以容纳输入框
status_label = tk.Label(root, text="程序未运行", fg="black")# 设置前景颜色为黑色
status_label.pack(pady=10)
delay_frame = tk.Frame(root)
delay_frame.pack()
min_delay_frame = tk.Frame(delay_frame)
min_delay_frame.pack(pady=0)
min_delay_label = tk.Label(min_delay_frame, text="最小延迟(ms):")
min_delay_label.pack(side=tk.LEFT)
min_delay_entry = tk.Entry(min_delay_frame)
min_delay_entry.pack(side=tk.LEFT)
max_delay_frame = tk.Frame(delay_frame)
max_delay_frame.pack(pady=5)
max_delay_label = tk.Label(max_delay_frame, text="最大延迟(ms):")
max_delay_label.pack(side=tk.LEFT)
max_delay_entry = tk.Entry(max_delay_frame)
max_delay_entry.pack(side=tk.LEFT)
clicking = False# 标志是否在点击中
def start_clicking():
global clicking
clicking = True
status_label.config(text="程序运行中", fg="red")# 设置前景颜色为红色
click_thread = threading.Thread(target=click_loop)
click_thread.start()
def stop_clicking():
global clicking
clicking = False
status_label.config(text="程序已停止", fg="black")# 设置前景颜色为黑色
def on_key_release(key):
if key == keyboard.Key.f10:
start_clicking()
elif key == keyboard.Key.f12:
stop_clicking()
def click_loop():
global clicking
while True:
if clicking:
# 进行桌面截图
desktop_screenshot = pyautogui.screenshot()
# 将截图和目标图像转换为灰度图像
desktop_gray = cv2.cvtColor(np.array(desktop_screenshot), cv2.COLOR_RGB2GRAY)
# 在截图中寻找目标图像
result = cv2.matchTemplate(desktop_gray, target_image, cv2.TM_CCOEFF_NORMED)
locations = np.where(result >= threshold)
locations = list(zip(*locations[::-1]))# 转换为(x, y)坐标
# 遍历所有找到的匹配位置
for loc in locations:
if not clicking:
break
intX, intY = loc
# 计算点击位置
click_x = intX + 4
click_y = intY + 2
# 获取最小和最大延迟时间
min_delay = float(min_delay_entry.get()) if min_delay_entry.get() else 400
max_delay = float(max_delay_entry.get()) if max_delay_entry.get() else 600
# 随机生成延迟时间(毫秒)
delay = random.uniform(min_delay, max_delay) / 1000
# 移动鼠标到点击位置
pyautogui.moveTo(click_x, click_y)
# 输出点击位置和延迟时间
print(f"点击位置:({click_x}, {click_y}),延迟:{int(delay * 1000)}毫秒")
# 等待随机延迟时间
time.sleep(delay)
# 执行鼠标点击
pyautogui.click()
break# 退出循环
# 等待一段时间再继续查找
time.sleep(1)
# 增加并排的启动和停止按钮
button_frame = tk.Frame(root)
button_frame.pack(pady=15)
start_button = tk.Button(button_frame, text="启动", command=start_clicking)
start_button.pack(side=tk.LEFT, padx=30)
stop_button = tk.Button(button_frame, text="停止", command=stop_clicking)
stop_button.pack(side=tk.LEFT, padx=30)
root.bind('<F10>', lambda event: start_clicking())
root.bind('<F12>', lambda event: stop_clicking())
listener = keyboard.Listener(on_release=on_key_release)
listener.start()
root.mainloop() 可能每次F10启动生成一个子程序导致占用内存 B站水哥有类似的项目 xhtdtk 发表于 2023-8-16 17:51
可能每次F10启动生成一个子程序导致占用内存
启动程序运行的时候CPU很低,运行了一会点暂停CPU就会猛长上去{:1_908:} 去掉遍历,增加多线程 继续提问gpt,使用线程池来操作,然后在stop_clicking()函数里加入关闭所有线程的操作,当cpu占用高的时候尝试关闭所有线程。
以下是我提问的例子
要一次性关闭所有启动的线程,可以使用线程池来管理线程,并在`stop_clicking()`函数中关闭线程池。
首先,导入`concurrent.futures`模块:
```python
import concurrent.futures
```
然后,创建一个`concurrent.futures.ThreadPoolExecutor`对象并命名为`executor`:
```python
executor = concurrent.futures.ThreadPoolExecutor()
```
接下来,在点击循环的部分,将点击任务提交给线程池执行:
```python
executor.submit(click_task)
```
这样,每次循环将会启动一个新的线程执行点击任务。
为了确保所有线程都能被关闭,需要在`stop_clicking()`函数中调用`executor.shutdown()`来关闭线程池。修改后的`stop_clicking()`函数如下所示:
```python
def stop_clicking():
global clicking
clicking = False
status_label.config(text="程序已停止", fg="black")# 设置前景颜色为黑色
executor.shutdown()
```
这样做可以在`stop_clicking()`函数中关闭线程池,从而停止所有启动的线程。请确保在修改代码时,将点击任务封装为一个单独的函数`click_task()`,并在点击循环中使用`executor.submit(click_task)`来提交任务。 调用大漠来实现简单快捷
页:
[1]