OpenCV目标跟踪(二)-LK光流法

本文介绍了光流的基本概念,重点阐述了Lucas-Kanade(LK)光流算法,包括其三个基本假设和基于图像金字塔的改进方法。讨论了OpenCV中的cvCalcOpticalFlowPyrLK函数在目标跟踪中的应用,并提供了示例程序及运行结果。文章末尾推荐了深入理解LK算法的博客资源。
摘要由CSDN通过智能技术生成

这几天主要看了光流的有关内容,下面就关于光流的有关内容进行个简单的总结。
所谓的光流是一种运动模式,这种运动模式即是指一个物体、表面、边缘在一个视角下由一个观察者和背景之间形成的明显移动。在如下的图中给出了光流的直观解释。
这里写图片描述

这里的每个像素都与速度相关联,这样得到的即是稠密光流,在光流中主要分为稠密光流和稀疏光流,相对于稠密光流,稀疏光流的计算则需要在跟踪之前指定一组点,下面我主要介绍下比较流行的基于金字塔的Lucas-Kanade光流算法。

(1)LK算法
LK算法其实是基于三个假设进行的:

a.亮度恒定。图像场景中目标的像素在帧间运动时外观上保持不变,对于灰度图像,需要假设像素被逐帧跟踪时其亮度不发生变化。这样的假设,我们可以用下面的数学表达式来表达:
这里写图片描述
也即是亮度I对时间t的偏导数为0,即:
  这里写图片描述

b.时间连续或者运动是“小运动”。图像的运动随时间的变化比较缓慢。实际应用中指的是时间变化相对于图像中运动的比例要足够小,这样目标在帧间的运动就比较小。
这条假设,就只能针对小运动,但实际上的运动往往是比较大的运动,这时我们就会将现在的LK算法加以改进,采用基于图像金字塔的LK算法,这在后面将进一步进行介绍。
针对这条假设,换句话说,可以将运动的变化看成是亮度对时间的导数,此时将f(x,t)用I(x(t),t)替换,应用偏微分的链式法则即可得到:
这里写图片描述

我们接着将从一维的情况过渡到二维的情况下去分析即得到:

这里写图片描述
这里写图片描述

c.空间一致性假设。一个场景中同一表面上邻近的点具有相似的运动,在图像平面上的投影也在邻近区域。
下面的这幅图,直观的给出了上述的三条假设。

这里写图片描述

但垂直光流由孔径问题产生,即用小孔或者小窗口去测量运动。这种情况下,我们通常只能观测到边缘而观测不到角点,而只靠边缘是不足以判断整个物体是如何运动的,如下图解释的那样:

这里写图片描述

单像素是不能解决整个运动的,要想解决这样的一个问题,需用到光流的最后一个假

lk光流法是一种基于前后两幅图像间像素点的运动信息来估计运动的算法。它利用图像中像素点的亮度变化来推断这个点的运动方向和大小。lk光流法广泛应用于计算机视觉领域中的运动估计、目标跟踪等任务中。 在Python中,我们可以使用OpenCV库来实现lk光流法。首先,我们需要导入OpenCV库和NumPy库。 ```python import cv2 import numpy as np ``` 然后,我们读取两张连续的图像,并将其转为灰度图像。 ```python frame1 = cv2.imread('frame1.jpg') frame2 = cv2.imread('frame2.jpg') gray1 = cv2.cvtColor(frame1, cv2.COLOR_BGR2GRAY) gray2 = cv2.cvtColor(frame2, cv2.COLOR_BGR2GRAY) ``` 接下来,我们可以使用`cv2.calcOpticalFlowPyrLK()`函数来计算光流。 ```python # 设置lk光流法的参数 lk_params = dict(winSize=(15, 15), maxLevel=2, criteria=(cv2.TERM_CRITERIA_EPS | cv2.TERM_CRITERIA_COUNT, 10, 0.03)) # 计算光流 corners1 = cv2.goodFeaturesToTrack(gray1, 25, 0.01, 10) corners2, status, error = cv2.calcOpticalFlowPyrLK(gray1, gray2, corners1, None, **lk_params) ``` 最后,我们可以根据计算得到的光流向量来绘制箭头表示运动方向。 ```python # 绘制光流箭头 mask = np.zeros_like(frame1) for i, (new, old) in enumerate(zip(corners2, corners1)): a, b = new.ravel() c, d = old.ravel() mask = cv2.line(mask, (a, b), (c, d), (0, 255, 0), 2) frame = cv2.circle(frame2, (a, b), 5, (0, 0, 255), -1) output = cv2.add(frame2, mask) ``` 以上就是使用Python实现lk光流法的基本流程。当然,除了以上描述的方法外,还可以根据具体的需求进行参数调整和算法优化。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值