Использование python mss для рисования ограничительной рамки поверх записи экрана - PullRequest
0 голосов
/ 21 января 2019

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

Я заметил в документах этот пример , но я попытался запустить его и не могу заставить его что-либо отображать. И я даже не уверен, что это сработает с моим примером.

import cv2
import time
import numpy as np
from mss import mss

with mss() as sct:
        # Part of the screen to capture
        monitor = {"top": 79, "left": 265, "width": 905, "height": 586}

        while "Screen capturing":
            last_time = time.time()

            # Get raw pixels from the screen, save it to a Numpy array
            screen = np.array(sct.grab(monitor))

            # print("fps: {}".format(1 / (time.time() - last_time)))

            print('loop took {} seconds'.format(time.time()-last_time))
            last_time = time.time()
            screen = cv2.cvtColor(screen, cv2.COLOR_BGR2RGB)
            screen = cv2.resize(screen, (224,224)).astype(np.float32)/255

            # Display the picture
            cv2.imshow("OpenCV/Numpy normal", screen)

            # Press "q" to quit
            if cv2.waitKey(25) & 0xFF == ord("q"):
                cv2.destroyAllWindows()
                break

Теперь скажите, что у меня есть набор ограничивающих рамок для отображения на каждом кадре, например,

bboxes = [np.array([12, 16, 29, 25]), np.array([5,  5, 38, 35])]

Можно ли каким-то образом изменить пиксели, чтобы отобразить это? Я полагаю, что мог бы сделать это и с помощью opencv, поскольку именно это в конечном итоге отображает экран.

РЕДАКТИРОВАТЬ: Ссылаясь на комментарий о ограничивающих прямоугольниках, они x1, y1, width, height и находятся в измененном размере (224,224) изображение

1 Ответ

0 голосов
/ 21 января 2019

Есть некоторые недостающие детали:

  • Каков формат ограничивающих рамок: [x1, y1, x2, y2] или [x1, y1, width, height] или что-то еще?
  • Значения ограничивающих рамок находятся в измененном размере (224, 224) или в исходном диапазоне?

В любом случае, вы можете использовать функцию ниже для рисования прямоугольников (вам нужно выбрать в зависимости от формата):

def draw_bboxes(img, bboxes, color=(0, 0, 255), thickness=1):
    for bbox in bboxes:
        # if [x1, y1, x2, y2]
        cv2.rectangle(img, tuple(bbox[:2]), tuple(bbox[-2:]), color, thickness)
        # if [x1, y1, width, height]
        cv2.rectangle(img, tuple(bbox[:2]), tuple(bbox[:2]+bbox[-2:]), color, thickness)

Предполагая, что вы определили bboxes, вы можете вызвать функцию:

  • Если вы хотите нарисовать исходную рамку:
# [...]
screen = np.array(sct.grab(monitor))
draw_bboxes(screen, bboxes)
# [...]
  • Если вы рисуете на рамке с измененным размером:
# [...]
screen = cv2.resize(screen, (224,224)).astype(np.float32)/255
draw_bboxes(screen, bboxes)
# [...]

С некоторыми изменениями полный код будет выглядеть так:

import cv2
import time
import numpy as np
from mss import mss

def draw_bboxes(img, bboxes, color=(0, 0, 255), thickness=1):
    for bbox in bboxes:
        cv2.rectangle(img, tuple(bbox[:2]), tuple(bbox[:2]+bbox[-2:]), color, thickness)

# bounding boxes
bboxes = [np.array([12, 16, 29, 25]), np.array([5,  5, 38, 35])]

with mss() as sct:
    # part of the screen to capture
    monitor = {"top": 79, "left": 265, "width": 905, "height": 586}
    while "Screen capturing":
        # get screen
        last_time = time.time()
        screen = np.asarray(sct.grab(monitor))
        print('loop took {} seconds'.format(time.time()-last_time))

        # convert from BGRA --> BGR
        screen = cv2.cvtColor(screen, cv2.COLOR_BGRA2BGR)
        # resize and draw bboxes
        screen = cv2.resize(screen, (224,224))
        draw_bboxes(screen, bboxes)

        # display
        cv2.imshow("OpenCV/Numpy normal", screen)

        # Press "q" to quit
        if cv2.waitKey(25) & 0xFF == ord("q"):
            cv2.destroyAllWindows()
            break

Вывод будет примерно таким:

enter image description here

...