当前位置: 首页 > news >正文

计算机视觉——光流法

系列文章目录

本系列开篇文章,暂时没有目录啦~

文章目录


前言

光流(Optical Flow)是指图像中的物体在连续帧之间的相对运动。具体来说,光流法试图通过图像中的像素变化(通常是亮度变化)来推测场景中物体的运动方向和速度。
假设你有一个视频或连续的图像帧,光流法就是计算在连续的两帧图像之间,每个像素点的位移(即物体的运动)。如果你可以估计每个像素点的位移,那么你就可以获得整个图像的光流场。

主要参考了下述两篇文章,如有侵权,联系我我会删除此内容
经典光流算法Lucas-Kanade(有图助理解)
光流法(optical flow methods)

一、问题假设

假设一——亮度一致性假设:图像中某个像素点的亮度在连续的两帧图像之间不会发生太大变化,只有由于相对运动而产生的位移。即假设物体的亮度在两帧图像之间是恒定的。这个假设是基于图像的亮度变化主要由物体的运动引起的。
假设二——平滑性假设:图像中的运动变化是平滑的,即在局部区域内,相邻像素的运动是相似的。

二、方程推导

设t时刻(x,y)位置的像素亮度为I(x,y,t)I(x,y,t)I(x,y,t)
根据假设一,对于一个像素点(x,y)(x,y)(x,y),在时间tttt+Δtt+\Delta tt+Δt之间的亮度变化应满足:
I(x,y,t)=I(x+Δx,y+Δy,t+Δt)I(x,y,t)=I(x+\Delta x,y+\Delta y,t+\Delta t)I(x,y,t)=I(x+Δx,y+Δy,t+Δt)
其中:

  • I(x,y,t)I(x,y,t)I(x,y,t)表示时刻ttt时,坐标(x,y)(x,y)(x,y)位置的亮度。
  • Δx,Δy\Delta x,\Delta yΔx,Δy分别是该像素在水平和垂直方向上的位移。
  • Δ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)近似为I(x+Δx,y+Δy,t+Δt)≈I(x,y,t)+∂I∂xΔx+∂I∂yΔy+∂I∂tΔtI(x+\Delta x,y+\Delta y,t+\Delta t) \approx I(x,y,t)+\frac{\partial I}{\partial x}\Delta x+\frac{\partial I}{\partial y}\Delta y+\frac{\partial I}{\partial t}\Delta tI(x+Δx,y+Δy,t+Δt)I(x,y,t)+xIΔx+yIΔy+tIΔt
这个公式使用了泰勒展开的前几项,其中:

  • ∂I∂x\frac{\partial I}{\partial x}xI是图像I(x,y,t)I(x,y,t)I(x,y,t)xxx方向的偏导数,表示图像亮度在水平(x)方向上的变化速率(即图像在xxx方向上的梯度);
  • ∂I∂y\frac{\partial I}{\partial y}yI是图像I(x,y,t))I(x,y,t))I(x,y,t))yyy方向的偏导数,表示图像亮度在垂直(y)方向上的变化速率(即图像在yyy方向上的梯度);
  • ∂I∂t\frac{\partial I}{\partial t}tI是图像I(x,y,t)I(x,y,t)I(x,y,t)随时间ttt变化的偏导数,表示图像亮度在时间方向上的变化速率(即图像随时间变化的亮度变化)。

现在,我们将泰勒展开的结果代入亮度恒定假设中:
I(x,y,t)=I(x+Δx,y+Δy,t+Δt)=I(x,y,t)+IxΔx+IyΔy+ItΔtI(x,y,t)=I(x+\Delta x,y+\Delta y,t+\Delta t)=I(x,y,t)+I_x\Delta x+I_y\Delta y+I_t\Delta tI(x,y,t)=I(x+Δx,y+Δy,t+Δt)=I(x,y,t)+IxΔx+IyΔy+ItΔt
其中:

  • Ix=∂I∂xI_x=\frac{\partial I}{\partial x}Ix=xI是图像在xxx方向的梯度;
  • Iy=∂I∂yI_y=\frac{\partial I}{\partial y}Iy=yI是图像在yyy方向的梯度;
  • It=∂I∂tI_t=\frac{\partial I}{\partial t}It=tI是图像在ttt方向的梯度。

由于左侧的两个I(x,y,t)I(x,y,t)I(x,y,t)相等,可以将它们抵消掉:
0=IxΔx+IyΔy+ItΔt0=I_x\Delta x+I_y\Delta y+I_t\Delta t0=IxΔx+IyΔy+ItΔt
接下来,假设Δx\Delta xΔxΔy\Delta yΔy是该像素的位移(即物体运动导致该像素位置的变化),我们可以将Δx\Delta xΔxΔy\Delta yΔy表示为光流的分量uuuvvv,即:
Δx=uΔt\Delta x=u\Delta tΔx=uΔt
Δy=vΔt\Delta y=v\Delta tΔy=vΔt
其中:

  • uuu是图像中像素在方向的运动速度(光流的水平分量);
  • vvv是图像中像素在方向的运动速度(光流的垂直分量);
  • Δt\Delta tΔt是两个时间帧之间的时间差。

将这些表达式代入之前的方程,我们得到:
0=IxuΔt+IyvΔt+ItΔt0=I_xu\Delta t+I_yv\Delta t+I_t\Delta t0=IxuΔt+IyvΔt+ItΔt
由于Δt\Delta tΔt是一个常数,且不等于零,我们可以把Δt\Delta tΔt消去,得到光流的核心方程:
Ixu+Iyv+It=0I_xu+I_yv+I_t=0Ixu+Iyv+It=0
这个方程描述了在每个像素点上,图像亮度变化与该点的运动(光流)之间的关系。它给出了光流uuuvvv的关系:像素的运动(光流)与图像的梯度信息(在空间和时间上的变化)有关。

三、计算Ix,Iy,ItI_x,I_y,I_tIx,Iy,It

四、计算光流u,vu,vu,v

4.1 传统算法Lucas-Kanade算法

增加一个假设:假设在小窗口内,光流是恒定的。
算法的核心思想是通过在该窗口内对每个像素的光流方程进行加权最小二乘法拟合,从而估算出该窗口内所有像素的水平和垂直方向的光流(即uuuvvv)。
Ixu+Iyv+It=0I_xu+I_yv+I_t=0Ixu+Iyv+It=0
我们将上述公式转为矩阵形式:
(Ix,Iy)(uv)=−It(I_x,I_y)\begin{pmatrix} u\\ v \end{pmatrix}=-I_t(Ix,Iy)(uv)=It
所以,如果我们选择一个n×nn \times nn×n的窗口(包含n2n^2n2个像素),那么每个像素的光流满足相同的方程。对于这个窗口内的所有像素,我们可以构建以下方程组:
{Ix1u+Iy1v=−It1Ix2u+Iy2v=−It2⋮Ixnu+Iynv=−Itn\left\{\begin{matrix} I_{x1}u+I_{y1}v=-I_{t1}\\ I_{x2}u+I_{y2}v=-I_{t2}\\ \vdots \\ I_{xn}u+I_{yn}v=-I_{tn} \end{matrix}\right.Ix1u+Iy1v=It1Ix2u+Iy2v=It2Ixnu+Iynv=Itn
将上述方程组转为矩阵形式:
[Ix1Iy1Ix2Iy2⋮⋮IxnIyn][uv]=−[It1It2⋮Itn]\begin{bmatrix} I_{x1} & I_{y1}\\ I_{x2} & I_{y2}\\ \vdots &\vdots \\ I_{xn} &I_{yn} \end{bmatrix}\begin{bmatrix} u\\ v \end{bmatrix}=-\begin{bmatrix} I_{t1}\\ I_{t2}\\ \vdots\\ I_{tn} \end{bmatrix}Ix1Ix2IxnIy1Iy2Iyn[uv]=It1It2Itn
令左边矩阵为AAA,中间矩阵为xxx,右边矩阵为bbb,上述公式转为:
Ax=bAx=bAx=b
利用最小二乘法的解法,我们可以得到uuuvvv的解:
x=(ATA)−1ATbx=(A^TA)^{-1}A^{T}bx=(ATA)1ATb
观察上述公式可以发现一个问题:ATAA^TAATA一定有逆吗?参看第五节。

五、孔径问题

5.1 直观理解

想象你透过一个小孔(比如一根吸管)去观察一条运动的直线。如果这条直线向右上方移动,你在小孔里看到的只是直线的一小段。由于你只能看到局部信息,你会发现:

  • 直线沿着垂直于自身的方向移动时,亮度会明显变化;
  • 但如果直线沿着平行于自身的方向移动时,局部的亮度看起来几乎不变。

结果就是:
你无法仅凭小孔里的这一小段直线判断运动的真实方向,只能感知到垂直于边缘的运动,而沿边缘方向的运动信息丢失。
这就是“孔径问题”的由来。

5.2 数学角度

光流基本方程是:
Ixu+Iyv+It=0I_xu+I_yv+I_t=0Ixu+Iyv+It=0
这是一个一元约束(一条方程),但我们有两个未知数(u,v)(u,v)(u,v)
结果是:我们只能确定光流在图像梯度方向上的分量,而沿着等梯度方向的分量无法确定。
举个例子:

  • 如果图像中某个区域是纯水平边缘(亮度只随 y 变化),则Ix=0,Iy≠0I_x=0,I_y \neq 0Ix=0,Iy=0
  • 则方程变成Iyv+It=0I_yv+I_t=0Iyv+It=0。这时候我们只能解出vvv(垂直方向的运动),而uuu(水平方向的运动)完全不受约束。
  • 这就是孔径问题:缺少运动方向的完整信息。

那么与ATAA^TAATA是否可逆有什么关系呢?
我们先考虑一下有哪些情况ATAA^TAATA不可逆:

  1. 像素的梯度信息缺失或重复:如果图像中的某个区域(或多个区域)的梯度信息是重复的或无效的,那么矩阵的列会变得线性相关。例如,如果在某个区域内图像亮度完全不变化(如纯白色区域),那么,这意味着我们无法从该像素中提取任何有用的运动信息,导致梯度矩阵的列是线性相关的。
  2. 没有足够的运动信息:在一些特定情况下,比如图像中存在单一的边缘(比如水平或垂直边缘),我们只能检测到沿边缘方向的运动,而无法感知到垂直于边缘方向的运动。这会导致方向的梯度相同或相互平行,进而使得矩阵变得奇异(不可逆)。
  3. 局部区域的梯度信息不足:如果选择的局部窗口区域太小,导致该区域内的图像梯度几乎没有变化,也可能导致的列线性相关。例如,如果选择一个只有一条直线的区域,那么该区域内的梯度信息就没有足够的多样性来推测所有方向的运动。

是不是有点眼熟,好像我们刚刚在直观理解里面提到过一些东西?没错,孔径问题是在一定程度上可以用ATAA^TAATA不可逆来解释的。那么ATAA^TAATA不可逆会出现什么情况呢?可能会出现多解,也就是不能准确估计运动方向。

5.3 解决方法

既然ATAA^TAATA不可逆会出现孔径问题,那么我们不用ATAA^TAATA不可逆的地方不就行了?
因此我们可以选择一些角点,这样保证ATAA^TAATA可逆,就可以保证光流估计运动方向的精度了。

总结


文章转载自:

http://XSoeTe9L.Lhytw.cn
http://L1Qdbvzl.Lhytw.cn
http://R81zqRfP.Lhytw.cn
http://s1CAi99m.Lhytw.cn
http://7c8lwiS4.Lhytw.cn
http://4606MDSR.Lhytw.cn
http://sT6HoBeJ.Lhytw.cn
http://Cq2Ulbp4.Lhytw.cn
http://BinQ82b3.Lhytw.cn
http://MzjzzpnR.Lhytw.cn
http://u8goAviJ.Lhytw.cn
http://lQVVGiyW.Lhytw.cn
http://rdTbOaVb.Lhytw.cn
http://igVHkmwL.Lhytw.cn
http://fXNkSBLL.Lhytw.cn
http://JmXZIW4F.Lhytw.cn
http://MzUZfmsh.Lhytw.cn
http://jiefOylI.Lhytw.cn
http://lYdIoKqg.Lhytw.cn
http://IpAlXHNE.Lhytw.cn
http://3aRYnL08.Lhytw.cn
http://SWOVlJ5v.Lhytw.cn
http://CV63Eet6.Lhytw.cn
http://Ne4k5sFu.Lhytw.cn
http://sC0uFN9y.Lhytw.cn
http://3HRX6diU.Lhytw.cn
http://6m3icNC9.Lhytw.cn
http://WQ3yEsmO.Lhytw.cn
http://RDnVal6p.Lhytw.cn
http://ZNMhDLYN.Lhytw.cn
http://www.dtcms.com/a/373143.html

相关文章:

  • VMware 如何创建链接克隆虚拟机
  • Excel处理控件Aspose.Cells教程:使用 Python 将 Pandas DataFrame 转换为 Excel
  • 【回眸】Tessy 基础操作指南
  • 更智能的零售终端设备管理:合规、安全与高效
  • TCP/IP、HTTP 和 HTTPS简介
  • UNBIASED WATERMARK:大语言模型的无偏差水印
  • Android Studio处理异常报错:Cause connect timed out
  • 基于哈塞特独立性表态的AI量化研究:美联储政策独立性的多维验证
  • 人工智能-python-深度学习-经典神经网络AlexNet
  • SpringBoot集成电科金仓数据库(上):环境搭建与基础配置
  • AR 巡检与普通巡检有哪些区别,有哪些优势|阿法龙XR云平台
  • Web与Nginx网站服务二
  • [硬件电路-166]:Multisim - SPICE与Verilog语言的区别
  • 计算机毕业设计 基于Python+Django的医疗数据分析系统
  • 鸿蒙:绑定半模态页面(bindSheet)
  • 001-003 产品经理-ML应用构建-ML应用范围
  • Node中使用 fs 和 node:fs 的区别与选择
  • SYN 包在什么场景下会被丢弃
  • R 语言科研绘图 --- 其他绘图-汇总2
  • Aider AI Coding 多策略编码系统深度分析报告
  • 胜券POS:打造智能移动终端,让零售智慧运营触手可及
  • tensorflow.js 使用场景
  • 【技术教程】如何将ONLYOFFICE文档集成到使用Spring Boot框架编写的Java Web应用程序中
  • 安卓学习 之 用户登录界面的简单实现
  • 3 提示词(Prompt):大模型的交互语言
  • 微信小程序体验版,当打开调试模式正常访问,关闭之后无法访问
  • 虚拟机ubuntu22.04没有网
  • 【WorkManager】无法在 Direct Boot 模式下初始化
  • Prompt Engineering to Context Engineering
  • Swift 语法学习指南 - 与 Kotlin 对比