Python利用VideoCapture和FFmpeg读取多个rtsp流性能的比较

news2025/2/6 17:46:14

最近一个项目,要用python读取30个海康摄像头的rtsp流,一开始直接用cv2.VideoCapture(video_path),结果运行一段时间后发现读出来的frame经常出现花屏的现象。所以通过两种方式对程序进行了修改。

1、我先是通过cap.set(cv2.CAP_PROP_BUFFERSIZE, 3)设置缓冲区大小可能有助于减少丢帧现象。代码如下:

import cv2  # 导入 OpenCV 库,用于处理计算机视觉和视频流相关的功能。

# 设置 RTSP 视频流的路径(用户名、密码、IP 地址和视频流的 URL)。
video_path = 'rtsp://admin:123456@192.168.3.101/Streaming/Channels/1'

# 使用 cv2.VideoCapture 打开 RTSP 视频流,cap 是一个视频捕获对象。
cap = cv2.VideoCapture(video_path)

# 设置视频流缓冲区的大小,减少延迟,CAP_PROP_BUFFERSIZE 设置为 3 表示缓冲区大小为 3 帧。
cap.set(cv2.CAP_PROP_BUFFERSIZE, 3)

# 检查视频流是否成功打开并且继续读取帧。cap.isOpened() 返回 True 表示视频流打开成功。
while cap.isOpened():
    # 读取视频流中的一帧。返回值 success 表示读取是否成功,frame 为读取到的图像帧。
    success, frame = cap.read()

    # 如果成功读取到帧,则显示该帧。
    if success:
        # 使用 OpenCV 显示读取到的视频帧,"SHOW" 为窗口名称,frame 为图像数据。
        cv2.imshow("SHOW", frame)
        
        # 等待 1 毫秒,检测按键。如果按下 'q' 键,则退出循环。
        if cv2.waitKey(1) & 0xFF == ord("q"):
            break  # 按下 'q' 键退出循环,关闭视频流。

2、然后我又尝试用FFmpeg直接处理RTSP流。

首先要安装ffmpeg,执行命令:

pip install ffmpeg-python

python代码如下:

import ffmpeg  # 导入 ffmpeg 库,用于处理视频流(如 RTSP 流)。
import numpy as np  # 导入 NumPy 库,用于处理数据(如视频帧的数组操作)。
import cv2  # 导入 OpenCV 库,用于处理计算机视觉相关的功能(如显示视频)。

# 设置摄像头的 RTSP 流地址(用户名、密码、IP 地址和视频流的 URL)。
camera = 'rtsp://admin:123456@192.168.3.101/Streaming/Channels/1'

# 使用 ffmpeg.probe 函数探测摄像头的视频流信息,返回一个包含流信息的字典。
probe = ffmpeg.probe(camera)

# 从探测结果中找到视频流(选择 codec_type 为 'video' 的流)。
video_stream = next((stream for stream in probe['streams'] if stream['codec_type'] == 'video'), None)

# 获取视频流的宽度和高度,并将其转换为整数类型。
width = int(video_stream['width'])
height = int(video_stream['height'])

# 使用 ffmpeg 创建一个异步运行的命令,将视频流传输到管道中,并指定格式、像素格式、帧率等。
out = (
    ffmpeg
        .input(camera, rtsp_transport='tcp')  # 设置输入源为摄像头 RTSP 流,并指定使用 TCP 协议。
        .output('pipe:', format='rawvideo', pix_fmt='bgr24', loglevel="quiet", r=25)  # 输出到管道,指定原始视频格式,像素格式为 BGR24,帧率为 25 帧每秒。
        .run_async(pipe_stdout=True)  # 异步运行 ffmpeg,并将标准输出连接到管道。
)

# 初始化空帧计数器,检测视频流是否断开。
cnt_empty = 0

# 无限循环,持续读取视频流并处理每一帧。
while True:
    # 从管道读取一帧数据,每帧的大小为 height * width * 3(3 为每个像素的 RGB 通道)。
    in_bytes = out.stdout.read(height * width * 3)

    # 如果没有读取到数据(即视频流结束或出现错误),则增加空帧计数器。
    if not in_bytes:
        cnt_empty += 1
        # 如果连续 10 次没有数据,则认为视频流已结束,跳出循环。
        if cnt_empty > 10:
            break

    # 如果有数据,重置空帧计数器。
    cnt_empty = 0

    # 将读取到的字节数据转换为 NumPy 数组,并重新塑形为图像帧(height, width, 3 表示高、宽、RGB 三通道)。
    frame = np.frombuffer(in_bytes, dtype=np.uint8).reshape(height, width, 3)

    # 使用 OpenCV 显示视频帧(此时 frame 是图像数据)。
    cv2.imshow('test', frame)

    # 等待按键,如果按下 'q' 键则退出循环。
    if cv2.waitKey(1) & 0xFF == ord('q'):
        break

# 释放资源(在程序退出时关闭 OpenCV 的窗口等资源)。
cv2.destroyAllWindows()

3、结论:
由于时间关系,我没用数据详细比较。直观感觉,只接入一两个摄像头,两种方式没什么区别,但是当摄像头很多并且分辨率和帧率都比较高时,FFmpeg延迟相对更低,性能表现好一些。下面这个表是网上找的,仅供参考。
 

特性cv2.VideoCapture (FFmpeg via OpenCV)FFmpeg (命令行或库调用)
简便性高,简洁的 API,直接使用 cv2.VideoCapture较低,需手动设置 FFmpeg 参数
性能依赖于 FFmpeg,适合一般应用,但可能有延迟通常更高效,低延迟,优化过的解码器
灵活性灵活性较低,只能使用 OpenCV 提供的功能高,可以精细控制流媒体传输、解码等
适用场景普通的视频捕获和播放,实时性要求不高需要低延迟、高性能和灵活控制的场景
库依赖基6于 FFmpeg,但封装在 OpenCV 中直接使用 FFmpeg

效率:FFmpeg 直接处理 RTSP 视频流的效率通常更高,尤其是在高帧率、低延迟的要求下,FFmpeg 的解码性能通常更好。
简便性:如果你只是想简化代码并快速实现功能,cv2.VideoCapture 会更方便。但它依赖于 OpenCV 和 FFmpeg 的封装,可能无法像直接使用 FFmpeg 那样精细调整解码行为。
建议:如果你的应用对实时性、低延迟和高性能有较高要求,尤其是在需要处理高帧率视频流的情况下,直接使用 FFmpeg 会更好。如果你需要快速开发并且不在乎一些细节的优化,使用 cv2.VideoCapture 会是一个简单方便的选择。

芝加哥时间深夜2点,休息了,晚安。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2293894.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

UE虚幻引擎No Google Play Store Key:No OBB found报错如何处理

UE虚幻引擎No Google Play Store Key:No OBB found报错如何处理? 问题描述: UE成功打包APK并安装过后,启动应用时提示: No Google Play Store KeyNo OBB found and no store key to try to download. Please setone …

吴恩达深度学习——卷积神经网络实例分析

内容来自https://www.bilibili.com/video/BV1FT4y1E74V,仅为本人学习所用。 文章目录 LeNet-5AlexNetVGG-16ResNets残差块 1*1卷积 LeNet-5 输入层:输入为一张尺寸是 32 32 1 32321 32321的图像,其中 32 32 3232 3232是图像的长和宽&…

LabVIEW的智能电源远程监控系统开发

在工业自动化与测试领域,电源设备的精准控制与远程管理是保障系统稳定运行的核心需求。传统电源管理依赖本地手动操作,存在响应滞后、参数调节效率低、无法实时监控等问题。通过集成工业物联网(IIoT)技术,实现电源设备…

【自动化办公】批量图片PDF自定义指定多个区域识别重命名,批量识别铁路货物运单区域内容改名,基于WPF和飞桨ocr深度学习模型的解决方案

项目背景介绍 铁路货运企业需要对物流单进行长期存档,以便后续查询和审计。不同的物流单可能包含不同的关键信息,通过自定义指定多个区域进行识别重命名,可以使存档的图片文件名具有统一的规范和明确的含义。比如,将包含货物运单…

neo4j-在Linux中安装neo4j

目录 切换jdk 安装neo4j 配置neo4j以便其他电脑可以访问 切换jdk 因为我安装的jdk是1.8版本的,而我安装的neo4j版本为5.15,Neo4j Community 5.15.0 不支持 Java 1.8,它要求 Java 17 或更高版本。 所以我需要升级Java到17 安装 OpenJDK 17 sudo yu…

专业学习|通过案例了解蒙特卡罗模拟实操步骤与含义

一、蒙特卡罗模拟介绍 蒙特卡罗模拟(Monte Carlo Simulation)是一种基于随机采样的数值计算方法,用于解决具有不确定性或复杂概率分布的问题。其核心思想是通过多次随机抽样来逼近系统的行为或目标函数的真实值,进而对系统进行评估…

数据结构【链栈】

基于 C 实现链表栈:原理、代码与应用 一、引言 栈就是一个容器,可以当场一个盒子,只能一个一个拿,一个一个放,而且是从上面放入。 有序顺序栈操作比较容易【会了链栈之后顺序栈自然明白】,所以我们这里只…

人工智能|本地部署|ollama+chatbox快速Windows10下部署(初级篇)

一、 前言: 其实早一个月我已经使用过deepseek,并且也在自己的机器上通过ollama部署过,但一直没有太多动力,现在感觉还是的记录一下,省的自己给忘掉了 本文只是简单记录一下ollamaopen-webuichatbox部署通过网盘分享…

Android Studio 下载安装教程(2024 更新版),附详细图文

今天,为大家带来的是Android Studio 2024更新版的下载安装教程,包含详细图文步骤。 随着 Android Studio 的不断更新,自从引入 Koala 系列后,其版本号的命名规则也发生了变化。以本次更新为例,版本号为 2024.2.1&#…

6.【BUUCTF】[SUCTF 2019]CheckIn

打开题目页面如下 看样子是一道有关文件上传的题 上传一句话木马 显示:非法后缀! 看来.php后缀被过滤了 上传一张带有木马的照片 在文件地址处输入cmd 输入以下代码执行 copy 1.jpg/b4.php/a 5.jpg 最后一行有一句话木马 上传带有木马的图片 但其实…

在线教程丨YOLO系列10年更新11个版本,最新模型在目标检测多项任务中达SOTA

YOLO (You Only Look Once) 是计算机视觉领域中最具影响力的实时目标检测算法之一,以其高精度与高效性深受业界青睐,广泛应用于自动驾驶、安防监控、医疗影像等领域。 该模型最早于 2015 年由华盛顿大学研究生 Joseph Redmon 发布,开创了将目…

FreeRTOS学习 --- 中断管理

什么是中断? 让CPU打断正常运行的程序,转而去处理紧急的事件(程序),就叫中断 中断执行机制,可简单概括为三步: 1,中断请求 外设产生中断请求(GPIO外部中断、定时器中断…

Docker基础以及单体实战

Docker 一、Docker1.1 Docker组成1.2 Dcoker运行图1.3 名称空间Namepace 1.4 docker、Docker compose、kubermetes 二、Docker安装2.1 在线Docker安装2.2 使用官方通用安装脚本2.3 二进制安装Docker三、Docker基础命令3.1 启动类3.2 镜像类3.3 容器类3.4 网络类3.5 Docker comp…

FFmpeg rtmp推流直播

文章目录 rtmp协议RTMP协议组成RTMP的握手过程RTMP流的创建RTMP消息格式Chunking(Message 分块) rtmp服务器搭建Nginx服务器配置Nginx服务器 librtmp库编译推流 rtmp协议 RTMP(Real Time Messaging Protocol)是由Adobe公司基于Flash Player播放器对应的…

2025Java面试题超详细整理《微服务篇》

什么是微服务架构? 微服务框架是将某个应用程序开发划分为许多独立小型服务,实现敏捷开发和部署,这些服务一般围绕业务规则进行构建,可以用不同的语言开发,使用不同的数据存储,最终使得每个服务运行在自己…

IIC重难点-2

一、光环境传感器硬件原理图 二、i.MX6ull I2C控制器介绍 1. Inter IC (I2C)提供标准I2C从机和主机的功能。I2C被设计为兼容标准NXP I2C总线协议。 2. I2C是一种双线双向串行总线,它提供了一种简单有效的数据交换方法,最大限度地减少了…

优化数据库结构

MySQL学习大纲 一个好的数据库设计方案对于数据库的性能尝尝会起到事倍功半的效果,合理的数据库结构不仅使数据库占用更小的磁盘空间,而且使查询速度更快。数据库结构的设计需要考虑数据冗余、查询和更新速度、字段的数据类型是否合理等多方面的内容&…

2. K8S集群架构及主机准备

本次集群部署主机分布K8S集群主机配置主机静态IP设置主机名解析ipvs管理工具安装及模块加载主机系统升级主机间免密登录配置主机基础配置完后最好做个快照备份 2台负载均衡器 Haproxy高可用keepalived3台k8s master节点5台工作节点(至少2及以上)本次集群部署主机分布 K8S集群主…

51单片机07 串口通信

串口是一种应用十分广泛的通讯接口,串口成本低、容易使用、通信线路简单,可实现两个设备的互相通信。单片机的串口可以使单片机与单片机、单片机与电脑、单片机与各式各样的模块互相通信。51单片机内部自带UART(Universal Asynchronous Recei…

Java进阶——IO 流

文章目录 Java进阶——IO 流 1、File 类的使用 1.1、File 常用构造器1.2、路径分隔符1.3、File 的常用方法 2、IO流原理及流的分类 2.1、IO流原理2.2、流的分类 3、IO流的体系结构4、节点流 4.1、FileReader 读入数据的操作4.2、FileWriter 写出数据的操作4.3、FileReader 和 …