Как сделать скриншот одного монитора с помощью OpenCV?

Я пытаюсь разработать устройство, которое меняет светодиодные полосы RGB в соответствии с цветом моего дисплея. Для этого я планирую сделать снимок экрана, нормализуя/взяв среднее значение цветов отдельных пикселей на дисплее. Я понял, как сделать снимок экрана с одним монитором, но хочу, чтобы он работал с настройкой с несколькими мониторами. Вот мой основной код. Любая помощь будет принята с благодарностью.

import numpy as np
import cv2
import pyautogui
   
  
# take screenshot using pyautogui
image = pyautogui.screenshot()
   
# since the pyautogui takes as a 
# PIL(pillow) and in RGB we need to 
# convert it to numpy array and BGR 
# so we can write it to the disk
image = cv2.cvtColor(np.array(image),
                     cv2.COLOR_RGB2BGR)

Я пробовал это с помощью модуля mss, но он не работает. У него проблема, когда дополнительный дисплей просто обрезает финальное изображение.

import numpy as np
import cv2
import pyautogui
import mss 
  
with mss.mss() as sct:
    
    # Get information of monitor 2
    monitor_number = 1
    mon = sct.monitors[monitor_number]

    # The screen part to capture
    monitor = {
        "top": mon["top"],
        "left": mon["left"],
        "width": mon["width"],
        "height": mon["height"],
        "mon": monitor_number,
    }
    output = "sct-mon{mon}_{top}x{left}_{width}x{height}.png".format(**monitor)

    # Grab the data
    sct_img = sct.grab(monitor)
    img = np.array(sct.grab(monitor)) # BGR Image

OpenCV не предназначен для захвата скриншотов.

Dan Mašek 17.11.2022 12:12
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
0
1
56
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используя python-mss, мы можем перебирать список мониторов и зацикливать кадр с каждого монитора (мы можем поместить этот цикл в бесконечный цикл).


Пример повторения мониторов:

for monitor_number, mon in enumerate(sct.monitors[1:]):
  • Мы игнорируем индекс 0 (похоже, что sct.monitors[0] применяет большой комбинированный монитор).
  • enumerate используется как ярлык для перебора списка, а также для получения индекса.

Следующий пример кода захватывает кадр с каждого монитора (в бесконечном цикле), уменьшает масштаб кадра и показывает его для тестирования (используя cv2.imshow).
Каждый монитор имеет отдельное окно, в заголовке которого отображается индекс монитора.

Пример кода:

import numpy as np
import cv2
import mss 

with mss.mss() as sct:
    # Grab frames in an endless lopp until q key is pressed
    while True:
        # Iterate over the list of monitors, and grab one frame from each monitor (ignore index 0)
        for monitor_number, mon in enumerate(sct.monitors[1:]):
            monitor = {"top": mon["top"], "left": mon["left"], "width": mon["width"], "height": mon["height"], "mon": monitor_number}  # Not used in the example

            # Grab the data
            img = np.array(sct.grab(mon)) # BGRA Image (the format BGRA, at leat in Windows 10).

            # Show down-scaled image for testing
            # The window name is img0, img1... applying different monitors.
            cv2.imshow(f'img{monitor_number}', cv2.resize(img, (img.shape[1]//4, img.shape[0]//4)))
            key = cv2.waitKey(1)
            if key == ord('q'):
                break

cv2.destroyAllWindows()

Пример вывода (с использованием двух мониторов):


Приведенный выше пример демонстрирует процесс захвата. Вам все еще нужно вычислить нормализованное среднее значение цвета...
Обратите внимание, что формат пикселей — BGRA, а не BGR (последний канал — это альфа-канал (прозрачность), который можно игнорировать).

Другие вопросы по теме