在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 ...
随机推荐
- Linux网络篇,ssh原理及应用
一.对称加密与非对称加密 对称加密: 加密和解密的秘钥使用的是同一个. 非对称加密: 非对称加密算法需要两个密钥:公开密钥(publickey)和私有密钥:简称公钥和私钥 对称加密 对称加密的密 ...
- itoa、ltoa
#include <stdlib.h> /*整形转字符型*/ char * itoa(int value, char *string, int radix) { char tmp[33]; ...
- Struts2-学习笔记系列(11)-使用StrutsTypeConverter
public class UserConvert extends StrutsTypeConverter { @Override public Object convertFromString(Map ...
- Java程序员必备:序列化全方位解析
前言 相信大家日常开发中,经常看到Java对象"implements Serializable".那么,它到底有什么用呢?本文从以下几个角度来解析序列这一块知识点~ 什么是Java ...
- 9.回文数-LeetCode
判断一个整数是否是回文数.回文数是指正序(从左向右)和倒序(从右向左)读都是一样的整数. 示例 1: 输入: 121输出: true示例 2: 输入: -121输出: false解释: 从左向右读, ...
- JavaScript函数作用域和声明提前(3.10.1 page.57)
<h4>3.函数作用域和声明提前</h4> <p> <!--<script type="text/javascript">-- ...
- 【山外问道】Linux UUID的查询方法
本文打印版下载地址 [山外问道]Linux_UUID的查询方法-打印版.pdf 一.查询存储设备的UUID 1.使用blkid命令查看 (1)查询所有存储设备的UUID:blkid. (2)查询指定设 ...
- java第八周课后作业
1.系统小练习 package homework; import java.util.Random; import java.util.Scanner; public class Menu { pub ...
- Python最佳工程实践,建立一个完美的工程项目
在程序开发时候一套好的开发环境和工具栈,可以帮我们极大的提高开发的效率,避免把大量时间浪费在周边琐事上.本文以Python为例,教大家如何快速打造完美的Python项目开发环境:内容涵盖了模块依赖管理 ...
- 最全的 API 接口集合
对于程序员来说,为自己的程序选择一些合适的API并不是那么简单,有时候还会把你搞得够呛,今天猿妹要和大家分享一个开源项目,这个项目汇集了各种开发的api,涵盖了音乐.新闻.书籍.日历等,无论你是从事W ...