文章目录
- 一、运动检测
一、运动检测
1.1 检测思路
目标跟踪是对摄像头视频中的移动目标进行定位的过程。实时目标跟踪是许多计算机视觉应用的重要任务,如监控、基于感知的用户界面、增强现实、基于对象的视频压缩以及辅助驾驶等。
好久之前做过一次人脸检测,里面涉及到了目标跟踪。
这次实现一般的运动物体检测,关于实现视频目标跟踪的方法有很多,当跟踪所有移动目标时,帧之间的差异会变的有用;当跟踪视频中移动的手时,基于皮肤颜色的均值漂移方法是最好的解决方案;当知道跟踪对象的一方面时,模板匹配是不错的技术。
常用的目标跟踪方法有:
- 背景法(本次用的方法)是:将一幅图作为背景,让后和每一帧对比;缺点是一开始存入的背景可能随光照变法而造成错误,但是可以用在光照环境稳定的地方,优点是可以检测之前背景没有的景象;
- 差帧法是:将前一帧和后一帧进行对比;缺点是无法对运动后突然又静止的景象进行识别,优点是光照不影响;
1.2 代码
二、运动方向预测
2.1 关键点(角点)追踪 goodFeaturesToTrack()
2.2 光流法
光流法的工作原理基于如下假设:
- 连续的两帧图像之间,目标像素亮度不变。
- 相邻的像素之间有相似的运动。
考虑第一帧的像素 ,表示在时间t时像素 的值。在经过时间 后,此像素在下一帧移动了 。因为这些像素是相同的,而且亮度不变,表示成,。
假设移动很小,使用泰勒公式可以表示成:
H.O.T是高阶无穷小。由第一个假设和使用泰勒公式展开的式子可以得到:
设: 同理得 和
令 ;
光流方程: 其中 和 分别是图像的梯度, 是是图像沿着时间的梯度。但是 和 是未知的,我们没办法用一个方程解两个未知数,那么就有了lucas-kanade这个方法来解决这个问题。
光流是进行视频中运动对象轨迹标记的一种很常用的方法,在OpenCV中实现光流也很容易。
cv2.calcOpticalFlowPyrLK
函数计算一个稀疏特征集的光流,使用金字塔中的迭代 Lucas-Kanade 方法。
返回值:
- nextPtrs 输出一个二维点的向量,这个向量可以是用来作为光流算法的输入特征点,也是光流算法在当前帧找到特征点的新位置(浮点数)
- status 标志,在当前帧当中发现的特征点标志status==1,否则为0
- err 向量中的每个特征对应的错误率
其他输入值:
- status 与返回的status相同
- err 与返回的err相同
- winSize 在计算局部连续运动的窗口尺寸(在图像金字塔中)
- maxLevel 图像金字塔层数,0表示不使用金字塔
- criteria 寻找光流迭代终止的条件
- flags 有两个宏,表示两种计算方法,
OPTFLOW_USE_INITIAL_FLOW
表示使用估计值作为寻找到的初始光流,
OPTFLOW_LK_GET_MIN_EIGENVALS
表示使用最小特征值作为误差测量 - minEigThreshold 该算法计算光流方程的2×2规范化矩阵的最小特征值,除以窗口中的像素数; 如果此值小于minEigThreshold,则会过滤掉相应的功能并且不会处理该光流,因此它允许删除坏点并获得性能提升。
实现原理:
首先选取第一帧,在第一帧图像中检测Shi-Tomasi角点,
然后使用LK算法来迭代的跟踪这些特征点。迭代的方式就是不断向cv2.calcOpticalFlowPyrLK()中传入上一帧图片的特征点以及当前帧的图片。
函数会返回当前帧的点,这些点带有状态1或者0,如果在当前帧找到了上一帧中的点,那么这个点的状态就是1,否则就是0。
实现流程:
- 加载视频。
- 调用 GoodFeaturesToTrack 函数寻找兴趣点(关键点)。
- 调用 CalcOpticalFlowPyrLK 函数计算出两帧图像中兴趣点的移动情况。
- 删除未移动的兴趣点。
- 在两次移动的点之间绘制一条线段。
这是一个裸眼3D视频动画