光流的概念:(Opt
它是一种运动模式,这
二维图像的移动相对于
有序的图像可以估计出
光流算法:
它评估了两幅图像的之
Lucas–Kana
这个算法是最常见,最
图像约束方程可以写为 I( x, y, z, t) = I( x + δ x, y + δ y, z + δ z, t + δ t)
I(x, y,z, t) 为在(x,y,z)位
我们假设移动足够的小
-
H.O.T. 指更高阶,在移动足够
- I x V x + I y V y + I z V z = − I t。 写做:
- 这个方程有三个未知量
- 三个未知数但是有多于
- 记作:
-
为了解决这个超定问题
,我们采用最小二乘法 : - or
- 得到:
- 其中的求和是从1到n
-
这也就是说寻找光流可
以通过在四维上图像导 数的分别累加得出。我 们还需要一个权重函数 W(i, j,k), 来突出窗口中心点的坐 标。高斯函数做这项工 作是非常合适的,
这个算法的不足在于它
或者
我们得到:
V x, V y, V z 分别是I(x,y,z
所以
实现Lucas-Kanade 光流算法可以分为三个步骤。
第一步骤为初始化需要跟踪的点。
第二步骤为根据两帧之间的光流来计算由初始化的需要跟踪的点的目标点,为此要先计算出两帧的光流金字塔。
第三步骤为把输入输出点进行互换,还有上一帧与目前帧的互换以及上一帧与当前帧金字塔的互换。
下面我们来具体看一下实现的过程:
//第三步,当第一次进入方法时候,因为输入点的容器是空的,所以并不运行这段代码,而是运行到第一步。当再次进入这个方法时。因为由第一步得到的输出点已经由第二步转换为输入点,所以输入点非空,我们就可以进入下面的方法。该方法时为opencv计算光流跟踪的主要方法。由前一帧与当前帧的图像和两帧的金字塔得到了新的输出点。如果输入点的光流小时。对应的m_status 的值为0。我们可以把没有光流的点进行删除。
if(m_lInputPoints.size())
{
cvCalcOpticalFlowPyrLK(m_prev_grey, m_grey, m_prev_pyramid, m_pyramid,
&m_lInputPoints[0], &m_lOutputPoints[0], m_lInputPoints.size(), cvSize(m_win_size, m_win_size), 3, m_status, 0,
cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 20, 0.03), m_flags);
m_flags |= CV_LKFLOW_PYR_A_READY;
}
//第一步从这里开始,假设我们已经初始化完毕输入点,但是我们要先把输入点放在输出的点的容器内,然后计算该容器内点的光流。
cvFindCornerSubPix(m_grey, &m_lOutputPoints[m_lOutputPoints.size() - 1], 1,
cvSize(m_win_size, m_win_size), cvSize(-1, -1),
cvTermCriteria(CV_TERMCRIT_ITER|CV_TERMCRIT_EPS, 20, 0.03));
//第二步,把得到的输出点的光流放到输入点的容器内,以及互换前一帧与当前帧,还有前一帧与当前帧的光流来进行下次的运算。这里运行完毕,并不运行到第三步,而是退出该方法。并得到下面一帧。
m_lInputPoints= m_lOutputPoints;
CV_SWAP(m_prev_grey, m_grey, m_swap_temp);
CV_SWAP(m_prev_pyramid, m_pyramid, m_swap_temp);
至此,Lucas-Kanade 光流算法已经成功的实现。可以对设定点进行跟踪。但是如何选取这些被跟踪的点来进行最优化的跟踪,是需要解决的下一个问题。