У меня есть код, созданный в ChatGPT, который, кажется, работает, но очень медленно: время сканирования может достигать от 3 до 5 секунд. Суть скрипта заключается в том, что он должен постоянно нажимать определённую клавишу, и если при этом клавиша подсвечивается оранжевым, то её нужно удерживать в течение одной секунды. Вот сам код: <br/>
```python
import keyboard
import time
import numpy as np
import mss
import cv2
# Определяем пороговые значения цветового диапазона для оранжевого
ORANGE_LOWER = np.array([255, 160, 1]) # Минимальные значения в BGR
ORANGE_UPPER = np.array([255, 180, 3]) # Максимальные значения в BGR
# Клавиши для поочередного нажатия
keys = ['s', 'w', 'q', 'r', 'b', 'h', 'e', 'd', 'shift', 'space', 'up', 'left', 'down', 'right']
current_key_index = 0
# Функция для захвата экрана и проверки наличия оранжевого цвета
def check_orange_color():
with mss.mss() as sct:
monitor = {"top": 0, "left": 0, "width": 800, "height": 600}
img = sct.grab(monitor)
img_np = np.array(img)
img_np = cv2.cvtColor(img_np, cv2.COLOR_BGRA2BGR)
hsv_image = cv2.cvtColor(img_np, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_image, ORANGE_LOWER, ORANGE_UPPER)
return cv2.countNonZero(mask) > 0
def main():
global current_key_index
while True:
current_key = keys[current_key_index]
# Нажимаем клавишу
keyboard.press(current_key)
print(f"Зажата клавиша: {current_key}")
# Проверка на наличие оранжевого цвета
while True:
if check_orange_color():
print(f"Оранжевый цвет обнаружен! Продолжаем зажимать '{current_key}'")
```
Как можно оптимизировать сканирование, чтобы улучшить скорость работы скрипта?
Оптимизация вашего скрипта может быть достигнута несколькими способами. Рассмотрим несколько методов, которые помогут ускорить процесс сканирования:
1. **Уменьшение разрешения захвата**: Если ваш монитор имеет высокое разрешение, это может сильно замедлять процесс. Попробуйте уменьшить размер области захвата экрана.
2. **Увеличение интервалов между сканированиями**: Если тратить слишком много времени на проверки, можно добавить небольшой интервал между ними. Это не увеличит скорость, но позволит избежать перегрузки процессора и может немного ускорить выполнение остальных задач.
3. **Оптимизация цветового диапазона**: Убедитесь, что значения `ORANGE_LOWER` и `ORANGE_UPPER` точно соответствуют требуемым параметрам. Используйте более точные значения, чтобы уменьшить время обработки маски. А также также рассмотрите возможность предварительного выбора области, где вы ожидаете найти оранжевый цвет, чтобы не обрабатывать лишние пиксели.
4. **Параллельные вычисления**: Если вы используете несколько потоков, вы можете выделить один поток для захвата экрана и один для обработки. Для этого используйте библиотеку `threading` или `concurrent.futures`.
5. **Контроль частоты**: Увеличьте время между проверками состояния клавиши, например, используя `time.sleep()` на короткое время (например, 0.1 сек) для ограничения частоты вызова функции проверки цвета.
Пример оптимизированного кода с обработкой в отдельном потоке:
```python
import keyboard
import time
import numpy as np
import mss
import cv2
import threading
# Определяем пороговые значения цветового диапазона для оранжевого
ORANGE_LOWER = np.array([5, 100, 100]) # Значения для HSV
ORANGE_UPPER = np.array([15, 255, 255])
# Клавиши для поочередного нажатия
keys = ['s', 'w', 'q', 'r', 'b', 'h', 'e', 'd', 'shift', 'space', 'up', 'left', 'down', 'right']
current_key_index = 0
keep_pressing = False
def check_orange_color():
with mss.mss() as sct:
monitor = {"top": 0, "left": 0, "width": 800, "height": 600}
img = sct.grab(monitor)
img_np = np.array(img)
img_np = cv2.cvtColor(img_np, cv2.COLOR_BGRA2BGR)
hsv_image = cv2.cvtColor(img_np, cv2.COLOR_BGR2HSV)
mask = cv2.inRange(hsv_image, ORANGE_LOWER, ORANGE_UPPER)
return cv2.countNonZero(mask) > 0
def color_detection_thread():
global keep_pressing
while True:
if keep_pressing:
if check_orange_color():
print(f"Оранжевый цвет обнаружен! Зажимаем клавишу '{keys[current_key_index]}' в течение одной секунды.")
time.sleep(1) # Удерживаем клавишу в течение 1 секунды
def main():
global current_key_index, keep_pressing
threading.Thread(target=color_detection_thread, daemon=True).start()
while True:
current_key = keys[current_key_index]
keyboard.press(current_key)
print(f"Зажата клавиша: {current_key}")
keep_pressing = True
time.sleep(0.1) # Задержка для контроля частоты
keyboard.release(current_key)
keep_pressing = False
# Переход к следующей клавише
current_key_index = (current_key_index + 1) % len(keys)
if __name__ == "__main__":
main()
```
Эти изменения помогут ускорить процесс работы скрипта и сделают его более отзывчивым. Не забудьте протестировать его в вашем окружении и настроить параметры по мере необходимости.
Как варианты: <br/> 1. Обязательно ли искать оранжевый индикатор во всей области изображения, а не в одном ожидаемом месте? <br/> 2. <code>mss.mss()</code> - обязательно ли каждую итерацию захватывать экран заново? <br/> 3. Преобразование в hsv точно нужно? <br/> 4. <code>time.sleep(0.05) # Проверяем цвет каждые 100 мс</code> - что то не клеится в Ваших показаниях, на основание чего указано 50мс? <br/> <br/> Короче, <a href="https://www.google.com/search?q=best+python+Profiling+2024&newwindow=1&sca_esv=ff46edf509a95d92&sxsrf=AHTn8zpMgC7K80pp55HYDIFYiTVWu7Levw%3A1738047898364&ei=moGYZ4r8Fdy5i-gPtYqlmA0&ved=0ahUKEwiKsdb87JeLAxXc3AIHHTVFCdMQ4dUDCBA&uact=5&oq=best+python+Profiling+2024&gs_lp=Egxnd3Mtd2l6LXNlcnAiGmJlc3QgcHl0aG9uIFByb2ZpbGluZyAyMDI0MggQIRigARjDBDIIECEYoAEYwwRI7qMXUJmdF1iZnRdwBHgBkAEAmAH-AqAB_gKqAQMzLTG4AQPIAQD4AQL4AQGYAgWgAo4DwgIKEAAYsAMY1gQYR5gDAIgGAZAGCJIHBTQuMy0xoAf3Ag&sclient=gws-wiz-serp" rel="nofollow">профилировщик</a> в зубы и бегом искать узкие места самостоятельно.
<blockquote>5 секунд</blockquote> 5 секунд для Python - это скорость света. Ничего не поделаешь