Python 如何在OpenCV中优化视频流的帧抓取?
我在OpenCV中遇到了帧捕获效率低的问题Python 如何在OpenCV中优化视频流的帧抓取?,python,opencv,raspberry-pi3,gstreamer,video-capture,Python,Opencv,Raspberry Pi3,Gstreamer,Video Capture,我在OpenCV中遇到了帧捕获效率低的问题 硬件和软件 Raspberry Pi 3(1.2 GHz四核ARM),带HDMI显示器 IP摄像机:局域网连接,RTSP,H264编解码器,1280x720分辨率,20 fps,1 GOP,2500 kB/s VBR比特率(参数可以更改) 拉斯比拉伸 Python 3.5 OpenCV 4.1 Gstreamer 1.0 任务 从IP摄像头获取视频流,识别图像并显示生成的视频(带有标记和消息)。 重要特点:实时处理,高清分辨率(1280x720),
- Raspberry Pi 3(1.2 GHz四核ARM),带HDMI显示器
- IP摄像机:局域网连接,RTSP,H264编解码器,1280x720分辨率,20 fps,1 GOP,2500 kB/s VBR比特率(参数可以更改)
- 拉斯比拉伸
- Python 3.5
- OpenCV 4.1
- Gstreamer 1.0
gst-launch-1.0 rtspsrc location='rtsp://web_camera_ip' latency=400 ! queue ! rtph264depay ! h264parse ! omxh264dec ! glimagesink
它工作得很好,CPU使用率约为9%
接下来,我使用Gstreamer、NEON和VFPV3支持编译了OpenCV
我使用以下代码进行测试:
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%,无数据流输出。写入(帧)-35%。当帧速率高于15时,会出现延迟和延迟
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)
- 是否有可能提高VideoCaputre的性能 (录像机)李>
- 是否有其他方法可以从中捕获帧 视频到OpenCV李>
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之后,videoconver不会加载CPU)
有什么想法吗?你真的需要识别你拍摄的每一张图像吗?您可以使用第一个管道来显示图像(您可以使用视频覆盖来显示水印和其他瑕疵),但例如,每第六个图像解码一次以进行CPU识别。
在这种情况下,您将只使用GPU捕获和显示视频,而无需CPU加载,CPU用于选择性图像识别您应该知道您正在使用哪些内存空间。您的第一条管道是最有效的:您解码图形卡上的视频,并告诉图形卡显示它。如果要在解码和显示之间执行CPU处理,则需要将图像数据下载到CPU主机内存,执行处理并将其上载回图形卡内存。这是昂贵的,尤其是对于像Pi这样的嵌入式设备。理想情况下,您可以直接在GPU上对OpenGL纹理进行处理,避免复制周围的图像数据。谢谢您的回答!我正在寻找一种使用GPU在Gstreamer中转换颜色格式的方法。如果我找不到解决办法,我就用你提出的方法。分离流进行识别和输出的主要缺点是无法标记已识别的对象。