Потоковое видео в памяти с помощью OpenCV VideoWriter и Python BytesIO

Мне было интересно, можно ли «передавать» данные с помощью класса OpenCV VideoWriter в Python?

Обычно для обработки данных в памяти, которые в противном случае попадали бы на диск, я использую BytesIO (или StringIO).

Однако моя попытка использовать BytesIO не удалась:

import cv2
from io import BytesIO

stream = cv2.VideoCapture(0)
fourcc = cv2.VideoWriter_fourcc('x264')

data = BytesIO()

# added these to try to make data appear more like a string
data.name = 'stream.{}'.format('av1')
data.__str__ = lambda x: x.name

try:
    video = cv2.VideoWriter(data, fourcc=fourcc, fps=30., frameSize=(640, 480))
    start = data.tell()

        # Check if camera opened successfully
        if (stream.isOpened() == False): 
            print("Unable to read camera feed", file=sys.stderr)
            exit(1)

        # record loop
        while True:
            _, frame = stream.read()
            video.write(frame)
            data.seek(start)
            # do stuff with frame bytes
            # ...

            data.seek(start)

    finally:
        try:
            video.release()
        except:
            pass
finally:
    stream.release()

Однако вместо записи объекта BytesIO я получаю следующее сообщение:

Traceback (most recent call last):
  File "video_server.py", line 54, in talk_to_client
    video = cv2.VideoWriter(data, fourcc=fourcc, fps=fps, frameSize=(width, height))
TypeError: Required argument 'apiPreference' (pos 2) not found

... Поэтому, когда я изменяю вызов VideoWriter на cv2.VideoWriter(data, apiPreference=0, fourcc=fourcc, fps=30., frameSize=(640, 480)) (я читал, что 0 означает авто, но я также пробовал cv2.CAP_FFMPEG), вместо этого я получаю следующую ошибку:

Traceback (most recent call last):
  File "video_server.py", line 54, in talk_to_client
    video = cv2.VideoWriter(data, apiPreference=0, fourcc=fourcc, fps=fps, frameSize=(width, height))
TypeError: bad argument type for built-in operation

Итак, мой вопрос: можно ли записывать закодированное видео с использованием класса cv2.VideoWriter в памяти, и если да, то как это делается?

На данный момент у меня совсем нет идей, поэтому любая помощь будет приветствоваться :-)


person Liam Deacon    schedule 26.06.2018    source источник
comment
Вы пытаетесь кодировать видео без записи на диск? В OpenCV это невозможно.   -  person zindarod    schedule 27.06.2018


Ответы (1)


К сожалению, OpenCV не поддерживает кодирование в память (или декодирование из нее). Вы должны писать на диск (или читать с него), чтобы VideoWriter (или VideoCapture) работал.

person Farhan    schedule 26.06.2018
comment
Я боялся, что дело обстоит именно так. Я хотел закодировать видео перед передачей по сети, чтобы уменьшить объем отправляемых данных, однако я пытался обойтись без необходимости записывать данные на диск ... Думаю, я откажусь от отправки отдельных изображений по сети. - person Liam Deacon; 27.06.2018
comment
Да, к сожалению, OpenCV не поддерживает эту функцию, поскольку я уверен, что она будет широко использоваться. - person Farhan; 27.06.2018