目录
1 项目介绍
2 代码分析
2.1 环境安装
2.2 utils.py
2.2.1 __init__()
2.2.2 start()
2.2.3 stop()
2.2.4 update()
2.2.5 elapsed()
2.2.6 fps()
2.3 multi_object_tracking_slow.py
2.3.1 导入库
2.3.2 定义参数
2.3.3 定义标签
2.3.4 读取模型
2.3.5 读取视频
2.3.6 定义writer
2.3.7 调用FPS中的start()
2.3.8 进入循环
2.3.9 计算数据
2.3.10 释放视频保存的writer
2.3.11 关闭所有窗口并释放视频
我们的效果是这样的
思路是先用DNN检测出第一帧中有的人,然后使用dlib进行目标追踪
项目中有如下的问题没有解决
项目由两个代码构成
首先要安装一个库 dlib,这个是专门做人脸,人体的,这个必须要用whl装,要不然装不上,如果自己用官方提供的gz编译一遍也能装,我们这就不费劲了
我们先总体看一下utils.py
导入库为datetime,这个是处理时间用的,python内置库
这个函数实例化后自动执行,内容为定义_start为None,_end为None,_numFrame为0
令_start这个变量为现在的时间,返回实例化对象本身
令_end这个变量为现在的时间
令_numFrames自加1,这个是统计帧数用的,应该会放在循环中
先用结束时间-开始时间,然后都汇总成分钟数
total_seconds()是datetime内置方法,作用是将时间转换为分钟数
用帧数/总时间,返回每秒平均帧数
我们有如下参数
我们的模型可以识别下面这些物体,我们只使用person这个类
我们设置为None,这个变量为是否储存视频,下面会用到
开始计时并实例化(start()的返回值是对象本身)
2.3.8.1 读取视频
2.3.8.2 图像预处理
更改图像大小并将其通道转变为RGB
2.3.8.3 视频录制
首先进入判定如果output不为None,writer为None则开始写入,视频编码格式为MJPG,存放在output的地方,30帧,尺寸为(frame.shape[1],frame.shape[0]),彩色图像(True)
2.3.8.4 检测位置
如果trackers里面没有东西,我们就需要向其中放追踪器,运行的首次判定一定会走这个分支的
读取视频的宽与高
图像预处理,frame要处理的图像,0.007843缩放系数(这个值是1/127,因为模型训练时是这样做的,我们现在也这样做),(w,h)尺寸,127.5均值,它这里是R,G,B三个通道都为127.5
输入,之后得出结果detecions
我们现在看一下detections的shape
我们可以看到前面两个shape(前面两个1)是没有内容的,后面这个6的意思是倒数第二维有6个元素(6个中括号),这个表示检测出来了6个物体,6个中括号内又有七个值,七个值中的第二个值的识别出来的标签号,第三个值是置信率,(第四个值与第五个值)是目标检测矩形的左上角点(x1,y1)分别除宽与高后的值(也就是左上角点坐标的两个值分别相对于整个图宽高的比例),(第六个值与第七个值)是目标检测矩形的右下角点(x2,y2)分别除宽与高后的值(也就是右下角点坐标的两个值相对于整个图的宽高的|比例)
2.3.8.5 遍历检测结果
我们看一下confidence
这个取的是置信率,如果我们判定的置信率大于我们设定的,我们进入判定
我们设定的置信率为0.2
进入分支后,我们提取识别到的标签,然后与之前定义的CLASSES(所有标签)的索引进行对比,入宫检测出来的标签不是persion(人)则跳出盖茨循环
下面就是检测出是人标签的情况,提取detections中3:7的元素,分别乘图像的宽和高,之后将四个值定义为startX,startY,endX,endY
这个里面用到了astype(),这个方法,我们举个例子
import numpy as np
a = np.array([1.1,2.3,3.4,4.1])
b = a.astype('int')
print(b)
print(type(b))
print()
a = np.array([1.1,2.3,3.4,4.1])
b = a.astype('str')
print(b)
print(type(b))
astype()可以将数组中的元素改变为指定的变量类型,我们上面的项目中乘积后依然会有多位浮点数,我们使用astype(int),这样所有的元素就为整形了
2.3.8.6 目标追踪
之后使用dlib进行追踪,代码中是3步依次对应下面三行
我们看一下这个t
是tracker对象
2.3.8.7 保存结果
我们将结果保存起来,labels现在里面有多个person字符,trackers中有多个tracker对象
2.3.8.8 绘制第一帧图像
画上框,写上字
2.3.8.9 直接追踪
当我们上面这个分支执行之后,我们就有了一组追踪器,现在我们的这个判定不再生效
进入我们的else分支,我们使用update对每一帧进行追踪,使用get_position()获取追踪器的位置,然后将其定义为startX,startY,endX,endY,然后画出来
此时这个大分支就走完了,我们可以把带有追踪效果的视频保存下来
会保存在我们的参数output中,如果要保存我们需要在参数中写上路径与文件名
无论是否保存,我们最终需要给它显示出来
每运行一帧我们都执行一次utils中的update()以计算总帧数
此时循环结束了,我们使用stop()记录当前时间,然后使用elapsed()计算总时间,之后使用fps()计算每秒展示多少帧(这个值是平均的)
我们最后看一下普通处理的FPS
我们可以看到大致是1s十帧,这个从观感上是有点慢的,下一章我们对上面的过程进行加速处理