光流法小结[通俗易懂]

光流法小结[通俗易懂]1.定义空间运动物体在观察成像平面上的像素运动的瞬时速度,是利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存在的对应关系,从而计算出相邻帧之间物体的运动信息的一种方法。也就是说,由空间域到图像平面的投影。而通俗来讲,把图像中的每一个点的瞬时速度和方向找出来就是光流。2.光流有什么用通过光流判断物体距离我们的远近。一般而言,远景的物体相对来说光流较小,而近景物体

大家好,又见面了,我是你们的朋友全栈君。

1. 定义

空间运动物体在观察成像平面上的像素运动的瞬时速度,是利用图像序列中像素在时间域上的变化以及相邻帧之间的相关性来找到上一帧跟当前帧之间存在的对应关系,从而计算出相邻帧之间物体的运动信息的一种方法。也就是说,由空间域到图像平面的投影。而通俗来讲,把图像中的每一个点的瞬时速度和方向找出来就是光流。

2. 光流有什么用

通过光流判断物体距离我们的远近。 一般而言,远景的物体相对来说光流较小,而近景物体光流较大,尤其是动态场景中的运动物体。

3. 如何计算光流

光流法的第一层推导

3.1 计算光流的几个假设
(1)相邻帧之间的亮度恒定;
(2)相邻视频帧的取帧时间连续,或者,相邻帧之间物体的运动比较“微小”;
(3)保持空间一致性;即,同一子图像的像素点具有相同运动

3.2 光流的基本方程
假设位于 (x,y,t) 的像素的亮度是 I(x,y,t) , 该像素在两个图像帧之间移动了 Δx Δy Δt ,由泰勒展开式我们可以得到:

I(x+Δx,y+Δy,t+Δt)=I(x,y,t)+IxΔx+IyΔy+ItΔt+o

由假设1可知
I(x+Δx,y+Δy,t+Δt)=I(x,y,t)

故有:
IxΔx+IyΔy+ItΔt=0
或者
IxΔxΔt+IyΔyΔt+It=0
这个方程便是我们计算光流的基本方程。

其中 ΔxΔt ΔyΔt 为该点在x和y方向上的瞬时速度,也就是光流。
It 代表 像素点在时间上的变化。 可以通过在像素位置(x,y)处两张图像之间的像素差。

但是这个我们要计算一个点的光流,有两个未知数,只有一个方程,该如何解呢?针对这个问题,有很多解决方法:
– 基于梯度的方法
– 基于匹配的方法
– 基于能量的方法
– 基于相位的方法

下面我们介绍一个很经典的算法, LK光流提取算法

LK-光流算法

基本假设:光流在像素点的邻域是一个常数
然后使用最小二乘法对邻域中的所有像素点求解基本的光流方程。因为方程个数已经超过了为未知量个数
假定像素位置p周围的领域像素由 q1q2q3... ,那么就有
Ix(q1)Vx+Iy(q1)Vy+It(q1)=0 ;
Ix(q2)Vx+Iy(q2)Vy+It(q2)=0 ;
Ix(q3)Vx+Iy(q3)Vy+It(q3)=0 ;

将其写为矩阵的形式,则有

这里写图片描述

然后通过伪逆的形式解最小二乘就可以求解到光流 v


v=(ATA)1ATb

L-K 光流算法的缺点

我们首先要设置一个邻域的窗口,之后计算光流
当窗口较大时,光流计算更鲁棒
当窗口较小时,光流计算更正确
原因在于,当图像中每一个部分的运动都不一致的时候,如果开的窗口过大,很容易违背假设:窗口(邻域)内的所有点光流一致,这可能与实际不一致,所以窗口小,包含的像素少,更精确些。当运动较为剧烈的时候,无法实现光流的基本假设,即 I(x+Δx,y+Δy,t+Δt)=I(x,y,t) ,因为 Δx Δy 而我们的领域小于实际运动的位移,所以当我们的领域加大的时候,算法更鲁棒。

如何解决这一问题,我们采用了金字塔的方法,即窗口固定,将图像生成金字塔,在每一层金字塔上都用同一个大小的窗口来进行光流计算。那么在图像大小较小的时候,窗口显得较大,此时的光流可以跟踪速度较快的目标,而在原始图像的时候,光流窗口相对较小,得到的光流就更准确。这是一个由粗到精的过程。

以上是光流的第一层推导



光流法的第二层推导

光流法的基本方程

这里写图片描述
其中 I(x,y) 指原图, J(x,y) 指参考图。 dx,dy 为在 (ux,uy) 处的光流向量。 wx,wy 为基于坐标点 (ux,uy) 的搜索窗口(半径)。

默认情况下,我们认为 dx,dy 应该小于 (ux,uy) ,也就是在I图中的一个点对应J图时,应该不会超过 (ux,uy) 这个窗口的。那么基于这个假设就出现了上面提到的关于窗口大小与光流准确性及鲁棒性带来的矛盾。下面讲如何利用图像金字塔来解决这个矛盾。

1. 如何建立图像金字塔

这里写图片描述
按照此公式建立,其中 IL 代笔第L层的图像金字塔。初始情况下使 I0 为原始图像。按照上述公司,由第L-1层图像到第L层图像是通过以下步骤
– 对L-1层图像进行低通滤波,滤波模板如下
这里写图片描述
– 将滤波后的图像抽取偶数行偶数列的像素重组为第L层图像,因此最后L-1层的图像大小是L层的一半。

但是对于图像滤波时边缘像素怎么办呢?由于模板的半径是1,那么就首先将原始图像的像素扩展一圈,宽度为一个像素,扩展出来的像素值与其相近的原始图像边缘像素一致,即
这里写图片描述

2. 根据金字塔逐层计算光流

首先引入两个光流量:剩余光流量 dL 和猜测光流量 gL
核心思想在于:对第L层的光流,是通过由第L-1层的精确光流得到的导出光流量 gL 以及这一层以 gL 为基准再次进行匹配微调后得到的剩余光流量 dL 。即第L层的光流 kL

kL=gL+dL

gL 由上一层的精确光流猜测得来

gL=2×kL1=2×(gL1+dL1)



基于的事实是:既然第L-1到第L层是降采样一半,那么光流量也应该减一半。

但是这样粗略的估算是不准确的,所以第L层还需要通过基本的光流方程得出剩余光流量

dL
去修正这个值,使得第L层的光流更精确.怎么得到

dL
,就是基本的光流方程


这里写图片描述

这里可以发现,关于最终光流的搜索范围事实上是变大了的,如图所示
这里写图片描述

所有都归功于上一层光流提供的先验信息使得光流跳出了 wx,wy 的约束,可以到更远的地方,这样就解决了上面提到的关于窗口大小的矛盾。事实上,对于在原始图像(L=0)上开一个d*d的搜索框,在金字塔的情况下,总的搜索半径可以达到

dfinal=(2lm+11)d

对于一般的视频做光流而言,采用3*3的窗口,图像金字塔的层数有2-3层就够了。因为覆盖范围以及很广了

最后得到的原始图像的光流按照一下公式计算而来
这里写图片描述

3. 计算光流基本方程

首先光流基本方程是一个最优化的问题,可以通过求导求其最优解
这里写图片描述
对基本光流方程求导
这里写图片描述

这里写图片描述
B(x+vx,y+vy) 进行一阶泰勒展开

这里写图片描述

计算两张图像的差

这里写图片描述

计算图像在 wx,wy 邻域内的差分,这里可以采用Sharr算子代表差分
这里写图片描述

这里写图片描述

这里写图片描述

这样就算出了LK光流。但是这一光流的假设是泰勒一阶展开足够精确。那么为了进一步使得计算出来的光流更加精确,我们采用牛顿逼近法进行迭代。

核心思想在于:在上一次计算出LK光流后,将得到的光流 vk 用来更新参考图像的像素位置(平移),之后再次计算光流。重新更新 vk 。如此循环直到迭代次数达到上限或者误差量 ε 小于设定的阈值时停止。 按照上述情况来看,停止迭代后,A图和B图两张图在 (x,y) 点处像素完全重合的。

这里写图片描述

这里写图片描述

这里写图片描述

这里是最终迭代结束后的精确光流量
这里写图片描述

总结算法

这里写图片描述

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员-用户IM,转载请注明出处:https://javaforall.cn/163529.html原文链接:https://javaforall.cn

【正版授权,激活自己账号】: Jetbrains全家桶Ide使用,1年售后保障,每天仅需1毛

【官方授权 正版激活】: 官方授权 正版激活 支持Jetbrains家族下所有IDE 使用个人JB账号...

(0)
blank

相关推荐

  • Qt中QTableView设置分页显示的三种方法[通俗易懂]

    1、已知所有数据的情况下,以MVC模式对数据进行分页处理:参考链接:http://www.cnblogs.com/caomingongli/archive/2011/11/17/2252745.html参考链接:https://blog.csdn.net/xujiali5172923/article/details/478352652、数据库很大的时候,QTableView会自动生…

  • yarn-site.xml 配置介绍

    yarn-site.xml 配置介绍

    2021年11月27日
  • c语言窗体关机程序代码,c语言 关机程序代码[通俗易懂]

    c语言窗体关机程序代码,c语言 关机程序代码[通俗易懂]通过C语言实现关机,有两种方式:1通过system函数,调用dos的关机命令。通过stdlib.h中的intsystem(char*cmd);可以执行dos命令cmd。dos下关机的命令为shutdown-s,于是嗲用system(“shutdown-s”);即可实现关机操作。2通过调用windows提供的api函数,来实现关机:voidshut_down_windows(){HAN…

  • 存算一体——后摩尔时代的AI芯片架构[通俗易懂]

    存算一体——后摩尔时代的AI芯片架构[通俗易懂]存算一体,或存内计算,是指将传统冯诺依曼架构中以计算为中心的设计,转变为以数据存储为中心的设计,也就是利用存储器对数据进行运算,从而避免数据搬运产生的“存储墙”和“功耗墙”,极大提高数据的并行度和能量效率。这种架构特别适用于要求大算力、低功耗的终端设备,如可穿戴设备、移动设备、智能家居等。1.冯诺依曼架构的局限首先是性能。经典的冯诺依曼架构下,数据的存储和计算是分开的,处理器CPU存储器之间通过数据总线进行数据交换。但由于处理器和存储器的内部结构、工艺和封装不同,二者的性能也存在很大的差.

  • python中turtle.write的用法_菜鸟教程python3实例

    python中turtle.write的用法_菜鸟教程python3实例学习菜鸟教程的Django教程,链接如下:安装:pipinstallDjango如果pip<1.4,使用:pipinstallhttps://www.djangoproject.com/download/1.11a1/tarball/或者clone代码:gitclonehttps://github.com/django/django.git创建一个项目:django-admi…

  • PO模式介绍

    PO模式介绍目标1.深入理解PO模式的思想2.熟练掌握PO模式的分层思想1.存在的问题在做UI自动化时定位元素特别依赖页面,一旦页面发生变更就不得不跟着去修改定位元素的代码。举例:假设要对一个元素进行点击操作,而且会经常对该元素进行操作,那么你就可能会编写多处如下代码 1 driver.find_element_by_id(“login-btn”…

发表回复

您的电子邮箱地址不会被公开。

关注全栈程序员社区公众号