Потоковое видео в формате MJPEG с помощью Gstreamer через OpenCV

У меня есть веб-камера USB, которая транслирует видео в формате MJPEG. Я пытаюсь прочитать поток в OpenCV на ноутбуке, выполнить некоторую обработку кадров в OpenCV и отправить поток через UDP на Raspberry Pi.

Используя интерфейс командной строки gstreamer, я могу отправлять веб-камеру прямо с ноутбука на raspberry Pi. Я запускаю эту команду на ноутбуке:

gst-launch-1.0 v4l2src device=/dev/video1 ! image/jpeg,width=640,height=480,framerate=30/1 ! jpegparse ! rtpjpegpay ! udpsink host=10.1.10.77 port=8090

А это от Пи:

gst-launch-1.0 udpsrc address=10.1.10.77 port=8090 ! application/x-rtp, encoding-name=JPEG,payload=96 ! rtpjpegdepay ! jpegdec ! videoconvert ! fbdevsink device=/dev/fb0

Видео появляется в середине экрана Pi, и все в порядке. Но, когда я пытаюсь включить OpenCV в этот процесс, я путаюсь. Следующий код успешно отправляет видео...

import cv2

# Object that pulls frames from webcam
cap_fetch = cv2.VideoCapture(1)
cap_fetch.set(cv2.CAP_PROP_FRAME_WIDTH,640);
cap_fetch.set(cv2.CAP_PROP_FRAME_HEIGHT,480);

# Object that sends frames over gstreamer pipeline
cap_send = cv2.VideoWriter('appsrc ! videoconvert ! video/x-raw,format=YUY2 ! jpegenc ! rtpjpegpay ! udpsink host=10.1.10.77 port=9000', 0, 0 , 30, (640,480))

if not cap_fetch.isOpened() or not cap_send.isOpened():
    print('VideoCapture or VideoWriter not opened')
    exit(0)

while True:
    ret,frame = cap_fetch.read()

    if not ret:
        print('empty frame')
        break

    # do stuff to frame

    cap_send.write(frame)

    cv2.imshow('send', frame)
    if cv2.waitKey(1)&0xFF == ord('q'):
        break

cap_fetch.release()
cap_send.release()

... Но это не работает, если я выбираю любой формат, кроме YUY2, или если я пытаюсь что-то вроде этого:

cap_send = cv2.VideoWriter('appsrc ! image/jpeg ! jpegenc ! rtpjpegpay ! udpsink host=10.1.10.77 port=9000', 0, cv2.VideoWriter_fourcc('M','J','P','G'), 30, (640,480))

Любая идея, почему это может быть? Я очень новичок в gstreamer, но я думаю, что рабочий конвейер от OpenCV до Pi конвертирует необработанные матрицы изображений BGR из openCV в видео YUY2, затем конвертирует в видео MJPEG, затем отправляет - это не кажется эффективным, или я что-то упускаю? Есть ли более чистый способ сделать это?


person Anna Svagzdys    schedule 21.02.2019    source источник
comment
stackoverflow.com/a/46636126/2286337   -  person zindarod    schedule 21.02.2019