金字塔LK光流法
最近看的一篇论文中有金字塔LK光流法,于是看了些东西,整理一下。
光流法
光流(optical flow)是空间运动物体在观察成像平面上的像素运动的瞬时速度。光流法是利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存在的对应关系,从而计算出相邻帧之间物体的运动信息的一种方法。通常将二维图像平面特定坐标点上的灰度瞬时变化率定义为光流矢量。
光流计算基于物体的运动的光学特性,提出了两个假设:
- 运动物体的灰度值在很短的时间间隔内保持不变;
- 给定邻域内的速度向量变化缓慢;
假设一个像素点为
(
x
,
y
)
(x,y)
(x,y),
I
(
x
,
y
,
t
)
I(x,y,t)
I(x,y,t)为该像素点
t
t
t时刻的的亮度,用
u
(
x
,
y
)
u(x,y)
u(x,y)和
v
(
x
,
y
)
v(x,y)
v(x,y)来表示该像素点在水平和竖直方向上的速度分量:
u
=
d
x
d
t
;
v
=
d
y
d
t
u=\frac{d x}{d t} ;\quad v=\frac{d y}{d t}
u=dtdx;v=dtdy
那么,在时间间隔很短的情况下(比如相邻两帧),
u
u
u和
v
v
v便可以看作各自方向上的位移。
我们假设时间间隔为
Δ
t
\Delta t
Δt,那么此时的亮度即为
I
(
x
+
Δ
x
,
y
+
Δ
y
,
t
+
Δ
t
)
I(x+\Delta x,y+\Delta y,t+\Delta t)
I(x+Δx,y+Δy,t+Δt)。在假设
Δ
t
\Delta t
Δt很小的前提下,将其泰勒展开,并舍弃掉二阶无穷小项:
I
(
x
+
Δ
x
,
y
+
Δ
y
,
t
+
Δ
t
)
=
I
(
x
,
y
,
t
)
+
∂
I
∂
x
Δ
x
+
∂
I
∂
y
Δ
y
+
∂
I
∂
t
Δ
t
(1)
I(x+\Delta x, y+\Delta y, t+\Delta t)=I(x, y, t)+\frac{\partial I}{\partial x} \Delta x+\frac{\partial I}{\partial y} \Delta y+\frac{\partial I}{\partial t} \Delta t \tag{1}
I(x+Δx,y+Δy,t+Δt)=I(x,y,t)+∂x∂IΔx+∂y∂IΔy+∂t∂IΔt(1)
根据假设(1):运动物体的灰度值在很短的时间间隔内保持不变,可得
I
(
x
+
d
x
,
y
+
d
y
,
t
+
d
t
)
=
I
(
x
,
y
,
t
)
I(x+d x, y+d y, t+d t)=I(x, y, t)
I(x+dx,y+dy,t+dt)=I(x,y,t),所以公式(1)中的
∂
I
∂
x
Δ
x
+
∂
I
∂
y
Δ
y
+
∂
I
∂
t
Δ
t
=
0
\frac{\partial I}{\partial x} \Delta x+\frac{\partial I}{\partial y} \Delta y+\frac{\partial I}{\partial t} \Delta t=0
∂x∂IΔx+∂y∂IΔy+∂t∂IΔt=0,即
−
∂
I
∂
t
=
∂
I
∂
x
d
x
d
t
+
∂
I
∂
y
d
y
d
t
=
∂
I
∂
x
u
+
∂
I
∂
y
v
−
I
t
=
I
x
u
+
I
y
v
−
I
t
=
[
I
x
I
y
]
[
u
v
]
(2)
\begin{array}{c} -\frac{\partial I}{\partial t}=\frac{\partial I}{\partial x} \frac{d x}{d t}+\frac{\partial I}{\partial y} \frac{d y}{d t}=\frac{\partial I}{\partial x} u+\frac{\partial I}{\partial y} v \\ -I_{t}=I_{x} u+I_{y} v \\ -I_{t}=\left[\begin{array}{ll} I_{x} & I_{y} \end{array}\right]\left[\begin{array}{l} u \\ v \end{array}\right] \tag{2} \end{array}
−∂t∂I=∂x∂Idtdx+∂y∂Idtdy=∂x∂Iu+∂y∂Iv−It=Ixu+Iyv−It=[IxIy][uv](2)
其中,
I
x
I_x
Ix和
I
y
I_y
Iy是图像在
(
x
,
y
)
(x,y)
(x,y)处的梯度,
I
x
=
I
(
x
+
1
,
y
)
−
I
(
x
,
y
)
I_x=I(x+1,y)-I(x,y)
Ix=I(x+1,y)−I(x,y),
I
y
=
I
(
x
,
y
+
1
)
−
I
(
x
,
y
)
I_y=I(x,y+1)-I(x,y)
Iy=I(x,y+1)−I(x,y),
I
t
I_t
It是图像在
(
x
,
y
)
(x,y)
(x,y)处关于时间
t
t
t的导数,
I
t
≈
(
I
(
x
,
y
,
t
)
−
I
(
x
,
y
,
t
−
1
)
)
I_{t} \approx(I(x, y, t)-I(x, y, t-1))
It≈(I(x,y,t)−I(x,y,t−1))。
这就是基本的光流约束方程。但此时要求出
u
u
u和
v
v
v,却只有一个方程。一个方程两个未知量,这是没法求解的。于是便有了LK光流法。
LK光流法
LK光流法提出了第三个假设:邻域内光流一致,即一个场景中的同一表面的局部邻域内具有相似的运动,在图像平面上的投影也在邻近区域,且邻近点速度一致(邻域内所有像素点光流一样)。
这时,邻域
w
×
w
w\times w
w×w内所有像素点(假设为
k
k
k个)运动一致,那么公式(2)便有
k
k
k个:
{
I
1
x
u
+
I
1
y
v
=
−
I
1
t
I
2
x
u
+
I
2
y
v
=
−
I
2
t
⋯
I
k
x
u
+
I
k
y
v
=
−
I
k
t
\left\{\begin{array}{l} I_{1 x} u+I_{1 y} v=-I_{1 t} \\ I_{2 x} u+I_{2 y} v=-I_{2 t} \\ \cdots \\ I_{k x} u+I_{k y} v=-I_{k t} \end{array}\right.
⎩⎪⎪⎨⎪⎪⎧I1xu+I1yv=−I1tI2xu+I2yv=−I2t⋯Ikxu+Ikyv=−Ikt
但
k
k
k个方程,两个未知量,也是无法求解的。所以只能找出该方程的最优解。
记:
A
=
[
[
I
x
,
I
y
]
1
⋯
[
I
x
,
I
y
]
k
]
,
b
=
[
I
t
1
⋯
I
t
k
]
A=\left[\begin{array}{c} {\left[I_{x}, I_{y}\right]_{1}} \\ \cdots \\ {\left[I_{x}, I_{y}\right]_{k}} \end{array}\right], b=\left[\begin{array}{c} I_{t 1} \\ \cdots \\ I_{t k} \end{array}\right]
A=⎣⎡[Ix,Iy]1⋯[Ix,Iy]k⎦⎤,b=⎣⎡It1⋯Itk⎦⎤
则方程可以写为:
A
[
u
v
]
=
−
b
A\left[\begin{array}{l}u \\ v\end{array}\right]=-b
A[uv]=−b,这里写最小二乘法的解法,还可以用牛顿迭代法等,便不做推导。将方程写成:
A
x
⃗
=
z
⃗
A \vec{x}=\vec{z}
Ax=z,得到:
A
T
A
x
⃗
=
A
T
z
⃗
x
⃗
=
(
A
T
A
)
−
1
A
T
z
⃗
\begin{array}{l} A^{T} A \vec{x}=A^{T} \vec{z} \\ \vec{x}=\left(A^{T} A\right)^{-1} A^{T} \vec{z} \end{array}
ATAx=ATzx=(ATA)−1ATz
即:
x
⃗
=
[
u
v
]
=
[
∑
i
=
1
k
I
i
x
2
∑
i
=
1
k
I
i
x
I
i
y
∑
i
=
1
k
I
i
x
I
i
y
∑
i
=
1
k
I
i
y
2
]
−
1
[
−
∑
i
=
1
k
I
i
x
I
t
−
∑
i
=
1
k
I
i
y
I
t
]
\vec{x}=\left[\begin{array}{c} u \\ v \end{array}\right]=\left[\begin{array}{cc} \sum_{i=1}^{k} I_{i x}^{2} & \sum_{i=1}^{k} I_{i x} I_{i y} \\ \sum_{i=1}^{k} I_{i x} I_{i y} & \sum_{i=1}^{k} I_{i y}^{2} \end{array}\right]^{-1}\left[\begin{array}{c} -\sum_{i=1}^{k} I_{i x} I_{t} \\ -\sum_{i=1}^{k} I_{i y} I_{t} \end{array}\right]
x=[uv]=[∑i=1kIix2∑i=1kIixIiy∑i=1kIixIiy∑i=1kIiy2]−1[−∑i=1kIixIt−∑i=1kIiyIt]
但只有在
A
T
A
A^TA
ATA可逆的时候,才能得出答案。在图像中,沿着两个方向都有像素发生变化的区域,
A
T
A
A^TA
ATA才可逆;反之,在灰度变化很小的区域,
A
T
A
A^TA
ATA一般不可逆。这限制了LK光流法的应用范围,也是其被称为“稀疏光流法”的主要原因。
迭代求解LK法
整理一下求解过程。
相邻的两帧图像
I
I
I和
J
J
J,对于
I
I
I中的像素点
u
=
[
u
x
u
y
]
T
u=\left[\begin{array}{ll}u_{x} & u_{y}\end{array}\right]^{T}
u=[uxuy]T,需要在图像
J
J
J中找到像素点
v
=
u
+
d
=
[
u
x
+
d
x
u
y
+
d
y
]
T
v=u+d=\left[\begin{array}{ll}u_{x}+d_{x} & u_{y}+d_{y}\end{array}\right]^{T}
v=u+d=[ux+dxuy+dy]T使其与前一个像素点最为相似。我们把
d
=
[
d
x
d
y
]
T
d=\left[\begin{array}{ll}d_x & d_y\end{array}\right]^{T}
d=[dxdy]T称为
u
u
u点的光流。为了求解,假设邻域内的点具有相同的光流,邻域采用
w
x
w_x
wx和
w
y
w_y
wy两个参数表示。则求解
d
d
d便成了使以下目标函数最小的优化问题:
ε
(
d
)
=
ε
(
d
x
,
d
y
)
=
∑
x
=
u
x
−
w
x
x
=
u
x
+
w
x
∑
y
=
u
y
−
w
y
y
=
u
y
+
w
y
(
I
(
x
,
y
)
−
J
(
x
+
d
x
,
y
+
d
y
)
)
2
\varepsilon(d)=\varepsilon\left(d_{x}, d_{y}\right)=\sum_{x=u_{x}-w_{x}}^{x=u_{x}+w_{x}} \sum_{y=u_{y}-w_{y}}^{y=u_{y}+w_{y}}\left(I(x, y)-J\left(x+d_{x}, y+d_{y}\right)\right)^{2}
ε(d)=ε(dx,dy)=x=ux−wx∑x=ux+wxy=uy−wy∑y=uy+wy(I(x,y)−J(x+dx,y+dy))2
最优解的导数为
0
0
0,则有:
∂
ε
(
d
)
∂
d
=
−
2
∑
x
=
u
x
−
w
x
x
=
u
x
+
w
x
∑
y
=
u
y
−
w
y
y
=
u
y
+
w
y
(
I
(
x
,
y
)
−
J
(
x
+
d
x
,
y
+
d
y
)
)
[
∂
J
∂
x
∂
J
∂
y
]
\frac{\partial \varepsilon(d)}{\partial d}=-2 \sum_{x=u_{x}-w_{x}}^{x=u_{x}+w_{x}} \sum_{y=u_{y}-w_{y}}^{y=u_{y}+w_{y}}\left(I(x, y)-J\left(x+d_{x}, y+d_{y}\right)\right)\left[\frac{\partial J}{\partial x} \quad \frac{\partial J}{\partial y}\right]
∂d∂ε(d)=−2x=ux−wx∑x=ux+wxy=uy−wy∑y=uy+wy(I(x,y)−J(x+dx,y+dy))[∂x∂J∂y∂J]
一阶泰勒展开后:
∂
ε
(
d
)
∂
d
≈
−
2
∑
x
=
u
x
−
w
x
y
=
u
y
−
w
y
x
=
u
x
+
w
x
y
=
u
y
+
w
y
(
I
(
x
,
y
)
−
J
(
x
,
y
)
−
[
∂
J
∂
x
∂
J
∂
y
]
[
d
x
d
y
]
)
[
∂
J
∂
x
∂
J
∂
y
]
\frac{\partial \varepsilon(d)}{\partial d} \approx-2 \sum_{x=u_{x}-w_{x} y=u_{y}-w_{y}}^{x=u_{x}+w_{x} y=u_{y}+w_{y}}\left(I(x, y)-J(x, y)-\left[\frac{\partial J}{\partial x} \quad \frac{\partial J}{\partial y}\right]\left[\begin{array}{l} d_{x} \\ d_{y} \end{array}\right]\right)\left[\begin{array}{ll} \frac{\partial J}{\partial x} & \frac{\partial J}{\partial y} \end{array}\right]
∂d∂ε(d)≈−2x=ux−wxy=uy−wy∑x=ux+wxy=uy+wy(I(x,y)−J(x,y)−[∂x∂J∂y∂J][dxdy])[∂x∂J∂y∂J]
由于时间间隔很短,所以
d
=
[
d
x
d
y
]
T
d=\left[\begin{array}{ll}d_x & d_y\end{array}\right]^{T}
d=[dxdy]T足够小,就可以用
[
∂
I
∂
x
∂
I
∂
y
]
\left[\begin{array}{ll} \frac{\partial I}{\partial x} & \frac{\partial I}{\partial y} \end{array}\right]
[∂x∂I∂y∂I]来代替
[
∂
J
∂
x
∂
J
∂
y
]
\left[\begin{array}{ll} \frac{\partial J}{\partial x} & \frac{\partial J}{\partial y} \end{array}\right]
[∂x∂J∂y∂J]。同时,为了使式子看上去简单一些,便定义
δ
I
(
x
,
y
)
=
I
(
x
,
y
)
−
J
(
x
,
y
)
\delta I(x, y)=I(x, y)-J(x, y)
δI(x,y)=I(x,y)−J(x,y)和
∇
I
=
[
∂
I
∂
x
∂
I
∂
y
]
T
\nabla I=\left[\begin{array}{ll}\frac{\partial I}{\partial x} & \frac{\partial I}{\partial y}\end{array}\right]^{T}
∇I=[∂x∂I∂y∂I]T,所以上述公式可以转换为:
1
2
∂
ε
(
d
)
∂
d
=
∑
x
=
u
x
−
w
x
x
=
u
x
+
w
x
∑
y
=
u
y
−
w
y
y
=
u
y
+
w
y
(
∇
I
T
d
−
δ
I
)
∇
I
T
\frac{1}{2} \frac{\partial \varepsilon(d)}{\partial d}=\sum_{x=u_{x}-w_{x}}^{x=u_{x}+w_{x}} \sum_{y=u_{y}-w_{y}}^{y=u_{y}+w_{y}}\left(\nabla I^{T} d-\delta I\right) \nabla I^{T}
21∂d∂ε(d)=x=ux−wx∑x=ux+wxy=uy−wy∑y=uy+wy(∇ITd−δI)∇IT
其中,
∇
I
T
d
−
δ
I
\nabla I^{T} d-\delta I
∇ITd−δI是标量,所以可以将式子中的
∇
I
T
\nabla I^{T}
∇IT换成
∇
I
\nabla I
∇I,这样变换之后,虽然最后的结果从
1
×
2
1\times 2
1×2的向量变成了
2
×
1
2×1
2×1的向量,但值是一样的。所以:
1
2
[
∂
ε
(
d
)
∂
d
]
T
≈
∑
x
=
u
x
−
w
y
x
=
u
x
+
w
x
y
=
u
y
−
u
y
−
w
y
(
∇
I
T
d
−
δ
I
)
∇
I
=
∑
x
=
u
x
−
w
y
x
=
u
x
+
w
x
y
=
u
y
−
u
y
−
w
y
∇
I
T
d
∇
I
−
δ
I
∇
I
=
∑
x
=
u
x
−
w
y
x
=
u
x
+
w
x
y
=
u
y
−
u
y
−
w
y
∇
I
∇
I
T
d
−
δ
I
∇
I
=
∑
x
=
u
x
−
w
x
x
=
u
x
+
w
x
∑
y
=
u
y
−
w
y
y
=
u
y
+
w
y
[
I
x
2
I
x
I
y
I
x
I
y
I
y
2
]
d
−
∑
x
=
u
x
−
w
x
x
=
u
x
+
w
y
∑
y
=
u
y
−
w
y
y
=
u
y
+
w
y
[
δ
I
⋅
I
x
δ
I
⋅
I
y
]
\begin{aligned} \frac{1}{2}\left[\frac{\partial \varepsilon(d)}{\partial d}\right]^{T} &\approx \sum_{x=u_{x}-w_{y}}^{x=u_{x}+w_{x} y=u_{y}-u_{y}-w_{y}}\left(\nabla I^{T} d-\delta I\right) \nabla I \\ &=\sum_{x=u_{x}-w_{y}}^{x=u_{x}+w_{x} y=u_{y}-u_{y}-w_{y}}\nabla I^{T} d\nabla I-\delta I \nabla I \\ &=\sum_{x=u_{x}-w_{y}}^{x=u_{x}+w_{x} y=u_{y}-u_{y}-w_{y}}\nabla I\nabla I^{T} d-\delta I \nabla I \\ &=\sum_{x=u_{x}-w_{x}}^{x=u_{x}+w_{x}} \sum_{y=u_{y}-w_{y}}^{y=u_{y}+w_{y}}\left[\begin{array}{cc} I_{x}^{2} & I_{x} I_{y} \\ I_{x} I_{y} & I_{y}^{2} \end{array}\right] d-\sum_{x=u_{x}-w_{x}}^{x=u_{x}+w_{y}} \sum_{y=u_{y}-w_{y}}^{ y=u_{y}+w_{y}}\left[\begin{array}{l} \delta I \cdot I_{x} \\ \delta I \cdot I_{y} \end{array}\right] \end{aligned}
21[∂d∂ε(d)]T≈x=ux−wy∑x=ux+wxy=uy−uy−wy(∇ITd−δI)∇I=x=ux−wy∑x=ux+wxy=uy−uy−wy∇ITd∇I−δI∇I=x=ux−wy∑x=ux+wxy=uy−uy−wy∇I∇ITd−δI∇I=x=ux−wx∑x=ux+wxy=uy−wy∑y=uy+wy[Ix2IxIyIxIyIy2]d−x=ux−wx∑x=ux+wyy=uy−wy∑y=uy+wy[δI⋅IxδI⋅Iy]
令
G
=
∑
x
=
u
x
−
w
x
x
=
u
x
+
w
x
∑
y
=
u
y
−
w
y
y
=
u
y
+
w
y
[
I
x
2
I
x
I
y
I
x
I
y
I
y
2
]
d
b
=
∑
x
=
u
x
−
w
x
x
=
u
x
+
w
y
∑
y
=
u
y
−
w
y
y
=
u
y
+
w
y
[
δ
I
⋅
I
x
δ
I
⋅
I
y
]
\begin{aligned}G&=\sum_{x=u_{x}-w_{x}}^{x=u_{x}+w_{x}} \sum_{y=u_{y}-w_{y}}^{y=u_{y}+w_{y}}\left[\begin{array}{cc} I_{x}^{2} & I_{x} I_{y} \\ I_{x} I_{y} & I_{y}^{2} \end{array}\right] d \\ b&=\sum_{x=u_{x}-w_{x}}^{x=u_{x}+w_{y}} \sum_{y=u_{y}-w_{y}}^{ y=u_{y}+w_{y}}\left[\begin{array}{l} \delta I \cdot I_{x} \\ \delta I \cdot I_{y} \end{array}\right] \end{aligned}
Gb=x=ux−wx∑x=ux+wxy=uy−wy∑y=uy+wy[Ix2IxIyIxIyIy2]d=x=ux−wx∑x=ux+wyy=uy−wy∑y=uy+wy[δI⋅IxδI⋅Iy]
则公式最终可以写成
d
=
G
−
1
b
d=G^{-1}b
d=G−1b的形式。有时候为了求得更加精确的
d
d
d,可以采用迭代求解的方式求
d
d
d。得到的位置
(
x
+
d
x
,
y
+
d
y
)
(x+d_x,y+d_y)
(x+dx,y+dy)往往不是整数点像素,需要采用类似双线性插值的方法来计算得到最终的值。
用
K
(
K
≥
1
)
K(K \geq 1)
K(K≥1)来表示迭代次数,对于第
k
(
K
≥
k
≥
1
)
k(K\geq k\geq 1)
k(K≥k≥1)次迭代,前面的
k
−
1
k-1
k−1次迭代提供了初始值
d
k
−
1
=
[
d
x
k
−
1
d
y
k
−
1
]
T
d^{k-1}=\left[\begin{array}{ll}d_{x}^{k-1} & d_{y}^{k-1}\end{array}\right]^{T}
dk−1=[dxk−1dyk−1]T,移动后得到的图像为
J
k
(
x
,
y
)
=
J
(
x
+
d
x
k
−
1
,
y
+
d
y
k
−
1
)
J_{k}(x, y)=J\left(x+d_{x}^{k-1}, y+d_{y}^{k-1}\right)
Jk(x,y)=J(x+dxk−1,y+dyk−1),第k次迭代需要求解的问题就是计算优化变量
η
k
=
[
η
x
k
η
y
k
]
T
\eta^{k}=\left[\begin{array}{ll}\eta_{x}^{k} & \eta_{y}^{k}\end{array}\right]^{T}
ηk=[ηxkηyk]T,使得下面的目标函数最小:
ε
k
(
η
k
)
=
ε
(
η
x
k
,
η
y
k
)
=
∑
x
=
u
x
−
w
x
x
=
u
x
+
w
x
∑
y
=
u
y
−
w
y
y
=
u
y
+
w
y
(
I
(
x
,
y
)
−
J
k
(
x
+
η
x
k
,
y
+
η
y
k
)
)
2
\varepsilon^{k}\left(\eta^{k}\right)=\varepsilon\left(\eta_{x}^{k}, \eta_{y}^{k}\right)=\sum_{x=u_{x}-w_{x}}^{x=u_{x}+w_{x}} \sum_{y=u_{y}-w_{y}}^{y=u_{y}+w_{y}}\left(I(x, y)-J_{k}\left(x+\eta_{x}^{k}, y+\eta_{y}^{k}\right)\right)^{2}
εk(ηk)=ε(ηxk,ηyk)=x=ux−wx∑x=ux+wxy=uy−wy∑y=uy+wy(I(x,y)−Jk(x+ηxk,y+ηyk))2
也可以写成
η
k
=
G
−
1
b
k
\eta^{k}=G^{-1}b_k
ηk=G−1bk的形式。这里的
G
G
G只需要计算一次,而
b
k
b_k
bk每一次迭代都不一样,需要重新计算。之后第
k
k
k次迭代的结果
d
k
=
d
k
−
1
+
η
k
d_k=d_{k-1}+\eta_k
dk=dk−1+ηk
金字塔LK光流法
之前的三条假设分别为:
- 运动物体的灰度值在很短的时间间隔内保持不变;
- 给定邻域内的速度向量变化缓慢;
- 邻域内光流一致;
这些假设在实际场景中很难满足,尤其是假设2。我们在求解过程中应用了泰勒展开,泰勒展开只有在变量变化很小的情况下才能使用,而如果帧之间的像素运动比较大,泰勒展开便不怎么合适了。所以就有大神提出了金字塔LK光流法,既然害怕像素运动太快,无法使用泰勒展开,那么就将整张图片进行缩小,降低其分辨率。对于运动较快的像素点,总能在图像分辨率降到一定程度时,其运动变得足够小,满足泰勒展开的条件。
算法将原始图像作为第0层,宽和高缩小
2
L
2^L
2L倍的图像作为第
L
L
L层,形成金字塔的样子。一些小细节:
- 对图像进行降采样之前通常采用低通滤波器进行滤波,防止降采样后发生锯齿现象;
- 对图像添加额外像素圈,将额外像素圈内的像素值填充为图像的真实边界值,这样就算在计算边缘点邻域时,只计算该点邻域的有效部分;
- 原始图像的宽和高不严格满足可以整除 2 L 2^L 2L,可以微调原图像,也可以按照 n x L ≤ n x L − 1 + 1 2 , n y L ≤ n y L − 1 + 1 2 n_{x}^{L} \leq \frac{n_{x}^{L-1}+1}{2}, n_{y}^{L} \leq \frac{n_{y}^{L-1}+1}{2} nxL≤2nxL−1+1,nyL≤2nyL−1+1来取宽和高;
算法大致流程其实就是先计算最顶层的光流大小,定义为
g
L
m
=
[
0
0
]
T
g^{L m}=\left[\begin{array}{ll}0 & 0\end{array}\right]^{T}
gLm=[00]T,传入到下一层作为初始值,最后计算出原始图像上的光流大小。假设第
L
+
1
L+1
L+1层计算到的第
L
L
L层的光流大小为
g
L
=
[
g
x
L
g
y
L
]
′
g^{L}=\left[\begin{array}{ll}g_{x}^{L} & g_{y}^{L}\end{array}\right]^{\prime}
gL=[gxLgyL]′,需要求得
d
L
=
[
d
x
L
d
y
L
]
d^{L}=\left[\begin{array}{ll}d_{x}^{L} & d_{y}^{L}\end{array}\right]
dL=[dxLdyL]使以下函数最小:
ε
L
(
d
L
)
=
ε
L
(
d
x
L
,
d
y
L
)
=
∑
x
=
u
x
L
−
w
x
y
=
u
y
L
−
w
y
x
=
u
x
L
+
w
x
y
=
u
y
L
+
w
y
(
I
L
(
x
,
y
)
−
J
L
(
x
+
g
x
L
+
d
x
L
,
y
+
g
y
L
+
d
y
L
)
)
2
\varepsilon^{L}\left(d^{L}\right)=\varepsilon^{L}\left(d_{x}^{L}, d_{y}^{L}\right)=\sum_{x=u_{x}^{L}-w_{x} y=u_{y}^{L}-w_{y}}^{x=u_{x}^{L}+w_{x} y=u_{y}^{L}+w_{y}}\left(I^{L}(x, y)-J^{L}\left(x+g_{x}^{L}+d_{x}^{L}, y+g_{y}^{L}+d_{y}^{L}\right)\right)^{2}
εL(dL)=εL(dxL,dyL)=x=uxL−wxy=uyL−wy∑x=uxL+wxy=uyL+wy(IL(x,y)−JL(x+gxL+dxL,y+gyL+dyL))2
由于泰勒展开是在变化微小的情况下才能使用,所以此处需要
x
+
g
x
L
x+g_x^L
x+gxL才能接近真实值,才能泰勒展开,相对于把邻域窗口进行了平移。后面便是和之前LK光流法类似,不再叙述。
计算得到
d
L
=
[
d
x
L
d
y
L
]
d^{L}=\left[\begin{array}{ll}d_{x}^{L} & d_{y}^{L}\end{array}\right]
dL=[dxLdyL]后,定义
g
L
−
1
=
2
(
g
L
+
d
L
)
g^{L-1}=2\left(g^{L}+d^{L}\right)
gL−1=2(gL+dL)作为第
L
−
1
L-1
L−1层的光流初始值大小,重复上述过程,最终计算得到的结果为
d
=
∑
L
=
0
L
m
2
L
d
L
d=\sum_{L=0}^{L m} 2^{L} d^{L}
d=∑L=0Lm2LdL。虽然对于原始图像来说,位移可能偏大,但对于每一层的图像来说,其对应的
d
L
d^L
dL其实都很小,因此可以使用泰勒展开求解。
整理一下整体流程
将图像
I
I
I和
J
J
J建立为
{
I
L
}
L
=
0
,
…
L
m
\left\{I^{L}\right\}_{L=0, \ldots L_{m}}
{IL}L=0,…Lm和
{
J
L
}
L
=
0
,
…
L
m
\left\{J^{L}\right\}_{L=0, \ldots L_{m}}
{JL}L=0,…Lm;
初始化最高层的光流为
g
L
m
=
[
0
0
]
T
g^{L m}=\left[\begin{array}{ll}0 & 0\end{array}\right]^{T}
gLm=[00]T;
从
L
=
L
m
L=L_m
L=Lm开始进行迭代:
计算图像
I
L
I^L
IL中像素点
u
u
u的位置:
u
L
=
[
u
x
L
u
y
L
]
=
u
/
2
L
u^{L}=\left[\begin{array}{ll}u_{x}^{L} & u_{y}^{L}\end{array}\right]=u / 2^{L}
uL=[uxLuyL]=u/2L
计算图像
I
L
I^L
IL在
x
x
x方向上的梯度:
I
x
L
(
x
,
y
)
=
I
L
(
x
+
1
,
y
)
−
I
L
(
x
−
1
,
y
)
2
I_{x}^{L}(x, y)=\frac{I^{L}(x+1, y)-I^{L}(x-1, y)}{2}
IxL(x,y)=2IL(x+1,y)−IL(x−1,y)(中心差分法)
计算图像
I
L
I^L
IL在
y
y
y方向上的梯度:
I
y
L
(
x
,
y
)
=
I
L
(
x
,
y
+
1
)
−
I
L
(
x
,
y
−
1
)
2
I_{y}^{L}(x, y)=\frac{I^{L}(x, y+1)-I^{L}(x, y-1)}{2}
IyL(x,y)=2IL(x,y+1)−IL(x,y−1)(中心差分法)
计算矩阵G:
G
=
∑
x
=
u
L
x
−
w
x
x
=
u
L
x
+
w
x
∑
y
=
u
L
y
−
w
y
y
=
u
L
y
+
w
y
[
I
x
L
2
I
x
L
I
y
L
I
x
L
I
y
L
I
y
L
2
]
G=\sum_{x=u^{L} x-w_{x}}^{x=u^{L} x+w_{x}} \sum_{y=u^{L} y-w_{y}}^{y=u^{L} y+w_{y}}\left[\begin{array}{cc}I_{x}^{L^{2}} & I_{x}^{L} I_{y}^{L} \\ I_{x}^{L} I_{y}^{L} & I_{y}^{L^{2}}\end{array}\right]
G=x=uLx−wx∑x=uLx+wxy=uLy−wy∑y=uLy+wy[IxL2IxLIyLIxLIyLIyL2]
初始化迭代
k
k
k次的初始值:
d
0
=
[
0
0
]
T
d^{0}=\left[\begin{array}{ll}0 & 0\end{array}\right]^{T}
d0=[00]T
进行k次迭代
计算图像差异:
δ
I
k
(
x
,
y
)
=
I
L
(
x
,
y
)
−
J
L
(
x
+
g
x
L
+
d
x
k
−
1
,
y
+
g
y
L
+
d
y
k
−
1
)
\delta I^{k}(x, y)=I^{L}(x, y)-J^{L}\left(x+g_{x}^{L}+d_{x}^{k-1}, y+g_{y}^{L}+d_{y}^{k-1}\right)
δIk(x,y)=IL(x,y)−JL(x+gxL+dxk−1,y+gyL+dyk−1)
计算向量
b
k
b_k
bk:
b
k
=
∑
x
=
u
L
x
−
w
x
x
=
u
L
x
+
w
x
∑
y
=
u
L
y
−
w
y
y
=
u
L
y
+
w
y
[
δ
I
k
(
x
,
y
)
I
x
(
x
,
y
)
δ
I
k
(
x
,
y
)
I
y
(
x
,
y
)
]
b_{k}=\sum_{x=u^{L} x-w_{x}} ^{x=u^{L} x+w_{x}}\sum_{y=u^{L} y-w_{y}}^{y=u^{L} y+w_{y}}\left[\begin{array}{l}\delta I^{k}(x, y) I_{x}(x, y) \\ \delta I^{k}(x, y) I_{y}(x, y)\end{array}\right]
bk=∑x=uLx−wxx=uLx+wx∑y=uLy−wyy=uLy+wy[δIk(x,y)Ix(x,y)δIk(x,y)Iy(x,y)]
计算光流:
η
k
=
G
−
1
b
k
\eta_k=G^{-1}b_k
ηk=G−1bk
计算下一次迭代的初始值:
d
k
=
d
k
−
1
+
η
k
d^k=d^{k-1}+\eta^k
dk=dk−1+ηk
结束
k
k
k上的迭代
得到
L
L
L层图像上的光流:
d
L
=
d
k
d^L=d^k
dL=dk
为
L
−
1
L-1
L−1层提供光流的初始值:
g
L
−
1
=
2
(
g
L
+
d
L
)
g^{L-1}=2\left(g^{L}+d^{L}\right)
gL−1=2(gL+dL)
结束
L
L
L上的迭代
计算最终的光流
d
=
g
0
+
d
0
d=g^0+d^0
d=g0+d0
找到图像
J
J
J中对应图像
I
I
I中像素点
u
u
u的位置:
v
=
u
+
d
v=u+d
v=u+d