lizoshan 发表于 2023-8-16 16:59

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()

xhtdtk 发表于 2023-8-16 17:51

可能每次F10启动生成一个子程序导致占用内存

wuming12365 发表于 2023-8-16 19:12

B站水哥有类似的项目

lizoshan 发表于 2023-8-16 20:20

xhtdtk 发表于 2023-8-16 17:51
可能每次F10启动生成一个子程序导致占用内存

启动程序运行的时候CPU很低,运行了一会点暂停CPU就会猛长上去{:1_908:}

sai609 发表于 2023-8-16 20:22

去掉遍历,增加多线程

tuoluo348 发表于 2023-8-16 22:27

继续提问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)`来提交任务。

lsy832 发表于 2023-8-17 00:03

调用大漠来实现简单快捷
页: [1]
查看完整版本: python大神帮我看看这个识图点击的代码要怎么优化,占用cpu太高了