【python】OpenCV—Faster Video File FPS

在这里插入图片描述

文章目录

  • 1、需求描述
  • 2、正常方法 cv2.read
  • 3、加速方法 imutils.video.FileVideoStream
  • 4、涉及到的核心库函数
    • 4.1、imutils.video.FPS
    • 4.2、imutils.video.FileVideoStream
  • 5、参考

1、需求描述

使用线程和队列数据结构将视频文件的 FPS 速率提高 !

我们的目标是将视频文件帧的读取和解码移动到程序的一个完全独立的线程中,释放我们的主线程来处理实际的图像处理。

2、正常方法 cv2.read

import datetime# class FPS:
# 	def __init__(self):
# 		# 存储开始时间、结束时间和在开始和结束间隔之间检查的帧总数
# 		self._start = None
# 		self._end = None
# 		self._numFrames = 0
#
# 	def start(self):
# 		# 开始计时器
# 		self._start = datetime.datetime.now()
# 		return self
#
# 	def stop(self):
# 		# 停止计时器
# 		self._end = datetime.datetime.now()
#
# 	def update(self):
# 		# 增加在开始和结束间隔期间检查的总帧数
# 		self._numFrames += 1
#
# 	def elapsed(self):
# 		# 返回开始和结束间隔之间的总秒数
# 		return (self._end - self._start).total_seconds()
#
# 	def fps(self):
# 		# 计算每秒(近似)帧数
# 		return self._numFrames / self.elapsed()# import the necessary packages
from imutils.video import FPS
import numpy as np
import argparse
import imutils
import cv2
# 构造参数解析器并解析参数
ap = argparse.ArgumentParser()
# 解析我们的命令行参数。对于这个脚本,我们只需要一个开关 --video ,它是我们输入视频文件的路径。
ap.add_argument("-v", "--video", default="1.mp4",help="path to input video file")
args = vars(ap.parse_args())
# 打开一个指向视频流的指针,并启动FPS定时器
stream = cv2.VideoCapture(args["video"])
fps = FPS().start()  # 启动一个我们可以用来测量 FPS 的计时器# 循环视频文件流中的帧
while True:# 从线程视频文件流中抓取帧(grabbed, frame) = stream.read()# 如果帧没有被抓取,那么我们已经到达了流的末尾if not grabbed:break# 调整帧大小并将其转换为灰度(同时仍保留 3 个通道)frame = imutils.resize(frame, width=450)frame = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)frame = np.dstack([frame, frame, frame])# 在图像中显示一段文本(这样我们就可以公平地对快速方法进行基准测试)cv2.putText(frame, "Slow Method", (10, 30),cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)# 显示帧并更新 FPS 计数器cv2.imshow("Frame", frame)cv2.waitKey(1)fps.update()# 停止定时器,显示FPS信息
fps.stop()
print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))
# 做一些清理工作
stream.release()
cv2.destroyAllWindows()

output

[INFO] elasped time: 13.08
[INFO] approx. FPS: 29.27

在这里插入图片描述

3、加速方法 imutils.video.FileVideoStream

# 导入必要的包
from imutils.video import FileVideoStream
from imutils.video import FPS
import numpy as np
import argparse
import imutils
import time
import cv2# 构造参数解析并解析参数
ap = argparse.ArgumentParser()
ap.add_argument("-v", "--video", default="1.mp4",help="path to input video file")
args = vars(ap.parse_args())
# 启动文件视频流线程并允许缓冲区开始填充
print("[INFO] starting video file thread...")
fvs = FileVideoStream(args["video"]).start()
time.sleep(1.0)
# 启动 FPS 计时器
fps = FPS().start()# 循环播放视频文件流中的帧
while fvs.more():# 从线程视频文件流中抓取帧,调整大小,并将其转换为灰度(同时仍保留 3 个通道)frame = fvs.read()try:frame = imutils.resize(frame, width=450)except:breakframe = cv2.cvtColor(frame, cv2.COLOR_BGR2GRAY)frame = np.dstack([frame, frame, frame])# 在frame上显示队列的大小cv2.putText(frame, "Queue Size: {}".format(fvs.Q.qsize()),(10, 30), cv2.FONT_HERSHEY_SIMPLEX, 0.6, (0, 255, 0), 2)# 显示帧并更新 FPS 计数器cv2.imshow("Frame", frame)cv2.waitKey(1)fps.update()# 停止计时器并显示 FPS 信息
fps.stop()
print("[INFO] elasped time: {:.2f}".format(fps.elapsed()))
print("[INFO] approx. FPS: {:.2f}".format(fps.fps()))
# 做一些清理工作
cv2.destroyAllWindows()
fvs.stop()

output

[INFO] starting video file thread...
[INFO] elasped time: 8.87
[INFO] approx. FPS: 43.19

在这里插入图片描述

帧率从30-提升到了40+

确实有效

4、涉及到的核心库函数

4.1、imutils.video.FPS

import datetimeclass FPS:def __init__(self):# 存储开始时间、结束时间和在开始和结束间隔之间检查的帧总数self._start = Noneself._end = Noneself._numFrames = 0def start(self):# 开始计时器self._start = datetime.datetime.now()return selfdef stop(self):# 停止计时器self._end = datetime.datetime.now()def update(self):# 增加在开始和结束间隔期间检查的总帧数self._numFrames += 1def elapsed(self):# 返回开始和结束间隔之间的总秒数return (self._end - self._start).total_seconds()def fps(self):# 计算每秒(近似)帧数return self._numFrames / self.elapsed()

4.2、imutils.video.FileVideoStream

# import the necessary packages
from threading import Thread
import sys
import cv2# 从 Python 3 导入 Queue 类
if sys.version_info >= (3, 0):from queue import Queue
# 否则,为 Python 2.7 导入 Queue 类
else:from Queue import Queueclass FileVideoStream:def __init__(self, path, queueSize=128):# 初始化文件视频流以及用于指示线程是否应该停止的布尔值self.stream = cv2.VideoCapture(path)self.stopped = False# 初始化存储视频文件帧的队列self.Q = Queue(maxsize=queueSize)def start(self):# 启动一个线程从文件视频流中读取帧t = Thread(target=self.update, args=())t.daemon = Truet.start()return selfdef update(self):# 循环while True:# 如果设置了线程指示器变量,则停止线程if self.stopped:return# 否则,请确保队列中有空间if not self.Q.full():# 从文件中读取下一帧(grabbed, frame) = self.stream.read()# 如果 grabbed 布尔值为 False,那么我们已经到了视频文件的末尾if not grabbed:self.stop()return# 将帧添加到队列中self.Q.put(frame)def read(self):# 返回队列中的下一帧return self.Q.get()def more(self):# 如果队列中还有帧,则返回 Truereturn self.Q.qsize() > 0def stop(self):# 指示应该停止线程self.stopped = True

5、参考

参考学习来自:

  • 基于cv2.VideoCapture 和 OpenCV 得到更快的 FPS之文件篇

  • 基于cv2.VideoCapture 和 OpenCV 得到更快的 FPS之Webcam篇

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

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

相关文章

02 RabbitMQ:下载安装

02 RabbitMQ:下载&安装 1. 下载&安装1.1. 官网1.2. Docker方式1.2.1. 下载镜像1.2.2. 启动1.2.3. 登录验证 1. 下载&安装 1.1. 官网 RabbitMQ: One broker to queue them all | RabbitMQ 1.2. Docker方式 1.2.1. 下载镜像 # docker pull 镜像名称[…

出行方案,智能推荐:用友BIP商旅云6.0推出AI新装备

随着企业业务的不断拓展和员工出行需求的日益复杂化,传统的商旅预订方式已经难以应对,同时企业在商旅成本控制方面也面临着巨大的挑战。为此用友BIP商旅云6.0推出了创新性的AI新装备——智能推荐,以智能分析与精准预测,为企业提供…

RAG调研

一 : RAG解决的问题 1.1 LLM 的局限 幻觉 知识过期 推理过程不透明,不可追踪 1.2 RAG介绍 检索增强生成(RAG)是一种使用外部知识库辅助文本生成的技术。它结合了检索与生成,通过访问外部数据库检索得到有关的信息&…

文件解析漏洞--IIS--Vulhub

文件解析漏洞 一、IIS解析漏洞 用windowserver2003安装IIS测试 1.1 IIS6.X 方法一:目录解析 在网站下建立文件夹的名字为.asp/.asa的文件夹,其目录内的任何扩展名的文件都被IIS当作asp文件来解析并执行。 1.txt文件里是asp文件的语法查看当前时间 方…

【C++】学习笔记——C++11_3

文章目录 十九、C116. 右值引用和移动语义万能引用和完美转发 7. 新的类功能新的默认成员函数类成员变量初始化defaultdelete继承和多态中的final与override关键字 8. 可变参数模板STL容器中的empalce相关接口函数 未完待续 十九、C11 6. 右值引用和移动语义 万能引用和完美转…

5 款最佳电脑照片恢复软件,助您恢复误删除的照片

电脑可以作为存储盒来保存您美好的照片记忆。 然而,病毒、格式化、删除等突发事件可能会夺走你由图片组成的记忆。 我怎样才能从我的计算机恢复已删除的照片? 照片恢复软件就是答案。 本页列出了适用于 Windows 和 Mac 的 5 个最佳图片恢复程序&…

创建个人公私钥对

Windows电脑 本地电脑打开命令输入框,如windows WINR–cmd打开cmd窗口输入ssh-keygen -t rsa -C “Remote dev” ,按三次回车,即可看到本地生成的公私钥进入用户目录,如windows为C:\Users\xxx(个人域账号).ssh,可看到…

【股票价格跨度】python刷题记录

R3-栈和队列-单调栈 有个小思路:如果用栈的话,比如a,b在c前面,然后查找c的跨度的时候,往回搜索,如果b比c小,那就可以把b的跨度加到c上,否则,继续往回查找到a----(思路貌似…

仿RabbitMQ实现消息队列———整体框架

目录 一、项目简介 需求分析 AMQP 特点: AMQP 模型: 交换机类型 持久化 网络通信 二、服务端模块 1、交换机数据管理 2、队列数据管理 3、绑定数据管理 4、消息数据管理 5、虚拟机数据管理 6、路由匹配管理 7、消费者管理 8、信道管理 …

BUGKU-WEB-文件包含

解题思路 你说啥我就干啥:点击一下试试你会想到PHP伪协议这方面去嘛,你有这方面的知识储备吗?看到?fileXXX.php,那不就是典型的文件包含吗?这里需要用的一个伪协议php://filter:是一种元封装器, 设计用于…

SSM学习10:整合MyBatis、MyBatisPlus

SpringBoot整合MyBatis 与创建spring web项目类型,添加上相应依赖 实体类 public class Account {private int id;public int getId() {return id;}public void setId(int id) {this.id id;}public String getName() {return name;}public void setName(String …

Educational Codeforces Round 168 (Rated for Div. 2)(A~D题题解)

A. Strong Password 思路&#xff1a;想要最长的时间&#xff0c;那么肯定就是如果存在前后相同的字母的时候&#xff0c;在中间插入一个不同的字符 &#xff0c;如果不存在前后相同的字符&#xff0c;直接在最后插入一个和原字符串最后一个字符不同的字符 #include <bits/…

Go语言入门进阶语法 | 数据结构 |指针|结构体|数组|切片|Map|方法|接口|错误|io库|泛型

✅作者简介&#xff1a;CSDN内容合伙人、信息安全专业在校大学生&#x1f3c6; &#x1f525;系列专栏 &#xff1a; &#x1f4c3;新人博主 &#xff1a;欢迎点赞收藏关注&#xff0c;会回访&#xff01; &#x1f4ac;舞台再大&#xff0c;你不上台&#xff0c;永远是个观众。…

QGIS 缓冲区交集信息提取

目标 计算出靠近河道的农田数量及位置&#xff0c;具体方法为使用QGIS 中计算出距离线图层&#xff08;代表河道&#xff09;100 米范围内的点&#xff08;代表水田&#xff09;图层中的点。 具体步骤 步骤 1: 创建缓冲区 首先需要基于线图层创建一个缓冲区图层。 打开 QGIS…

JavaScript基础——JavaScript调用的三种方式

JavaScript简介 JavaScript的作用 JavaScript的使用方式 内嵌JS 引入外部js文件 编写函数 JavaScript简介 JavaScript&#xff08;简称“JS”&#xff09;是一种具有函数优先的轻量级&#xff0c;解释型或即时编译型的编程语言。它是Web开发中最常用的脚本语言之一&#x…

软件测试:动态黑盒测试的过程

要成为一个成功的软件测试员&#xff0c;需要采用更结构化的、目标明确的方法继续测试。 本文粗略描述动态黑盒测试的结构化过程 目录 1.动态黑盒测试 拿到需求文档或产品说明书 定义测试用例 test-case 2. 通过性测试和时效性测试 3. 等价类划分 4. 数据测试 边界条件…

【Redis】 拓展:Redis - BigKey方案探讨

BigKey: 用户越多&#xff0c;redis数据越多&#xff0c;bigkey会使得缓存数据更大&#xff0c;网络带宽会被占用&#xff0c;执行效率就低下&#xff0c;高并发的时候吞吐量QPS也会下降。 产生原因&#xff1a; 看如下list&#xff1a; 一个key的内容太大&#xff0c;比如1M&…

【宝藏系列】物联网中常用的十种通信协议

【宝藏系列】物联网中常用的十种通信协议 文章目录 【宝藏系列】物联网中常用的十种通信协议1️⃣MQTT2️⃣CoAP3️⃣AMQP4️⃣XMPP5️⃣LwM2M6️⃣HTTP7️⃣DDS8️⃣Bluetooth Low Energy9️⃣LoRaWAN1️⃣0️⃣NB-IoT 1️⃣MQTT MQTT&#xff08;Message Queuing Telemetry T…

JNDI注入-高版本绕过

参考博客&#xff1a; JNDI注入与动态类加载 探索高版本 JDK 下 JNDI 漏洞的利用方法 - 跳跳糖 (tttang.com) 分析版本 jdk8u201 分析流程 修复 在ldap绕过中&#xff0c;我们讲了LDAP的修复&#xff0c;下面用jdk8u201具体来看下修复。 修复之前&#xff0c;利用是在L…

英文文献翻译方法哪个好?高效率的翻译方法分享

三伏天的酷热也抵挡不住学术人探索知识的脚步&#xff0c;阅读和翻译英文文献几乎已经成为了许多研究者和学者的日常。然而在面对浩如烟海的英文资料时&#xff0c;如何高效准确地进行翻译&#xff0c;成为了亟待解决的问题。 今天我便挖掘到了5款实用的英文文献翻译工具&…