上一章我们对人体追踪进行了普通处理,生成了追踪的结果,但是我们运行的时候感觉视频播放速度很慢,在这里我们对人体追踪进行加速处理,还是同样的素材,同样的环境,同样的模型
目录
1 导入库
在这里我们新加入了multiprocessing这个库,这个库是python自带的库,是操作多进程用的
2 定义start_tracker()
我们使用多进程来提升结果的流畅性,此时我们定义的函数start_tracker()就是进程中需要进行的任务
要传入的参数为
- box 检测出来的物体矩形
- label 检测标签
- rgb 检测图像
- inputQueue 输入队列,这个是专门放图片的
- outputQueue 输出队列,这个是放标签与追踪结果的矩形两角点的
一个进程中会有若干个队列,我们当前就有两个队列inputQueue和outputQueue,队列对象使用get()获取信息,使用put()存放信息,只有先put(存放)之后才能get(获取)
在这里我们仅仅先定义,下面使用的时候会再次看一遍参数
2.1 生成追踪结果
2.2 进入循环
首先获取视频每一帧的内容
如果获取到的图片不为空,就对该张图片进行追踪,然后获取位置,赋值给startX,startY,endX,endY这四个值,然后将label(我们定义函数时传入的参数),与(startX,startY,endX,endY)存放在队列outputQuene中
3 定义参数
4 定义两个队列的集合
这里注意后面加s了,这个是遍历用的,而不是队列的对象,这列表里面放的是队列的对象
5 定义标签
6 读模型
7 读视频
8 定义是否保存
9 开始计时
10 进入循环
10.1 读视频每一帧
10.2 图像预处理
10.3 判定是否保存
10.4 检测位置
这里的判定条件改变了,判定条件为inputQueues为空,也就是第一帧的时候
10.4.1 遍历结果
前面的过程都一样,先对置信,然后对标签,之后获取识别的两个角点
之后是不同的地方,我们把两个角点的坐标捏成了变量bb,之后创建iq与oq两个队列,此时这两个队列都是空的,因为我们没有向其中放任何东西,之后我们将空的iq对象放入inputQueues这个列表中,将空的oq对象放入outputQueues中
之后创建进程p,我们这段代码是在遍历结果的for循环中的,所以每获得一个正确的结果,我们就创建一个进程p
multiprocessing.Process是创建进程对象
target是进程要执行的任务,此处我们定义为start_tracker,这个就是我们一开始定义的函数
参数(args)为bb(角点坐标,对应上面的box),label(标签),rgb(图像),iq(输入队列,专门放图像用的),oq(输出队列,放标签与追踪角点用的)
p.daemon 这个默认值为False,如果设置为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置
p.start() 开始进程
- 守护进程 守护进程_百度百科
之后画出我们第一帧的检测结果并写上字
10.5 进行追踪
此时我们已经开启了进程,我们现在在多个进程中会不断的运行start_tracker()这个函数,但由于我们没有在iq中放入图像,所以inputQueue get到的东西都是None,卡在这一步
此时我们放入rgb(当前帧图像)
这样我们的outputQueue就有了结果,之后我们在oq中get
我现在画个图解释一下当前的状况,比如我们现在检测到四个人,检测到四个人就代表有了四个进程,之后分别将图像的每一帧作为输入给这四个进程
之后我们将每一个进程的结果都画出来
后面的代码就相同了,我们简单过一下
10.6 保存视频
10.7 展示图像
10.8 记录总帧数
11 停止计时
12 显示时间与FPS
13 释放视频存储对象
14 关闭所有窗口并释放视频流
我们最后看一下FPS
每秒多了两帧,我们现在追踪的目标只有四个,如果我们追踪的目标更多的时候,使用多进程效果就会更加明显,跟硬件也有关系,我们自己可以试一下
15 注意
当我们创建进程时
我们需要将其放在main函数中,不然有可能会有错误