专栏首页科学计算VSLAM前端:金字塔光流跟踪算法

VSLAM前端:金字塔光流跟踪算法

VSLAM前端:金字塔光流跟踪算法

一、光流

 像素点在二维图像中的运动被定义为光流,其在相邻帧图像中存在有位移运动,即存在像素的光流。我们的目的是计算出光流,计算要满足几个前提假设:1.灰度不变性:同一个像素的灰度值在各个图像中是固定不变的;2. 相邻帧之前像素的位移不能太大;3.运动像素周围的像素具有同样的运动规律。

 假设图中像素点的位移向量为

d

,即光流,设第一帧中像素的二维坐标为

u= \begin{bmatrix} u_x & u_y\end{bmatrix}

,下一帧像素的位置可以表示为

v=u+d=\begin{bmatrix} u_x+d_x& u_y+d_y\end{bmatrix}

,前两帧图像分别用

I(x,y)

J(x,y)

表示。我们假设邻域内像素具有相同的运动规律,我们建立以光流为优化变量的误差函数:

\epsilon(d)=\epsilon(d_x, d_y)=\sum_{x=u_x-\omega_x}^{u_x + w_x}\sum_{y=u_y-\omega_y}^{u_y+\omega_y}(I(x,y)-J(x+d_x,y+d_y))^2

 其中

\omega_x

\omega_y

表示整数,一般取2,3,4,5,6,7。

二、图像金字塔

 上图为4层图像金字塔,从下往上进行图像的下采样即可,这里不多解释,读者可自行了解。

三、基于金字塔的Lucas-Kanade算法

 算法的基本思路为:首先在金字塔的最高层计算光流大小,将它作为下一层金字塔光流的初始值,以此类推计算第0层的光流大小,作为最终的光流结果。

 我们将第一小节的误差函数改写为金字塔第

L

层的损失函数:

\epsilon^L(d^L)=\epsilon^L(d_x^L, d_y^L)=\sum_{x=u_x^L-\omega_x}^{u_x^L + w_x}\sum_{y=u_y^L-\omega_y}^{u_y^L+\omega_y}(I^L(x,y)-J^L(x+g_x^L+d_x^L,y+g_y^L+d_y^L))^2

 其中

g^L

为猜测光流,表示金字塔第

L

层迭代的光流初始值,

d^L

为剩余光流,表示金子塔第

L

层迭代的光流误差。

3.1 剩余光流

d^L

的计算

 我们使用上式对

d^L

求导:

\frac{\partial \epsilon^L(d^L)}{\partial d^L}=-2\sum_{x=u_x^L-\omega_x}^{u_x^L + w_x}\sum_{y=u_y^L-\omega_y}^{u_y^L+\omega_y}(I^L(x,y)-J^L(x+g_x^L+d_x^L,y+g_y^L+d_y^L)) \begin{bmatrix} \frac{\partial J^L}{\partial x} & \frac{\partial J^L}{\partial y}\end{bmatrix}

 然后将图像

J^L(x+d_x^L, y+d_y^L)

d^L=\begin{bmatrix} 0 & 0\end{bmatrix}

处进行一阶泰勒展开可得:

\frac{\partial \epsilon^L(d^L)}{\partial d^L}=-2\sum_{x=u_x^L-\omega_x}^{u_x^L + w_x}\sum_{y=u_y^L-\omega_y}^{u_y^L+\omega_y}(I^L(x,y)-J^L(x+g_x^L,y+g_y^L)- \begin{bmatrix} \frac{\partial J^L}{\partial x} & \frac{\partial J^L}{\partial y}\end{bmatrix}d^L) \begin{bmatrix} \frac{\partial J^L}{\partial x} & \frac{\partial J^L}{\partial y}\end{bmatrix}

 其中

\begin{bmatrix} \frac{\partial J^L}{\partial x} & \frac{\partial J^L}{\partial y}\end{bmatrix}

表示图片

J^L

x,y

坐标求导。对于领域内的像素我们定义:

\delta I(x,y)=I^L(x,y)-J^L(x+g_x^L,y+g_y^L)
\Delta I = \begin{bmatrix} I_x & I_y\end{bmatrix}^T=\begin{bmatrix} \frac{\partial J^L}{\partial x} & \frac{\partial J^L}{\partial y}\end{bmatrix}^T

 其中

\Delta I

由图像梯度求出,即:

I_x(x,y)=\frac{I^L(x+1,y)-I^L(x-1,y)}{2}
I_y(x,y)=\frac{I^L(x,y+1)-I^L(x,y-1)}{2}

 我们将上述公式全部带入泰勒展开式,并且两边同时取转置,可得:

\frac{1}{2}\begin{bmatrix}\frac{\partial \epsilon^L(d^L)}{\partial d^L}\end{bmatrix}^T= \sum_{x=u_x^L-\omega_x}^{u_x^L + w_x}\sum_{y=u_y^L-\omega_y}^{u_y^L+\omega_y} (\begin{bmatrix} I_x^2 & I_xI_y \\ I_xI_y & I_y^2\end{bmatrix}d^L- \begin{bmatrix} \delta I \cdot I_x \\ \delta I \cdot I_y\end{bmatrix})

 我们化简公式:

G=\sum_{x=u_x^L-\omega_x}^{u_x^L + w_x}\sum_{y=u_y^L-\omega_y}^{u_y^L+\omega_y}\begin{bmatrix} I_x^2 & I_xI_y \\ I_xI_y & I_y^2\end{bmatrix}
b_k=\sum_{x=u_x^L-\omega_x}^{u_x^L + w_x}\sum_{y=u_y^L-\omega_y}^{u_y^L+\omega_y}\begin{bmatrix} \delta I \cdot I_x \\ \delta I \cdot I_y\end{bmatrix}

 则可以得到:

\frac{1}{2}\begin{bmatrix}\frac{\partial \epsilon^L(d^L)}{\partial d^L}\end{bmatrix}^T=Gd^L-b_k

 当取得极小值时,导数为0,则

d^L=G^{-1}b_k

,至此我们得到经典的Lucas-Kanade光流公式,但其建立在像素位移很小的前提下。我们现在讨论的是金字塔光流,其对光流法进行了改进,进行多次迭代,我们改写公式:

\eta^k=G^{-1}b_k

 当

\eta^k

小于阈值后,迭代终止,迭代公式为:

d_L^k=d_L^{k-1}+\eta^k

,以上就是每层金字塔剩余光流的计算过程。

3.2 猜测光流

g^L

的计算

 最高层

g^L=\begin{bmatrix} 0 & 0\end{bmatrix}^T

,每层金字塔图像猜测光流公式为:

g^{L-1}=2(g^L+d^L)

 最终光流

d=g^0+d^0

四、原始论文算法流程

 原始论文的算法流程更加简洁明了,推荐大家看下面流程:

五、opencv接口函数

void calcOpticalFlowPyrLK(
InputArray prevImg, InputArray nextImg, InputArray prevPts, InputOutputArray nextPts, 
OutputArray status, OutputArray err, 
Size winSize=Size(21,21), int maxLevel=3, 
TermCriteria criteria=TermCriteria(TermCriteria::COUNT+TermCriteria::EPS, 30, 0.01), 
int flags=0, double minEigThreshold=1e-4)

 prevImg:第一帧金字塔图像;

 nextImg:第二帧金字塔图像;

 prevPts:第一帧的像素坐标;

 nextPts:需要找到的第二帧像素坐标;

 status:状态变量;

 err:错误矢量输出;

 winSize:每层金字塔的搜索窗口大小;

 maxLevel:金字塔最大层级;

 criteria:迭代终止条件;

 flags:OPTFLOW_USE_INITIAL_FLOW与OPTFLOW_LK_GET_MIN_EIGENVALS使用的标志位;

 minEigThreshold:最小特征值阈值;

本文分享自微信公众号 - 科学计算technomania(Quant_Times),作者:大亮

原文出处及转载信息见文内详细说明,如有侵权,请联系 yunjia_community@tencent.com 删除。

原始发表时间:2021-04-01

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • VSLAM前端:图像特征提取

     视觉里程计主要是通过图像对运动进行估计。一副中等分辨率的图像就是一个维度巨大的矩阵,我们无法对矩阵直接进行估计,其面临的将是海量的计算,因此我们有必要对图像进...

    猫叔Rex
  • 一个狠招|如何高效学习3D视觉

    有的读者可能对于计算机视觉中2D和3D视觉的区别仍然较为模糊,此处根据某篇论文中的解释,介绍如下:

    OpenCV学堂
  • OpenCV中的光流及视频特征点追踪

    这篇博客将介绍光流的概念以及如何使用 Lucas-Kanade 方法估计光流,并演示如何使用 cv2.calcOpticalFlowPyrLK() 来跟踪视频中...

    玖柒的小窝
  • 干货 | OpenCV中KLT光流跟踪原理详解与代码演示

    在视频移动对象跟踪中,稀疏光流跟踪是一种经典的对象跟踪算法,可以绘制运动对象的跟踪轨迹与运行方向,是一种简单、实时高效的跟踪算法,这个算法最早是有Bruce D...

    OpenCV学堂
  • DeepFlow高效的光流匹配算法(上)

    本周主要介绍一篇基于传统光流法而改进的实现快速的稠密光流算法。该算法已经集成到OpenCV中,算法介绍网址:http://lear.inrialpes.fr/s...

    点云PCL博主
  • AR设备单目视觉惯导SLAM算法综述与评价

    标题:Survey and evaluation of monocular visual-inertial SLAM algorithms for augmen...

    点云PCL博主
  • 视觉/视觉惯性SLAM最新综述:领域进展、方法分类与实验对比

    Visual and Visual-Inertial SLAM: State of the Art, Classification,and Experiment...

    3D视觉工坊
  • C++ OpenCV视频操作之稠密光流对象跟踪

    我们在学习完稀疏光流跟踪完后,我们再学习一下稠密光流对象跟踪,稠密光流算法(即图像上所有像素点的光流都计算出来),由于要计算图像上所有点的光流,故计算耗时,速度...

    Vaccae
  • 视觉/视觉惯性SLAM最新综述:领域进展、方法分类与实验对比

    Visual and Visual-Inertial SLAM: State of the Art, Classification,and Experiment...

    计算机视觉
  • CV学习笔记(八):光流法原理

    在之前的几篇关于OpenCV的文章中我集中介绍了OpenCV中比较常用的操作和函数.在我们基础的学习中,这些函数其实在图像进行预操作的过程中已经够用了.因此在之...

    云时之间
  • CV学习笔记(八):光流法原理

    在之前的几篇关于OpenCV的文章中我集中介绍了OpenCV中比较常用的操作和函数.在我们基础的学习中,这些函数其实在图像进行预操作的过程中已经够用了.因此在之...

    云时之间
  • vSLAM开发指南:从技术框架、开源算法到硬件选型!

    出品 | 智东西公开课 讲师 | 小觅智能 CTO 杨瑞翾 编辑 | 王鑫

    小白学视觉
  • vSLAM技术综述

    SLAM是“Simultaneous Localization And Mapping”的缩写,可译为同步定位与建图。概率 SLAM 问题 (the proba...

    SIGAI学习与实践平台
  • vSLAM技术综述

    SLAM是“Simultaneous Localization And Mapping”的缩写,可译为同步定位与建图。概率 SLAM 问题 (the proba...

    小白学视觉
  • 专栏 | 对比激光SLAM与视觉SLAM:谁会成为未来主流趋势?

    机器之心
  • 【SLAM】开源 | Good Graph提高了VSLAM估计的准确性和鲁棒性,及基于VSLAM的闭环导航系统的轨迹跟踪性能!

    论文地址: http://arxiv.org/pdf/2008.10123v1.pdf

    CNNer
  • B站up主硬核打造「螃蟹火星车」,遥控、拍照、测距,还能做人脸检测;网友:赛博螃克

    没错,策划、采购、烹饪、食用、电路、模型、加工、软件、算法一条龙,全是B站up主稚晖君一个人搞定的,且只花了一个周末就完成了。

    用户1737318
  • 使用VPI 1.1加速计算机视觉和图像处理

    VPI是VISION PROGRAMING INTERFACE的缩写,即视觉编程接口,是NVIDIA 用于高性能计算机视觉处理的下一代 API

    GPUS Lady
  • 使用VPI 1.1加速计算机视觉和图像处理

    VPI是VISION PROGRAMING INTERFACE的缩写,即视觉编程接口,是NVIDIA 用于高性能计算机视觉处理的下一代 API

    GPUS Lady

扫码关注云+社区

领取腾讯云代金券