pythonopencvpython-mss

Can't record screen using mss and cv2


I have the following code

from mss import mss
import cv2
import numpy


class MSSSource:
    def __init__(self):
        self.sct = mss()

    def frame(self):
        monitor = {'top': 0, 'left': 0, 'width': 640, 'height': 480}
        grab = self.sct.grab(monitor)
        return True, numpy.array(grab)

    def release(self):
        pass


class CapSource:
    def __init__(self):
        self.cap = cv2.VideoCapture(0)

    def frame(self):
        return self.cap.read()

    def release(self):
        self.cap.release()


if __name__ == '__main__':
    fourcc = cv2.VideoWriter_fourcc(*'DIVX')
    out = cv2.VideoWriter('output.avi', fourcc, 20.0, (640, 480))
    source = MSSSource()

    while (True):
        ret, frame = source.frame()
        if not ret:
            break
        out.write(frame)
        cv2.imshow('hello', frame)
        if cv2.waitKey(1) & 0xFF == ord('q'):
            break

    out.release()
    source.release()
    cv2.destroyAllWindows()

Using CapSource, I can record working video from my camera.

MSSSource, while showing fine in the window, produces 5kb large file which i can't play.

Using PIL.ImageGrab (not included here) works fine, so I wonder what is the issue with mss specifically.

What am I doing wrong, how can I troubleshoot the issue?

OS: Windows 10


Solution

  • Redefine MSSSource.frame() to:

    def frame(self):
        monitor = {'top': 0, 'left': 0, 'width': 640, 'height': 480}
        im = numpy.array(self.sct.grab(monitor))
        im = numpy.flip(im[:, :, :3], 2)  # 1
        im = cv2.cvtColor(im, cv2.COLOR_BGR2RGB)  # 2
        return True, im
    

    MSS returns raw pixels in the BGRA form (Blue, Green, Red, Alpha). So #1 will reshape from BGRA to BGR and #2 will convert BGR to RGB.