通过OpenCV使用Gstreamer流式传输实时MJPEG视频

时间:2019-02-21 15:18:29

标签: opencv video-streaming gstreamer mjpeg video-codecs

我有一个USB网络摄像头,可以传输MJPEG视频。我正在尝试将流读取到便携式计算机上的OpenCV中,对OpenCV中的帧进行一些处理,然后将流通过UDP发送到树莓派。

使用gstreamer命令行界面,我可以将摄像头直接从笔记本电脑发送到树莓派。我在笔记本电脑上运行以下命令:

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

这是来自Pi的:

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视频,然后发送-似乎效率不高,或者我错过了什么吗?有没有更清洁的方法可以做到这一点?

0 个答案:

没有答案