我在OpenCV中遇到了帧捕获效率低的问题。
- Raspberry Pi 3 (1,2 GHz quad-core ARM) with HDMI Display
- IP camera: LAN connected, RTSP, H264 codec, 1280x720 resolution, 20 fps, 1 GOP, 2500 kB/s VBR bitrate (parameters can be changed).
- OS Raspbian Stretch
- Python 3.5
- OpenCV 4.1
- Gstreamer 1.0
从IP摄像机获取视频流,识别图像并显示结果视频(带有标记和消息)。
重要特点:实时处理,高清分辨率(1280x720),高帧率(>20 fps),连续工作数小时.
通用算法:源视频流->解码和帧捕获->在OpenCV ->中与帧一起工作,使用Raspberry Pi GPU将处理后的帧组装成视频流->显示视频。
OpenCV输出/显示方法-- imshow --即使在低分辨率视频中也不能很好地工作。唯一允许使用Raspberry Pi GPU解码和显示视频的库是Gstreamer。
我用OMX支持编译了Gstreamer模块(gStreer1.0-plugins-bad、gStreer1.0-OMX),并对其进行了测试:
gst-launch-1.0 rtspsrc location='rtsp://web_camera_ip' latency=400 ! queue ! rtph264depay ! h264parse ! omxh264dec ! glimagesink
它的工作原理很好,的CPU使用率约为9%。
接下来,我用Gstreamer、NEON、VFPV3支持编译了VFPV3。
我使用以下代码进行测试:
import cv2
import numpy as np
src='rtsp://web_camera_ip'
stream_in = cv2.VideoCapture(src)
pipeline_out = "appsrc ! videoconvert ! video/x-raw, framerate=20/1, format=RGBA ! glimagesink sync=false"
fourcc = cv2.VideoWriter_fourcc(*'H264')
stream_out = cv2.VideoWriter(pipeline_out, cv2.CAP_GSTREAMER, fourcc, 20.0, (1280,720))
while True:
ret, frame = stream_out.read()
if ret:
stream_out.write(frame)
cv2.waitKey(1)
它也起作用了,但不如Gstreamer本身好。CPU使用率约为50%,无stream_out.write(帧)- 35%.当帧速率超过15时,存在延迟和延迟。
4.1。使用Gstreamer解码视频流:
pipline_in='rtspsrc location=rtsp://web_camera_ip latency=400 ! queue ! rtph264depay ! h264parse ! omxh264dec ! videoconvert ! appsink'
stream_in = cv2.VideoCapture(pipline_in)
它甚至使情况更糟--的CPU负载增加了几个百分点的,延迟变得更多了。
4.2。我还试图使用方法从PyImageSearch.com优化库--使用来自imutils库的WebcamVideoStream进行线程处理。
from threading import Thread
import cv2
import numpy as np
import imutils
src='rtsp://web_camera_ip'
stream_in = WebcamVideoStream(src).start()
pipeline_out = "appsrc ! videoconvert ! video/x-raw, framerate=20/1, format=RGBA ! glimagesink sync=false"
fourcc = cv2.VideoWriter_fourcc(*'H264')
stream_out = cv2.VideoWriter(pipeline_out, cv2.CAP_GSTREAMER, fourcc, 20.0, (1280,720))
while True:
frame = stream_in.read()
out.write(frame)
cv2.waitKey(1)
CPU使用率提高到的70%,输出视频流的质量没有改变。
4.3挂起下列参数的whaitKey(1-50)、视频流比特率(1000-5000 kB/s)、视频流GOP (1-20)没有帮助。
据我所知,VideoCap胞/Videowritter方法的效率很低。也许这在个人电脑上并不明显,但对覆盆子Pi 3来说却是至关重要的。
提前感谢您的回答!
更新1
我想我知道问题是什么,但我不知道如何解决。
主要问题是videoconvert 不支持GPU --主要是由于颜色格式的转换造成的!
我使用“纯”Gstreamer测试了这个假设,并添加了视频转换:
gst-launch-1.0 rtspsrc location='web_camera_ip' latency=400 ! queue ! rtph264depay ! h264parse ! omxh264dec ! videoconvert ! video/x-raw, format=BGR ! glimagesink sync=false
黑色显示,CPU负载为25%。
检查这个线:
gst-launch-1.0 rtspsrc location='web_camera_ip' latency=400 ! queue ! rtph264depay ! h264parse ! omxh264dec ! videoconvert ! video/x-raw, format=RGBA ! glimagesink sync=false
视频显示,CPU负载为5%。我还假设omxh264dec使用GPU将颜色格式YUV转换为RGBA (在omxh264dec之后,视频converts不加载CPU)。
在这线程6by9中,Rapberry的工程师和图形编程专家写道:“IL video_encode组件支持OMX_COLOR_Format24bitBGR888,我似乎还记得到OpenCV的RGB地图”。
有什么想法吗?
发布于 2019-07-08 22:09:14
你真的需要识别你捕捉到的每一幅图像吗?您可以使用第一个管道来显示图像(您可以使用视频覆盖用于水印和其他工件),但是可以解码(例如,每6幅图像用于CPU识别)。在本例中,您将只使用GPU来捕获和显示不需要加载CPU的视频,使用CPU进行选择性图像识别。
https://stackoverflow.com/questions/56924742
复制相似问题