计算机视觉——光流法

系列文章目录

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

文章目录


前言

光流(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://www.pswp.cn/pingmian/95898.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/95898.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

前端安全攻防:XSS, CSRF 等防范与检测

前端安全攻防:XSS, CSRF 等防范与检测在Web应用日益普及的今天,前端安全已经成为一个不容忽视的重要环节。随着攻击技术的不断演进,各种前端安全漏洞(如跨站脚本攻击 XSS、跨站请求伪造 CSRF 等)层出不穷,它…

03OpenCV图像处理

参考课程: 【黑马程序员 OpenCV入门教程】 [https://www.bilibili.com/video/BV1Fo4y1d7JL] ZZHow(ZZHow1024) 1.1几何变换 图像缩放 对图像的大小进行调整,即使图像放大或缩小 cv2.resize(src, dsize, fx0, fy0, interpolationcv2.INTER_LINEAR)参数…

UE5 C++ 第三方动态库的使用

一. 首先要拷贝对应的 第三方库 bin里有dll动态库,include里有动态库需要的头文件。 二.在Target.cs里,进行设置 头文件前面的路径为公共路径 设置需要一起打包的三方库文件 三.加载这个库 FPlatformProcess::GetDllHandle将他解析为 任意类型&#x…

C++进阶——多态

ʕ • ᴥ • ʔ づ♡ど 🎉 欢迎点赞支持🎉 个人主页:励志不掉头发的内向程序员; 专栏主页:C语言; 文章目录 前言 一、多态的概念 二、多态的定义及实现 2.1、多态的构成条件 (1)虚函…

Swift 语法学习指南 - 与 Kotlin 对比

Swift 语法学习指南 - 与 Kotlin 对比 本指南专为有 Android/Kotlin 开发经验的开发者设计,通过对比学习快速掌握 Swift 语法 目录 语言基础对比变量与常量数据类型函数定义类与结构体继承与协议可选类型集合类型控制流闭包与Lambda扩展与Extension错误处理内存管理…

嵌入式C语言笔记十七——构造数据类型

一.结构体:1.类型定义:struct 结构体名 {数据类型1 成员变量1;数据类型2 成员变量2;数据类型3 成员变量3;... };struct student {char name[32];char sex;int age;int score; };2.结构体变量定义:存储类型 数据类型 变量名;3.结构体元素初始化…

深入实践G1垃圾收集器调优:Java应用性能优化实战指南

深入实践G1垃圾收集器调优:Java应用性能优化实战指南 一、技术背景与应用场景 随着微服务和海量并发请求的普及,Java应用在生产环境中对低延迟和高吞吐的需求日益显著。传统的CMS和Parallel GC 在大内存场景下常出现Full GC 停顿时间长、吞吐下降等问题…

【JobScheduler】Android 后台任务调度的核心组件指南

JobScheduler 是 Android 平台上原生支持在直接启动模式(Direct Boot Mode)下执行任务的调度器。 相比 WorkManager 需要复杂的配置才能勉强支持直接启动,JobScheduler 在这方面有着天生的优势和明确的 API 支持。如果你面临的硬性要求是必须…

c# 调用basler 相机

目录 一联合halcon: 二 c# 原生 一联合halcon: 环境配置 下载安装pylon软件 下载安装halcon 创建 winform项目 test_basler 添加引用 打开pylon可以连接相机 可以看到我的相机id为23970642 ( c#联合halcon的基础教程(案例…

《2025年AI产业发展十大趋势报告》四十六

《2025年AI产业发展十大趋势报告》四十六随着科技的迅猛发展,人工智能(AI)作为引领新一轮科技革命和产业变革的战略性技术,正逐步渗透到各个行业和领域,成为推动经济社会发展的重要引擎。2023年,生成式AI的…

c++ 杂记

1. 为什么返回*this?2. 3. 友元函数的使用&#xff1a;需要头文件中类内外声明&#xff0c;cpp文件中实现定义哦// Sales_data.h #ifndef SALES_DATA_H #define SALES_DATA_H#include <string>class Sales_data {std::string bookNo;int units_sold 0;double revenue …

PDF文件基础-计算机字体

计算机字体的原理包含了字符编码、字形渲染和字体文件存储三个关键技术。 字符编码负责将每个字符映射到一个唯一的数字码&#xff1b;字形渲染则将这些数字码转换成屏幕或纸张上可识别的图形&#xff1b;字体文件存储则包含了字符的编码、图形描述信息以及字体的其他属性&…

华为IP(9)

OSPF的基本配置OSPF路由计算前言&#xff1a;1)同一区域内的OSPF路由器拥有完全一致的LSDB&#xff0c;在区域内部&#xff0c;OSPF采用SPF算法完成路由计算。2&#xff09;随着网络规模不断扩大&#xff0c;路由器为了完成路由计算所消耗的内存、CPU资源也越来越多。通过区域划…

java.nio.file.InvalidPathException异常

一.问题概述 本人在ubuntu22.04的操作系统上&#xff0c;运行java程序时创建一个文件时&#xff0c;由于文件名称中包含了中文&#xff0c;所以导致了程序抛出了java.nio.file.InvalidPathException的异常。 java.nio.file.InvalidPathException: Malformed input or input co…

Next系统总结学习(一)

下面我按题号逐条 详细 解释并给出示例与最佳实践。为便于阅读&#xff0c;我会同时给出关键代码片段&#xff08;伪代码/实用例子&#xff09;&#xff0c;并指出常见坑与解决方案。 1. 你是如何理解服务端渲染&#xff08;SSR&#xff09;的&#xff1f;它的核心工作流程是怎…

房屋安全鉴定需要什么条件

房屋安全鉴定需要什么条件&#xff1a;专业流程与必备要素解析房屋安全鉴定是保障建筑使用安全的重要环节&#xff0c;它通过对建筑结构、材料性能及使用状况的全面评估&#xff0c;为房屋的安全使用、改造或维护提供科学依据。随着城市建筑老化及自然灾害频发&#xff0c;房屋…

现代C++:现代C++?

C语言正在走向完美&#xff0c;所以&#xff0c;C语言值得学习&#xff08;甚至研究&#xff09;&#xff0c;这些知识可以成为一切编程的基础。然而在实践中&#xff0c;不必全面的使用C语言的各种特性&#xff0c;而应根据工程项目的实际情况&#xff0c;适当取舍&#xff08…

【C++】哈希表实现

1. 哈希概念 哈希(hash)又称散列&#xff0c;是⼀种组织数据的方式。从译名来看&#xff0c;有散乱排列的意思。本质就是通过哈希 函数把关键字Key跟存储位置建立一个映射关系&#xff0c;查找时通过这个哈希函数计算出Key存储的位置&#xff0c;进行快速查找 1.1 直接定址法…

ai 玩游戏 llm玩街霸 大模型玩街霸 (3)

1. 开源代码地址&#xff1a; https://github.com/OpenGenerativeAI/llm-colosseum 2. 架构&#xff1a; 3. 图片&#xff1a; 4. 感觉还是下面的步骤&#xff1a; a. 实时理解游戏当前环境&#xff0c;英雄角色&#xff0c;英雄状态 b. 根据当前状态感知&#xff0c;生成英雄…

2025年渗透测试面试题总结-59(题目+回答)

安全领域各种资源&#xff0c;学习文档&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具&#xff0c;欢迎关注。 目录 一、SQL注入全解 二、XSS与文件漏洞 三、服务端漏洞专题 四、职业经验与能力评估 1、注入攻击原理是什么…