python视频延迟严重_利用多进程降低opencv视频延迟处理rtsp视频流

Python多进程opencv

前几天遇到了一个问题,利用opencv程序调取rtsp视频流,因为处理程序要消耗的CPU时间过于长,VideoCapture的read是按帧读取,所以经常导致内存溢出,延时还高得出奇。

所以想到是不是可以利用多进程把读取视频和处理视频分开,这样就可以消除因处理图片所导致的延迟。

所用库

multiprocessing

gc

opencv-python

os

实现方法

一开始是想用多线程,但是因为GIL的存在,像实时处理视频这样的CPU密集型任务多线程等于没用。然后就选择了多进程。

然后要考虑怎样在两个进程中传参的问题:

multiprocessing中有Quaue、SimpleQuaue等进程间传参类,还有Manager这个大管家。

Quaue这一类都是严格的数据结构队列类型

Manager比较特殊,它提供了可以在进程间传递的列表、字典等python原生类型

还要考虑怎样才能达到处理进程可以在读取进程中得到最新的一帧:

其实VideoCapture是一个天生的队列,先进先出。如果要达到实时获得最新帧的目的,就需要栈来存储视频帧,而不是队列。

这样的话,Quaue这一大类就都没有可能了,肯定不能用它来传参。

提到栈突然想到了python的列表,它的append和pop操作完全可以当”不严格“的栈来用。所以顺理成章地multiprocessing.Manager.list就是最好的进程间传参类型。

再就是传参栈自动清理的问题,压栈频率肯定是要比出栈频率高的,时间一长就会在栈中积累大量无法出栈的视频帧,会导致程序崩溃,这就需要有一个自动清理机制:

设置一个传参栈容量,每当达到这个容量就直接把栈清空,再利用gc库手动发起一次python垃圾回收。这样就不会导致严重的内存溢出和程序崩溃。

实现代码

import os

import cv2

import gc

from multiprocessing import Process, Manager

# 向共享缓冲栈中写入数据:

def write(stack, cam, top: int) -> None:

"""

:param cam: 摄像头参数

:param stack: Manager.list对象

:param top: 缓冲栈容量

:return: None

"""

print('Process to write: %s' % os.getpid())

cap = cv2.VideoCapture(cam)

while True:

_, img = cap.read()

if _:

stack.append(img)

# 每到一定容量清空一次缓冲栈

# 利用gc库,手动清理内存垃圾,防止内存溢出

if len(stack) >= top:

del stack[:]

gc.collect()

# 在缓冲栈中读取数据:

def read(stack) -> None:

print('Process to read: %s' % os.getpid())

while True:

if len(stack) != 0:

value = stack.pop()

cv2.imshow("img", value)

key = cv2.waitKey(1) & 0xFF

if key == ord('q'):

break

if __name__ == '__main__':

# 父进程创建缓冲栈,并传给各个子进程:

q = Manager().list()

pw = Process(target=write, args=(q, "rtsp://xxx:xxx@192.168.1.102:554", 100))

pr = Process(target=read, args=(q,))

# 启动子进程pw,写入:

pw.start()

# 启动子进程pr,读取:

pr.start()

# 等待pr结束:

pr.join()

# pw进程里是死循环,无法等待其结束,只能强行终止:

pw.terminate()

实际上这个程序就是把VideoCapture的队列读取改成了栈读取。这个程序可以写成一个类,来作为一个新形式的VideoCapture。

TODO

并没有加入进程锁,只是有一些防止栈空出栈的判断,这样并不能达到进程安全。最好还是加锁

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

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

相关文章

MySQL表级约束和列级约束

MySQL中只要支持六种完整性约束,如表所示:其中check约束是MySQL8中提供的支持。 约束条件 约束描述 primary key 主键约束,约束的值可唯一的标识对应的记录 not null 非空字段的值不能为空 unique 唯一约束,约束1字段的值是…

MySQL外键约束

MySQL外键约束 外键约束(FOREIGN KRY,缩写FK)是用来实现数据库表的参照完整性约束的。 外键约束可以是两张表紧密的结合起来,特别是针对修改或者删除的级联操作时, 会保证数据的完整性。 (注&#xff1…

zookeeper 密码_Dubbo、ZooKeeper介绍

dubbo是一个分布式架构的服务框架,一般结合maven的模块式开发使用。传统的单架构项目,不方便维护和升级;通过maven的模块式开发,就可以把一个单架构的工程,拆封成一个一个的小模块,包括(jar和war)&#xff…

异常--java

java默认的异常处理机制 优点:发生异常后、会给出异常类型、异常提示信息、异常出现的位置 缺点:出现异常后,后续语句不执行了;提示信息太专业,可读性差 解决:try-catch-finally 处理异常;th…

192.168.8.1手机登陆_高端机型都在鼓吹的ufs3.1是什么?对于手机使感受明显吗?...

最近很多朋友留言问,ufs3.1是什么,很重要吗?下面就由小编来给大家介绍一下手机上的ufs3.1是什么!ufs是高端安卓手机,常用的储存协议,就好像我们电脑里的固态硬盘一样,速度越快,打开软…

使用try-catch-finally处理异常---java

package demo02;import java.util.Scanner;public class TestException {public static void main(String[] args) {Scanner input new Scanner(System.in);//输入总分try{System.out.println("请输入总分");int sum input.nextInt();System.out.println("请输…

代码合并工具_11个代码质量审核和管理工具,程序员必备!

「 读者福利!2 TB 各类技术资源免费赠送 」如今,代码质量分析和审核已成为每个企业的基本流程。随着开源代码库使用的增加,安全性和代码质量对于构建高质量软件至关重要。不良的代码不仅会影响代码的可维护性,而且还会在某些情况下…

异常体系----java

一、异常体系 1、error error类层次描述了java运行时系统内部错误和资源耗尽错误,一般指与jvm或动态加载等相关的问题, 如:虚拟机错误,动态链接失败,系统崩溃等。 2、exception 所有异常类的父类,其子…

xy坐标正负方向_【笛卡尔坐标系】

【壹】笛卡尔坐标系(Cartesian coordinates)就是直角坐标系和斜坐标系的统称。相交于原点的两条数轴,构成了平面放射坐标系。如两条数轴上的度量单位相等,则称此放射坐标系为笛卡尔坐标系。两条数轴互相垂直的笛卡尔坐标系,称为笛卡尔直角坐标…

throw和throws的使用

throw和throws的使用 public class Person {private String name;private int age;public Person(){}Person(String name,int age){this.name name;this.age age;}public int getAge() {return age;}public String getName() {return name;}public void setName(String name…

python解决最优化问题_python实现最优化算法

二分法函数详见rres,此代码使该算法运行了两次def asdf(x):rres8*x**3-2*x**2-7*x3return rresi2left0right1while i>0 :i i-1ans 0.1mid1 (left right ans) / 2mid2 (left right - ans) / 2aasdf(mid1)casdf(mid2)if a > c :right mid1else :left m…

为什么需要包装类?

1、某些方法的参数必须是对象,为了让基本数据类型的数据能作为参数,提供包装类。 2、包装类还可以提供更多的功能 3、其他特别重要的功能:比如可以实现字符串和基本数据类型之间的转换 认识一下包装类吧! package demo05;impor…

python自动计算多个教学班的优秀率_第二个月课堂009python之总结(002)

python7天的总结------------------------------------------------------------------------------------------------评价:1、函数 def 自定义行数和内建函数2、re模块3、python3和python的去别4、字典,元组,列表,元组&#xf…

一句话概括自动装箱/拆箱

自动装箱过程是通过调用包装类的valueOf()方法实现的,二自动拆箱过程是通过调用包装类的xxxValue()方法实现的(xxx代表对应的基本数据类型,如intValue,doubleValue等)。 …

python loop call soon_python3-asyncio 学习笔记 1 -- call_soon

最近在学习python3 的 asyncio, 特将学习笔记记录于此.先来个简单的例子:import asynciodef hello_world(loop):print(Hello World)loop.stop()loop asyncio.get_event_loop()# Schedule a call to hello_world()loop.call_soon(hello_world, loop)# Blocking call interrupte…

2021-05-24

String类的使用 package demo07;import java.util.Locale; import java.util.function.BiConsumer;public class TestString {public static void main(String[] args) {//1.创建一个String对象String str "abcDEfghijkL";//2.操作该String对象//2.1最简单的方法Sy…

StringBuffer和StringBuild

StringBuffer和StringBuild两个类的区别主要是: StringBuffer JDK1.0提供的类,线程安全,做线程同步检查,效率较低。 StringBuild JDK1.5提供的类,线程不安全,不做线程同步检查,因此效率较高。…

python背单词游戏_Python基础-背单词游戏

Hangman直译为“吊死鬼”,是一个猜单词的双人游戏。由一个玩家想出一个单词或短语,另一个玩家猜该单词或短语中的每一个字母。第一个人抽走单词或短语,只留下相应数量的空白与下划线。想字的玩家一般会画一个绞刑架,当猜字的玩家猜…

Date类练习

package demo09;import java.util.Date;public class TestDate {public static void main(String[] args) {//获取当前时间Date now new Date();//输出当前时间System.out.println(now.toString());System.out.println(now.toLocaleString());System.out.println(now.getYear(…

全连接层的作用_python构建计算图2——全连接层

(好久不更~)前文中,参照tensorflow的方式实现了简单的自动求导。接下来要在自动求导的基底(模板)上搭建简单的bp神经网络。计算图前文曾多次提到计算图,关于什么是计算图,有很多种说法。既然它被…