在Python中从opencv编写Gstreamer管道

Wis*_*ill 4 python opencv gstreamer raspberry-pi

我正在尝试使用gstreamer从opencv流式传输一些图像,但管道出现了一些问题。我是gstreamer和opencv的新手。我在树莓派3上用gstreamer为python3编译了opencv 3.2。我有一个与raspivid一起使用的bash脚本。

raspivid -fps 25 -h 720 -w 1080 -vf -n -t 0 -b 2000000 -o - | gst-launch-1.0 -v fdsrc ! h264parse ! rtph264pay config-interval=1 pt=96 ! gdppay ! tcpserversink host=192.168.1.27 port=5000
Run Code Online (Sandbox Code Playgroud)

我想转换此管道,以便从opencv中使用它,并将其输入我的算法处理的图像。我做了一些研究,发现可以将videoWriter与appsrc一起使用,而不是fdsrc,但是出现以下错误

GStreamer Plugin: Embedded video playback halted; module appsrc0 reported: Internal data flow error.
Run Code Online (Sandbox Code Playgroud)

我想出的python脚本是以下方式导入cv2

cap = cv2.VideoCapture(0)


# Define the codec and create VideoWriter object
fourcc = cv2.VideoWriter_fourcc(*'MJPG')
out = cv2.VideoWriter('appsrc  ! h264parse ! '
                      'rtph264pay config-interval=1 pt=96 ! '
                      'gdppay ! tcpserversink host=192.168.1.27 port=5000 ',
                      fourcc, 20.0, (640, 480))

while cap.isOpened():
    ret, frame = cap.read()
    if ret:
        frame = cv2.flip(frame, 0)

        # write the flipped frame
        out.write(frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break

# Release everything if job is finished
cap.release()
out.release()
cv2.destroyAllWindows()
Run Code Online (Sandbox Code Playgroud)

管道中有任何错误吗?我不明白这个错误。我已经有一个可以从bash管道读取的Python客户端,从延迟角度和消耗资源的角度来看,结果都非常好。

Wis*_*ill 6

我遇到了解决方案,希望对其他遇到相同问题的人有所帮助。管道布置错误,需要视频转换。另一方面,延迟是非常相关的,但是将speed.preset设置为ultrafast可以解决此问题,即使那里没有太多压缩,这也是一个很好的折衷方案。这是我的解决方案。

import cv2

cap = cv2.VideoCapture(0)

framerate = 25.0

out = cv2.VideoWriter('appsrc ! videoconvert ! '
                      'x264enc noise-reduction=10000 speed-preset=ultrafast tune=zerolatency ! '
                      'rtph264pay config-interval=1 pt=96 !'
                      'tcpserversink host=192.168.1.27 port=5000 sync=false',
                      0, framerate, (640, 480))

while cap.isOpened():
    ret, frame = cap.read()
    if ret:

        out.write(frame)

        if cv2.waitKey(1) & 0xFF == ord('q'):
            break
    else:
        break

# Release everything if job is finished
cap.release()
out.release()
Run Code Online (Sandbox Code Playgroud)