slam14讲(第8讲、前端里程计)LK光流、直接法

直接法的引出

因为第7讲大部分都是讲特征点法,通过提取orb特征点和点的描述子,来构建两帧图像之间的特征点对应关系。这种方法会有缺点:

  1. 关键点和描述子提取计算耗时,如果相机的频率高,则slam算法大部分耗时被占。
  2. 特征点是稀疏的,往往只有几百个,而且在我看来容易被一些动态物体干扰,就会对后续匹配造成影响。
  3. 在一些特征不明显的地方,大白墙或者没有明显角点的地方,特征点难提取,对后续计算相机运动造成影响。

光流法

光流可以分成稀疏光流和稠密光流。Lucas-Kanade光流跟踪部分像素点的运动成为稀疏光流,Horn-Schunck光流跟踪所有像素点的运动成为稠密光流。而书中主要是介绍了LK稀疏光流法。

个人见解

光流法的作用就是用来跟踪上一帧图片的像素点在当前帧图片中的位置,本质上也是特征匹配的一种方法,只是特征点法的特征匹配是通过点的描述子来进行匹配,而LK光流从图像入手,在灰度不变假设上,根据两帧图像求出跟踪像素点的运动速度,从而在第二帧图片中找到跟踪点的像素。后续就是简单列一下书里的公式。

公式推导

将图片看成是关于时间(t)和像素(u,v)的函数,即三元函数。根据灰度不变假设,对于t时刻在第一帧图片(x,y)的像素,根据灰度不变:
I ( x + d x , y + d y , t + d t ) = I ( x , y , t ) \boldsymbol{I}(x+\mathrm{d} x, y+\mathrm{d} y, t+\mathrm{d} t)=\boldsymbol{I}(x, y, t) I(x+dx,y+dy,t+dt)=I(x,y,t)
然后就是经典的一阶泰勒展开:
I ( x + d x , y + d y , t + d t ) ≈ I ( x , y , t ) + ∂ I ∂ x d x + ∂ I ∂ y d y + ∂ I ∂ t d t \boldsymbol{I}(x+\mathrm{d} x, y+\mathrm{d} y, t+\mathrm{d} t) \approx \boldsymbol{I}(x, y, t)+\frac{\partial \boldsymbol{I}}{\partial x} \mathrm{~d} x+\frac{\partial \boldsymbol{I}}{\partial y} \mathrm{~d} y+\frac{\partial \boldsymbol{I}}{\partial t} \mathrm{~d} t I(x+dx,y+dy,t+dt)I(x,y,t)+xI dx+yI dy+tI dt
因为灰度不变,所以只剩三项:
∂ I ∂ x d x + ∂ I ∂ y d y + ∂ I ∂ t d t = 0 \frac{\partial \boldsymbol{I}}{\partial x} \mathrm{~d} x+\frac{\partial \boldsymbol{I}}{\partial y} \mathrm{~d} y+\frac{\partial \boldsymbol{I}}{\partial t} \mathrm{~d} t=0 xI dx+yI dy+tI dt=0
然后就是除dt移项
∂ I ∂ x d x d t + ∂ I ∂ y d y d t = − ∂ I ∂ t \frac{\partial \boldsymbol{I}}{\partial x} \frac{\mathrm{d} x}{\mathrm{~d} t}+\frac{\partial \boldsymbol{I}}{\partial y} \frac{\mathrm{d} y}{\mathrm{~d} t}=-\frac{\partial \boldsymbol{I}}{\partial t} xI dtdx+yI dtdy=tI
对于上面这个式子, d x / d t dx/dt dx/dt d y / d t dy/dt dy/dt就是我们要求的像素点的运动速度,记为u和v。其他项就是图像关于x,y,t的梯度,通过opencv或者自己去计算都可以求。最终就有
[ I x I y ] [ u v ] = − I t \left[\begin{array}{ll}\boldsymbol{I}_x & \boldsymbol{I}_y\end{array}\right]\left[\begin{array}{l}u \\ v\end{array}\right]=-\boldsymbol{I}_t [IxIy][uv]=It
但是只有一个像素点只有一个方程,所以一般是假设在点附近的一个窗口具有同样的运动,所以取一个w*w的窗口,就有 w 2 w^2 w2个方程
[ I x I y ] k [ u v ] = − I t k , k = 1 , … , w 2 \left[\begin{array}{ll}\boldsymbol{I}_x & \boldsymbol{I}_y\end{array}\right]_k\left[\begin{array}{l}u \\ v\end{array}\right]=-\boldsymbol{I}_{t k}, \quad k=1, \ldots, w^2 [IxIy]k[uv]=Itk,k=1,,w2
这个就是用经典最小二乘法即可求出u和v,因为两帧图像的时间差是已知的,所以就可以在当前帧得到上一帧的对应点位置。

代码实现

书中除了直接用opencv去实现光流,同样通过高斯牛顿手写了一个光流法。本质上是求解一个优化问题:
min ⁡ Δ x , Δ y ∥ I 1 ( x , y ) − I 2 ( x + Δ x , y + Δ y ) ∥ 2 2 \min _{\Delta x, \Delta y}\left\|\boldsymbol{I}_1(x, y)-\boldsymbol{I}_2(x+\Delta x, y+\Delta y)\right\|_2^2 Δx,ΔyminI1(x,y)I2(x+Δx,y+Δy)22
这个写法有点像直接法的光度误差,只不过目标不一样,光流法求的是上一帧跟踪像素点在当前帧图片的像素位置。那么对应的雅可比就是 I 2 I_2 I2 x + Δ x , y + Δ y x+\Delta x, y+\Delta y x+Δx,y+Δy 处的梯度。但是这样子的定义感觉是有些歧义,最好是把 x + Δ x , y + Δ y x+\Delta x, y+\Delta y x+Δx,y+Δy当成一个整体 x 2 , y 2 x_2,y_2 x2,y2,优化目标就是 x 2 , y 2 x_2,y_2 x2,y2(即跟踪点在第二帧图片的位置)。
请添加图片描述
这样展开才能说得过去对应的雅可比就是 I 2 I_2 I2 x + Δ x , y + Δ y x+\Delta x, y+\Delta y x+Δx,y+Δy 处的梯度。也可以参考SLAM光流法、直接法代码踩坑记录

然后后续程序就是基于单层光流去构建构建图像金字塔从粗到细实现多层光流,多层光流实际上可以帮助整个优化问题更好逼近全局最优解,而不是受图像梯度影响陷入局部最优。
在这里插入图片描述

代码结果

很明显在目标函数优化后的误差,多层光流是优于单层光流的,也证明了多层光流的有效性。

直接法

直接法根据像素点的数量,可以分成稀疏、稠密和半稠密三种。与上面LK光流的区别在于,直接法通过构建两帧图片之间的光度误差,来直接优化两帧的R和t。而LK光流只是完成了像素点跟踪的问题。

公式推导

用下书的原图:
在这里插入图片描述
对于同一个三维点P,有下面的式子:其实就是相机模型的式子
p 1 = [ u v 1 ] 1 = 1 Z 1 K P , p 2 = [ u v 1 ] 2 = 1 Z 2 K ( R P + t ) = 1 Z 2 K ( T P ) 1 : 3 . \begin{aligned} & \boldsymbol{p}_1=\left[\begin{array}{l}u \\ v \\ 1\end{array}\right]_1=\frac{1}{Z_1} \boldsymbol{K} \boldsymbol{P}, \\ & \boldsymbol{p}_2=\left[\begin{array}{l}u \\ v \\ 1\end{array}\right]_2=\frac{1}{Z_2} \boldsymbol{K}(\boldsymbol{R} \boldsymbol{P}+\boldsymbol{t})=\frac{1}{Z_2} \boldsymbol{K}(\boldsymbol{T} \boldsymbol{P})_{1: 3} .\end{aligned} p1= uv1 1=Z11KP,p2= uv1 2=Z21K(RP+t)=Z21K(TP)1:3.

然后就是通过光度误差构建优化问题。
e = I 1 ( p 1 ) − I 2 ( p 2 ) e=\boldsymbol{I}_1\left(\boldsymbol{p}_1\right)-\boldsymbol{I}_2\left(\boldsymbol{p}_2\right) e=I1(p1)I2(p2)
min ⁡ T J ( T ) = ∥ e ∥ 2 \min _{\boldsymbol{T}} J(\boldsymbol{T})=\|e\|^2 minTJ(T)=e2
对于多个空间点就能构成多个误差项
min ⁡ T J ( T ) = ∑ i = 1 N e i T e i , e i = I 1 ( p 1 , i ) − I 2 ( p 2 , i ) \min _{\boldsymbol{T}} J(\boldsymbol{T})=\sum_{i=1}^N e_i^{\mathrm{T}} e_i, \quad e_i=\boldsymbol{I}_1\left(\boldsymbol{p}_{1, i}\right)-\boldsymbol{I}_2\left(\boldsymbol{p}_{2, i}\right) TminJ(T)=i=1NeiTei,ei=I1(p1,i)I2(p2,i)

接下来就是去求误差对位姿T的雅可比。定义两个中间变量:
q = T P , u = 1 Z 2 K q \begin{aligned} \boldsymbol{q} & =\boldsymbol{T} \boldsymbol{P}, \\ \boldsymbol{u} & =\frac{1}{Z_2} \boldsymbol{K} \boldsymbol{q} \end{aligned} qu=TP,=Z21Kq
q是图中三维点P经过T的变换后在第二帧图像的三维坐标,u就是其在第二帧图像对应的像素。接着也是一阶的泰勒展开:
∂ e ∂ T = ∂ I 2 ∂ u ∂ u ∂ q ∂ q ∂ δ ξ δ ξ \frac{\partial e}{\partial \boldsymbol{T}}=\frac{\partial \boldsymbol{I}_2}{\partial \boldsymbol{u}} \frac{\partial \boldsymbol{u}}{\partial \boldsymbol{q}} \frac{\partial \boldsymbol{q}}{\partial \delta \boldsymbol{\xi}} \delta \boldsymbol{\xi} Te=uI2quδξqδξ
最终可以得到:
J = − ∂ I 2 ∂ u ∂ u ∂ δ ξ \boldsymbol{J}=-\frac{\partial \boldsymbol{I}_2}{\partial \boldsymbol{u}} \frac{\partial \boldsymbol{u}}{\partial \delta \boldsymbol{\xi}} J=uI2δξu
其中
∂ u ∂ δ ξ = [ f x Z 0 − f x X Z 2 − f x X Y Z 2 f x + f x X 2 Z 2 − f x Y Z 0 f y Z − f y Y Z 2 − f y − f y Y 2 Z 2 f y X Y Z 2 f y X Z ] \frac{\partial \boldsymbol{u}}{\partial \delta \boldsymbol{\xi}}=\left[\begin{array}{cccccc}\frac{f_x}{Z} & 0 & -\frac{f_x X}{Z^2} & -\frac{f_x X Y}{Z^2} & f_x+\frac{f_x X^2}{Z^2} & -\frac{f_x Y}{Z} \\ 0 & \frac{f_y}{Z} & -\frac{f_y Y}{Z^2} & -f_y-\frac{f_y Y^2}{Z^2} & \frac{f_y X Y}{Z^2} & \frac{f_y X}{Z}\end{array}\right] δξu=[Zfx00ZfyZ2fxXZ2fyYZ2fxXYfyZ2fyY2fx+Z2fxX2Z2fyXYZfxYZfyX]
是前面BA也涉及到的雅可比,经典像素对左扰动的雅可比。

代码实现

书中的代码也是给出了手动高斯牛顿的方法,并且结合图像金字塔。结果也是显然,多层直接发的误差最终是更小,效果也更好。

总结

光流法总结

本质上做了特征匹配的工作,光流法通过估计像素的运动来得到上一帧跟踪点在当前帧图像的像素位置。
优点:

  1. 运算速度快,因为省去了计算特征点描述子和特征匹配的过程

缺点:

  1. 灰度不变是很强的假设,实际并不一定满足,对图像的连续性和光照稳定性要求高
  2. 如果在一些角点很难提取的地方,像素点的跟踪效果会变差,导致后续位姿估计的结果

直接发总结

直接基于两帧图片,构建光度误差优化两帧图像之间的R和t。避免了跟踪点的过程。
优点:

  1. 直接法根据点的来源分成稀疏直接法,半稠密直接法,稠密直接法。一般稀疏直接法用于实时性要求高的视觉定位系统中。稠密直接法一般用于结构重建上。
  2. 稀疏直接法计算速度快,省去计算特征点和描述子的时间,实时性较好。
  3. 有像素梯度即可,不要求特征点,所以在一些特征缺失的场景可以使用。

缺点:

  1. 本质上图像是非凸函数,所以优化的过程中会容易陷入局部最优。可以通过图像金字塔改善效果。
  2. 直接法在选点少的情况下,效果不好,一般建议500个点以上。
  3. 灰度不变假设,实际不一定满足。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/14224.shtml

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

相关文章

【MySQL精通之路】InnoDB(10)-行格式

目录 1.表数据结构 1.1 聚集索引数据结构 1.2 辅助索引数据结构 2.行格式 2.1 REDUNDANT行格式 2.2 REDUNDANT存储特性 2.3 COMPACT行格式 2.4 COMPACT存储特性 2.5 DYNAMIC行格式 2.6 DYNAMIC存储特性 2.7 COMPRESSED行格式 2.8 COMPRESSED存储特性 3.定义表格的…

数组-区间合并

一、题目描述 二、题目思路 这里提供满足基本要求的解题思路: 1.先对列表内按照start大小升序排序,这里创建Comparator接口的实现类,重写compare方法。 2.遍历intervals,设置laststart、lastend两个变量与当前区间相比较&#…

Ansible实战YAML语言完成apache的部署,配置,启动全过程

🏡作者主页:点击! 🏝️Ansible专栏:点击! ⏰️创作时间:2024年5月24日15点59分 目录 💯趣站推荐💯 🎊前言 ✨️YAML语言回顾 🎆1.编写YAML文…

k近邻和kd树

K近邻 选取k值的时候可以采用交叉验证的方法 一般采用欧氏距离 kd树 采用树这个特殊的数据结构来实现k近邻算法 先假设是二维的情况 下面讲解kd树的完整构造过程 找这个中位数是按照每棵子树来创建的 前提是已经有了一棵kd树,然后来一个实例点

Python UDP编程简单实例

TCP是建立可靠的连接,并且通信双方都可以以流的形式发送数据。 相对于TCP,UDP则是面向无连接的协议,不需要建立连接,只需要知道对方IP地址和端口号,就可以直接发送数据包。但是只管发送不保证到达。 虽然UDP传输数据…

Docker快速部署Seata的TC服务以及微服务引入Seata教程

目录 一、使用docker部署Seata的TC服务 1、拉取TC服务镜像 2、创建并运行容器 ​3、修改配置文件 4、在Nacos中添加TC服务的配置 5、重启TC服务 二、微服务集成Seata 1、引入依赖 2、修改配置文件 Seata是阿里的一个开源的分布式事务解决方案,能够为分布…

STM32学习和实践笔记(31):输入捕获实验

1.输入捕获介绍 在定时器中断实验章节中我们介绍了通用定时器具有多种功能,输入捕获就是其中一种。STM32F1除了基本定时器TIM6和TIM7,其他定时器都具有输入捕获功能。输入捕获可以对输入的信号的上升沿,下降沿或者双边沿进行捕获,…

Redis系统架构中各个处理模块是干什么的?no.19

Redis 系统架构 通过前面的学习,相信你已经掌握了 Redis 的原理、数据类型及访问协议等内容。本课时,我将进一步分析 Redis 的系统架构,重点讲解 Redis 系统架构的事件处理机制、数据管理、功能扩展、系统扩展等内容。 事件处理机制 Redis…

SSMP整合案例第一步 制作分析模块创建与开发业务实体类

制作分析 我们要实现一个模块的增删改查 实际开发中mybatisplus用的不多,他只能对没有外键的单表进行简单的查询 但在这个案例中我们还是选择mybatisplus开发 模块创建 我们把所有服务器都放在一起 就不用前后端分离 我们尝试用后端开发进行全栈开发 新建项目添…

Thinkphp3.2.3网站后台不能访问如何修复

我是使用Thinkphp3.2.3新搭建的PHP网站,但是网站前台可以访问,后台访问出现如图错误: 由于我使用的Hostease的Linux虚拟主机产品默认带普通用户权限的cPanel面板,对于上述出现的问题不清楚如何处理,因此联系Hostease的…

(3)医疗图像处理:MRI磁共振成像-快速采集--(杨正汉)

目录 一、磁共振快速采集技术基础 1.K空间的基本特点 2.快速成像的理由: 3.快速成像的硬件要求: 二、磁共振快速采集技术 1.采集更少的相位编码线 2.平行采集技术PAT 3.其他与快速采集有关的技术 1)部分回波技术 2)频率…

java如何获取IP和IP的归属地?

在Java中,获取IP地址通常指的是获取本地机器的IP地址或者通过某种方式(如HTTP请求)获取的远程IP地址。代码案例如下: 而要获取IP的归属地(地理位置信息),则通常需要使用第三方IP地址查询服务,我…

23种设计模式顺口溜

口诀: 原型 抽风 ,单独 建造 工厂 (寓意:(这里代指本来很简单的东西,却要干工厂这里复杂的业务) 抽风:抽象工厂单独:单例桥代理组合享元适配器,&#xff0…

亚马逊云科技介绍

🔥博客主页: 小羊失眠啦. 🎥系列专栏:《C语言》 《数据结构》 《C》 《Linux》 ❤️感谢大家点赞👍收藏⭐评论✍️ 文章目录 一、亚马逊云科技云计算1.1 云计算的优势 二、领先的云平台三、亚马逊云科技区域的全球网络…

最简单的,在mac笔记本上安装Unix-v6系统,进行“Unix内核源码剖析”

Unix V6 已经是 1975 年的系统了,但是其源代码拢共只有 1w 行左右,并且使用了 C 语言(K & R 之前的标准),还是现代操作系统的鼻祖,所以说是初学者最好的研究对象。 安装模拟器 brew install simh …

平衡发展与环保:理性看待地下式污水处理厂建设|中联环保圈

这些年啊,随着城市化进程越来越快,还有环境保护意识不断提高,这地下式污水处理厂慢慢就成了热门的建设趋势了。据相关统计,全球现在运行着 200 多座地下式污水处理厂呢,咱国家建成和在建的数量也差不多快到 200 座啦。…

基于transformers框架实践Bert系列4-文本相似度

本系列用于Bert模型实践实际场景,分别包括分类器、命名实体识别、选择题、文本摘要等等。(关于Bert的结构和详细这里就不做讲解,但了解Bert的基本结构是做实践的基础,因此看本系列之前,最好了解一下transformers和Bert…

STM32入门笔记(02):USART串口通信注意事项笔记(SPL库函数版)

这是通过串口通信发送过来的数据,里面包括了故障码,电压,电流,频率等信息,请你用STM32f103系列单片机的串口1读取该数据并解析出电压和电流是多少? 要用STM32F103系列单片机的串口1读取并解析发电机上的逆…

【Django项目】 音乐网站spotify复刻

代码:https://github.com/tomitokko/spotify-clone 注:该项目不是自己提供mp3文件,而是使用spotify 的api接口获取。