Какие методы можно использовать для ускорения процесса сканирования в Python?

У меня есть код, созданный в 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}'")
```
Как можно оптимизировать сканирование, чтобы улучшить скорость работы скрипта?
  • 27 января 2025 г. 18:54
Ответы на вопрос 3
Оптимизация вашего скрипта может быть достигнута несколькими способами. Рассмотрим несколько методов, которые помогут ускорить процесс сканирования:

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&amp;newwindow=1&amp;sca_esv=ff46edf509a95d92&amp;sxsrf=AHTn8zpMgC7K80pp55HYDIFYiTVWu7Levw%3A1738047898364&amp;ei=moGYZ4r8Fdy5i-gPtYqlmA0&amp;ved=0ahUKEwiKsdb87JeLAxXc3AIHHTVFCdMQ4dUDCBA&amp;uact=5&amp;oq=best+python+Profiling+2024&amp;gs_lp=Egxnd3Mtd2l6LXNlcnAiGmJlc3QgcHl0aG9uIFByb2ZpbGluZyAyMDI0MggQIRigARjDBDIIECEYoAEYwwRI7qMXUJmdF1iZnRdwBHgBkAEAmAH-AqAB_gKqAQMzLTG4AQPIAQD4AQL4AQGYAgWgAo4DwgIKEAAYsAMY1gQYR5gDAIgGAZAGCJIHBTQuMy0xoAf3Ag&amp;sclient=gws-wiz-serp" rel="nofollow">профилировщик</a> в зубы и бегом искать узкие места самостоятельно.
<blockquote>5 секунд</blockquote> 5 секунд для Python - это скорость света. Ничего не поделаешь
Похожие вопросы