如何在OpenCV中优化视频流中的帧抓取?

2024-09-28 17:22:35 发布

您现在位置:Python中文网/ 问答频道 /正文

我遇到了OpenCV中帧捕获效率低的问题。在

  1. 硬件和软件。在

    • Raspberry Pi 3(1,2 GHz四核ARM),带HDMI显示屏
    • IP摄像机:LAN连接,RTSP,H264编解码器,1280x720分辨率,20帧/秒,1个GOP,2500 kB/s VBR比特率(参数可更改)。在
    • 拉斯波斯伸展
    • Python 3.5
    • OpenCV 4.1版
    • Gstreamer 1.0版
  2. 任务。

从IP摄像机获取视频流,识别图像并显示结果视频(带有标记和消息)。

重要功能:实时处理、高清分辨率(1280x720)、高帧速率(大于20 fps)、连续工作数小时。在

  1. 我的解决方案。在

通用算法:源视频流->解码和帧捕获->使用OpenCV中的帧->将处理过的帧组装成视频流->使用Raspberry Pi GPU显示视频

OpenCV输出/显示方法-imshow即使在低分辨率视频中也不能很好地工作。唯一允许使用Raspberry Pi GPU解码和显示视频的库是Gstreamer。在

我使用omx支持编译了Gstreamer模块(gstreamer1.0-plugins-bad,gstreamer1.0-omx),并对其进行了测试:

gst-launch-1.0 rtspsrc location='rtsp://web_camera_ip' latency=400 ! queue ! rtph264depay ! h264parse ! omxh264dec ! glimagesink

它工作得很好,CPU使用率约为9%。在

接下来,我使用Gstreamer、NEON、VFPV3支持编译OpenCV。在

我使用以下代码进行测试:

^{pr2}$

它也起了作用,但不如Gstreamer本身好。CPU使用率约为50%没有流_输出.写入(帧)-35%。当帧速率高于15时,存在延迟和延迟。在

  1. 我是如何解决这个问题的。在

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条。我还试图使用method从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)、videostream比特率(1000-5000 kB/s)、videostream GOP(1-20)。在

  1. 问题。在

据我所知,VideoCaputre/videowriter方法的效率非常低。也许它在PC机上并不明显,但对于Raspberry Pi 3来说却是至关重要的。在

  • 有没有可能提高摄像机的性能 (录影机)?在
  • 有没有其他方法可以从 视频到OpenCV?在

提前感谢您的回答!在

更新1

我想我知道问题是什么,但我不知道怎么解决它。在

  1. 在使用VideoCapture和VideoCapture+Gstreamer时,对CPU使用率进行了优化。VideoCapture(src)+VideoWriter(gstreamer_piplene_out)-50-60%,VideoCapture(gstreamer_pipline_-in)+VideoWriter(gstreamer_piplene_-out)-40-50%。在
  2. 我程序的不同部分使用的颜色格式。H264视频流-YUV,OpenCV-BGR,OMX层输出-RGBA。OpenCV只能处理BGR颜色格式的帧。OMX层输出尝试以不同颜色格式启动采集的视频时,显示黑屏。在
  3. Gstremaer管道中的颜色格式转换是使用视频转换进行的。在某些情况下,该方法可以自动工作(无需指定参数),也可以强制指定颜色格式。我不知道它在“纯”视频捕获(src)中是如何工作的。在

主要问题是m> videoconvert不支持GPU-主CPU负载是由颜色格式转换引起的!在

我使用“纯”Gstreamer测试了这个假设,并添加了videoconvert:

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%。我还假设omxh24dec使用GPU将颜色格式YUV转换为RGBA(在omxh264dec之后,videoconver不加载CPU)。在

  1. 我不知道如何使用GPU在覆盆子上的VideoCapture/Gstreamer中进行颜色格式转换。在

this线程6by9中,Rapberry工程师和图形编程专家写道:“IL-video_encode组件支持OMX_COLOR_格式24bitbgr888,我似乎记得它映射到OpenCV的RGB”。在

有什么想法吗?在


Tags: inweb视频gpu颜色格式cpuout
1条回答
网友
1楼 · 发布于 2024-09-28 17:22:35

你真的需要识别你拍摄的每一张照片吗?您可以使用第一个管道显示图像(您可以使用视频覆盖水印和其他伪影),但例如每6个图像解码一次CPU识别。 在本例中,您将只使用GPU来捕获和显示视频,而不需要CPU加载,CPU用于选择性的图像识别

相关问题 更多 >