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