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

ops/2025/2/6 10:32:33/

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

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

python">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,执行命令:

python">pip install ffmpeg-python

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.ppmy.cn/ops/156127.html

相关文章

Ollama AI 开发助手完全指南:从入门到实践

本文将详细介绍如何使用 Ollama AI 开发助手来提升开发效率,包括环境搭建、模型选择、最佳实践等全方位内容。 © ivwdcwso (ID: u012172506) 目录 基础环境配置模型选择与使用开发工具集成实践应用场景性能优化与注意事项最佳实践总结一、基础环境配置 1.1 系统要求 在…

基于AnolisOS8.6+Kubespray2.23部署Kubernetes-v1.27

测试环境 Virtual Box,AnolisOS-8.6-x86_64-minimal.iso,4 vCPU, 8G RAM, 50 vDisk。最小化安装。需联网。 系统环境 关闭防火墙 systemctl stop firewalld systemctl disable firewalld systemctl status firewalld selinux关闭 cat /etc/selinux/c…

LeetCode - #197 Swift 实现找出温度更高的日期

网罗开发 (小红书、快手、视频号同名) 大家好,我是 展菲,目前在上市企业从事人工智能项目研发管理工作,平时热衷于分享各种编程领域的软硬技能知识以及前沿技术,包括iOS、前端、Harmony OS、Java、Python等…

关于大模型 AGI 应知应会_生在AI发展的时代

在 AI 时代,大模型和通用人工智能(AGI)正在深刻改变我们的生活和工作方式。以下是一些关于大模型和 AGI 的关键知识点,帮助我们更好地理解这一技术浪潮。 一、大模型的核心概念与特点 (一)什么是大模型 …

需求分析应该从哪些方面来着手做?

需求分析一般可从以下几个方面着手: 业务需求方面 - 与相关方沟通:与业务部门、客户等进行深入交流,通过访谈、问卷调查、会议讨论等方式,明确他们对项目的期望、目标和整体业务需求,了解项目要解决的业务问题及达成的…

Vue 中如何嵌入可浮动的第三方网页窗口(附Demo)

目录 前言1. 思路Demo2. 实战Demo 前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 1. 思路Demo 以下Demo提供思路参考,需要结合实际自身应用代码 下述URL的链接使用百度替代! 方式 1…

在Mapbox GL JS中“line-pattern”的使用详解

在Mapbox GL JS中,line-pattern 是一种用于在地图上绘制带有图案的线条的样式属性。通过 line-pattern,你可以使用自定义的图像作为线条的图案,而不是使用纯色或渐变。 1. 基本概念 line-pattern: 该属性允许你指定一个图像作为线条的图案。…

自定义数据集 使用scikit-learn中svm的包实现svm分类

数据集生成: - 使用 make_classification 函数生成包含1000个样本的数据集,设置20个特征,其中10个是有信息的特征,类别数为2,通过设置 random_state 42 保证每次运行生成的数据相同。 数据划分: - 使用…