Я пытаюсь разработать устройство, которое меняет светодиодные полосы 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
Используя python-mss, мы можем перебирать список мониторов и зацикливать кадр с каждого монитора (мы можем поместить этот цикл в бесконечный цикл).
Пример повторения мониторов:
for monitor_number, mon in enumerate(sct.monitors[1:]):
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 (последний канал — это альфа-канал (прозрачность), который можно игнорировать).
OpenCV не предназначен для захвата скриншотов.