使用 GStreamer 创建一个简单的 OpenCV 管道
Create a simple OpenCV pipeline with GStreamer
我有一个通过 UDP 传输图像的管道
fps = 20
width = 500
height = 500
out_send = cv2.VideoWriter(
"appsrc ! videoconvert ! "
"video/x-raw,format=I420 ! "
"jpegenc ! rtpjpegpay !"
"udpsink host=127.0.0.1 port=5000",
cv2.CAP_GSTREAMER, 0, fps, (width, height), True
)
while True:
frame = np.random.randint(255, size=(height, width, 3), dtype=np.uint8)
out_send.write(frame)
time.sleep(0.05)
这将启动管道,但我无法使用以下管道接收。流式传输不会开始,只是挂起。
gst-launch-1.0 udpsrc port=5000 ! application/x-rtp,media=video,payload=26,clock-rate=90000,encoding-name=JPEG ! rtpjpegdepay ! jpegdec ! videoconvert ! queue ! xvimagesink
但是,如果帧是从网络摄像头捕获的,如下所示
cap_send = cv2.VideoCapture(0)
fps = int(cap_send.get(cv2.CAP_PROP_FPS))
width = int(cap_send.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap_send.get(cv2.CAP_PROP_FRAME_HEIGHT))
while True:
ret, frame = cap_send.read()
if not ret:
break
out_send.write(frame)
然后接收管道启动并且流式传输没有任何问题。
在这两种情况下,我都会在接收端看到以下消息
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
编辑:
我运行接收管道GST_DEBUG=3
并看到以下输出
gst_rtp_jpeg_depay_process:<rtpjpegdepay0> discarding data packets received when we have no header
仅当发送管道如上所述使用原始图像/numpy 数组时才会发生这种情况。
我这里哪里做错了。 gstreamer 的新手,需要一些帮助
目标:异步流式传输在 opencv 中生成的图像。
@Micka 为我指明了正确的方向。
问题出在帧大小上。我已经尝试过 MJPEG 和 H264,两者都需要帧大小 (width/height),它们是 8 的倍数。Gstreamer 会将它们四舍五入到最接近的第 8 个倍数。如果高度是四舍五入的,那么在帧的末端会看到抖动。如果宽度是圆角的,那么在接收器上会看到一个绿色屏幕。
我有一个通过 UDP 传输图像的管道
fps = 20
width = 500
height = 500
out_send = cv2.VideoWriter(
"appsrc ! videoconvert ! "
"video/x-raw,format=I420 ! "
"jpegenc ! rtpjpegpay !"
"udpsink host=127.0.0.1 port=5000",
cv2.CAP_GSTREAMER, 0, fps, (width, height), True
)
while True:
frame = np.random.randint(255, size=(height, width, 3), dtype=np.uint8)
out_send.write(frame)
time.sleep(0.05)
这将启动管道,但我无法使用以下管道接收。流式传输不会开始,只是挂起。
gst-launch-1.0 udpsrc port=5000 ! application/x-rtp,media=video,payload=26,clock-rate=90000,encoding-name=JPEG ! rtpjpegdepay ! jpegdec ! videoconvert ! queue ! xvimagesink
但是,如果帧是从网络摄像头捕获的,如下所示
cap_send = cv2.VideoCapture(0)
fps = int(cap_send.get(cv2.CAP_PROP_FPS))
width = int(cap_send.get(cv2.CAP_PROP_FRAME_WIDTH))
height = int(cap_send.get(cv2.CAP_PROP_FRAME_HEIGHT))
while True:
ret, frame = cap_send.read()
if not ret:
break
out_send.write(frame)
然后接收管道启动并且流式传输没有任何问题。
在这两种情况下,我都会在接收端看到以下消息
Setting pipeline to PAUSED ...
Pipeline is live and does not need PREROLL ...
Pipeline is PREROLLED ...
Setting pipeline to PLAYING ...
New clock: GstSystemClock
编辑:
我运行接收管道GST_DEBUG=3
并看到以下输出
gst_rtp_jpeg_depay_process:<rtpjpegdepay0> discarding data packets received when we have no header
仅当发送管道如上所述使用原始图像/numpy 数组时才会发生这种情况。
我这里哪里做错了。 gstreamer 的新手,需要一些帮助
目标:异步流式传输在 opencv 中生成的图像。
@Micka 为我指明了正确的方向。
问题出在帧大小上。我已经尝试过 MJPEG 和 H264,两者都需要帧大小 (width/height),它们是 8 的倍数。Gstreamer 会将它们四舍五入到最接近的第 8 个倍数。如果高度是四舍五入的,那么在帧的末端会看到抖动。如果宽度是圆角的,那么在接收器上会看到一个绿色屏幕。