在TX2上多线程读取视频帧进行caffe推理
参考文章:Multi-threaded Camera Caffe Inferencing
背景
一般在TX2上部署深度学习模型时,都是读取摄像头视频或者传入视频文件进行推理,从视频中抽取帧进行目标检测等任务。但对于较大的模型,推理的速度是小于视频的帧率的。如果我们使用单线程进行处理,即读取一帧检测一帧,推理会堵塞视频的正常传输,表现出来就是摄像头视频有很大的延迟,如果是对实时性要求较高,这种延迟是难以接受的。因此,采用多线程的方法,将视频读取与深度学习推理放在两个线程里,互不影响,达到实时的效果。
在上篇博客 在Jetson TX2上显示摄像头视频并使用python进行caffe推理 实际上使用了单线程。本篇博客采用两个不同的线程,一个进行摄像机捕获,一个进行caffe推理。
程序下载: tegra-cam-caffe-threaded.py
线程间工作的分配
将摄像机捕获图像放入子线程,主线程完成其余所有工作,包括caffe初始化、推理和图像呈现。下面是启动子线程进行摄像机图像捕获并完成后终止它的代码片段
import threading
#
# This 'grab_img' function is designed to be run in the sub-thread.
# Once started, this thread continues to grab new image and put it
# into the global IMG_HANDLE, until THREAD_RUNNING is set to False.
#
def grab_img(cap):
global THREAD_RUNNING
global IMG_HANDLE
while THREAD_RUNNING:
_, IMG_HANDLE = cap.read()
def main():
......
# Start the sub-thread, which is responsible for grabbing images
THREAD_RUNNING = True
th = threading.Thread(target=grab_img, args=(cap,))
th.start()
......
# Terminate the sub-thread
THREAD_RUNNING = False
th.join()
线程间的同步
多线程读取视频帧进行caffe推理适合经典的生产者-消费者模型,如下图

摄像机图形捕获线程充当生产者,主线程(caffe推理)充当消费者。我们需要设计一个队列来处理生产和消费,我们需要监视队列的满度,以决定是否需要删除项目和限制消费者。
在我们的例子中,我们认为生产者(以30帧每秒捕获摄像机)可能比消费者(caffe推理,其速率取决于模型的复杂程度)更快。我们需要跟踪相机捕获线程产生的最新图像帧,通过python中的垃圾收集器,甚至不需要使用互斥锁来保留最新帧。
我使用一个全局变量 IMG_HANDLE 来引用图像帧,每当生产者(摄像机捕获线程)从相机获取新帧时,这个 IMG_HANDLE 就会更新。另一方面,每当消费者(caffe推理线程)准备处理下一个图像帧,它就取消对 IMG_HANDLE 的引用,从而总是获得最新的图像帧。

帧2、4、5被丢弃时,python垃圾回收器自动回收,因为程序不再有对他们的引用。事实上,一旦caffe推理线程完成,帧1、3、6也会被垃圾收集。
程序的使用
python3 tegra-cam-caffe-threaded.py --usb --vid
讨论与总结
但是,这种多线程设计是否有助于提高caffe推理脚本的吞吐量?也就是说能否通过这种设计推断出更多的帧/秒(fps)。答案可能是否定的。例如在最初的单线程设计中,假设摄像机捕获图像生成图像帧的速度比caffe推理的速度快,然后cap.read()总是立即返回(非阻塞方式)。因为总是有图像帧等待处理,更具体的说,旧的图像帧要么在v4l2驱动缓冲区中排队,要么在gstream/opencv堆栈中排队,然后又由cap.read()立即返回。那么旧的相框很可能不是相机捕捉到的最新的相框。
那么,这种多线程设计的真正好处是什么呢?
在tegra-cam-caffe-threaded.py 中,我们只在全局变量IMG_HANDLE中保留最新的一个图像帧。因此,caffe推理(主)线程总是获取最新抓取的图像帧进行处理。总之,我认为这种多线程设计有助于改善caffe推理程序的延迟。
在TX2上多线程读取视频帧进行caffe推理的更多相关文章
- TX2之多线程读取视频及深度学习推理
背景 一般在TX2上部署深度学习模型时,都是读取摄像头视频或传入视频文件进行推理,从视频中抽取帧进行目标检测等任务.对于大点的模型,推理的速度是赶不上摄像头或视频的帧率的,如果我们使用单线程进行处理, ...
- 在Jetson TX2上显示摄像头视频并使用python进行caffe推理
参考文章:How to Capture Camera Video and Do Caffe Inferencing with Python on Jetson TX2 与参考文章大部分都是相似的,如果 ...
- How to read video frames in hadoop?如何在Hadoop中读取视频帧?
To process specialized file formats (such as video) in Hadoop, you'd have to write a custom InputFor ...
- python opencv 按一定间隔截取视频帧
前言关于opencvOpenCV 是 Intel 开源计算机视觉库 (Computer Version) .它由一系列 C 函数和少量 C++ 类构成,实现了图像处理和计算机视觉方面的很多通用算法. ...
- 使用JavaCV实现读取视频信息及自动截取封面图
概述 最近在对之前写的一个 Spring Boot 的视频网站项目做功能完善,需要利用 FFmpeg 实现读取视频信息和自动截图的功能,查阅资料后发现网上这部分的内容非常少,于是就有了这篇文章. 视频 ...
- opencv 读取视频内容写入图片帧
现在主要把自己平时用到的opencv功能记录到博客,一方面方便自己有时间来回顾,另一方便提供给大家一个参考. opencv 读取视频内容,把视频帧每一帧写成图片,存入电脑中.这个步骤是许多数据处理的基 ...
- 在Jetson TX2上捕获、显示摄像头视频
参考文章:How to Capture and Display Camera Video with Python on Jetson TX2 与参考文章大部分都是相似的,如果不习惯看英文,可以看看我下 ...
- python_Opencv_读取视频
目标 • 学会读取视频文件,显示视频,保存视频文件 • 学会从摄像头获取并显示视频 • 你将会学习到这些函数:cv2.VideoCapture(),cv2.VideoWrite()用摄像头捕获视频 使 ...
- opencv学习之路(2)、读取视频,读取摄像头
一.介绍 视频读取本质上就是读取图像,因为视频是由一帧一帧图像组成的.1秒24帧基本就能流畅的读取视频了. ①读取视频有两种方法: A. VideoCapture cap; cap.open(“1.a ...
随机推荐
- redis 练习 a的数据库数据迁移到b数据库
思路 1.从a redis中获取所有的key 2.判断key的类型 3.根据key的类型,判断使用的是set/hset类型 4.set到b redis中(写入到b redis中)
- String 对象-->toLowerCase() 方法
1.定义和用法 将字符串中所有的大写字符转换成小写字符,小写字符不变 返回转换后的结果字符串 语法: string.toLowerCase() 注意:不会改变字符串本身,仅以返回值的形式返回结果 举例 ...
- python selenium使用
安装selenium #Python pip install selenium #Anaconda3 conda install selenium 下载浏览器版本对应的驱动文件 chrome chro ...
- NumPy学习1:基本概念
NumPy的数组类被称作 ndarray .通常被称作数组.注意numpy.array和标准Python库类array.array并不相同,后者只处理一维数组和提供少量功能.更多重要ndarray对象 ...
- Android Them+SharedPreferences 修改程序所有view字体颜色、大小和页面背景
有这么一个需求,可以对页面的样式进行选择,然后根据选择改变程序所有字体颜色和页面背景.同时下一次启动程序,当前设置依然有效. 根据需求,我们需要一种快速,方便,有效的方式来实现需求,然后可以通过And ...
- Java匹马行天下之JavaSE核心技术——异常处理
Java匹马行天下之JavaSE核心技术——异常处理 异常的简介 在Java中,异常就是Java在编译.运行或运行过程中出现的错误. 程序错误分为三种:编译错误.运行时错误和逻辑错误 编译错误是因为程 ...
- V - Largest Rectangle in a Histogram HDU - 1506
两种思路: 1 单调栈:维护一个单调非递减栈,当栈为空或者当前元素大于等于栈顶元素时就入栈,当前元素小于栈顶元素时就出栈,出栈的同时计算当前值,当前值所包含的区间范围为从当前栈顶元素到当前元素i的距离 ...
- 快速搭建网站信息库(小型Zoomeye)
前言:本来是不想重复造车轮的,网上资料有开源的fofa,和一些设计.有的架设太复杂了,好用东西不会用,整个毛线.还有的没有完整代码. 设计方案: 测试平台:windows 测试环境:php ...
- 重启mysql服务
重启mysql 启动mysql: 方式一:sudo /etc/init.d/mysql start 方式二:sudo service mysql start 停止mysql: 方式一:sudo /et ...
- mybatis源码配置文件解析之三:解析typeAliases标签
在前边的博客在分析了mybatis解析settings标签,<mybatis源码配置文件解析之二:解析settings标签>.下面来看解析typeAliases标签的过程. 一.概述 在m ...