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

news2024/12/26 23:31:54

直接法的引出

因为第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.coloradmin.cn/o/1685231.html

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

相关文章

轻量SEO分析报告程序网站已开心去授权

轻量SEO分析报告程序网站已开心去授权,可以让你生成有洞察力的、 简洁的、易于理解的SEO报告,帮助你的网页排名和表现更好 网站源码免费下载地址抄笔记 (chaobiji.cn)https://chaobiji.cn/

算法学习:快速排序

🔥 个人主页:空白诗 文章目录 🚀 引言📌 快速排序算法核心思想1. 选择基准值(Pivot)2. 分区操作(Partitioning)3. 递归排序子序列 📌 JavaScript 实现1. 快速排序主函数2…

OGG几何内核-BRepBuilderAPI_MakeEdge学习

OGG几何内核fork自OCCT 7.7.0, BRepBuilderAPI_MakeEdge是几何内核的一个重要和基础的功能,也十分复杂,因为要支持line、circle、ellipse,parabola,hyperbola,circle,beziercurve,b…

Web前端开发技术-格式化文本 Web页面初步设计

目录 Web页面初步设计 标题字标记 基本语法: 语法说明: 添加空格与特殊符号 基本语法: 语法说明: 特殊字符对应的代码: 代码解释: 格式化文本标记 文本修饰标记 计算机输出标记 字体font标记 基本语法: 属…

《TortoiseSVN》简单使用说明

##################工作记录#################### 常用图标说明 一个新检出的工作副本 修改过的文件 更新过程遇到冲突的文件 你当前对文件进行了锁定,不要忘记不使用后要解锁,否则别人无法使用 当前文件夹下的某些文件或文件夹已经被调度从版本控制…

BUUCTF靶场 [reverse]easyre、reverse1、reverse2

工具: DIE:下载:https://download.csdn.net/download/m0_73981089/89334360 IDA:下载:https://hex-rays.com/ida-free/ 新手小白勇闯逆向区!!! [reverse]easyre 首先查壳&#xf…

一刷后日谈

后日谈 1.前言 ​ 今天是一刷结束的日子,回顾一路走过来的路,还是得对自己说声谢谢的; ​ 我是一个向来都很抗拒编程的人,那繁琐的符号让我觉得很是头疼,本科期间数据结构与算法都重修了三次,最后临近毕…

Redis --学习笔记

Redis简介 一个基于内存的key-value结构数据库。Redis 是互联网技术领域使用最为广泛的存储中间件 特点: 基于内存存储,读写性能高 适合存储热点数据(热点商品、资讯、新闻) 企业应用广泛 Redis默认端口号为6379 Redis是用…

Shell之(正则表达式)

目录 一、正则表达式的概括 常用选项 基础正则表达式 查看以xxx为开头 查看以xxx为结尾的文件内容 匹配单个或多个字符 匹配中括号里的内容 对子表达式进行多次或者限定次数的匹配 拓展正则表达式的基本用法 扩展元字符 匹配前面的字符或表达式至少1次&#xff0…

分布式微服务之springboot学习[上]

文章目录 SpringBoot基本介绍官方文档springboot是什么?springboot快速入门需求/图解说明完成步骤快速入门小结 Spring SpringMVC SpringBoot的关系梳理关系如何理解 -约定优于配置 依赖管理和自动配置依赖管理什么是依赖管理修改自动仲裁/默认版本号 starter场景启动器starte…

CSDN智能总结助手

github项目地址: https://github.com/anjude/little-demo/tree/master 获取CSDN的user name和user token 打开csdn,打开控制台 - Application - Cookies,找到domain为blog.csdn.net的cookie,复制user_name和user_token的值 把上…

【计网】广播域和冲突域

一、相关概念 1.各层次设备 2.冲突域 2.1定义 冲突域通俗来讲就是在同一个网络中,两台设备同时传输的话会产生冲突。位于OSI的第一层:物理层 例如在集线器场景下,集线器属于物理层设备,它不具备交换机的功能,当收到节…

PIM Anycast RP(PIM实现)

拓扑图 配置 配置全局使能组播路由 配置OSPF 配置PIM-SM 配置anycast-rp,Loopback 1为Anycast-RP地址,Loopback 0为Anycast-RP本地地址 配置IGMP sysname AR1 # multicast routing-enable # interface GigabitEthernet0/0/0ip address 10.1.12.1 2…

删除重复的电子邮箱-力扣

题目 答案 delete p1 from Person as p1 ,Person as p2 where p1.email p2.email AND p1.id>p2.id; 解析 按照题目删除即可,注意删除的是一条,所以直接是person p1 即可 此处不能用distinct ,其一般与select相互使用。

遍历列表

自学python如何成为大佬(目录):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 遍历列表中的所有元素是常用的一种操作,在遍历的过程中可以完成查询、处理等功能。在生活中,如果想要去商场买一件衣服&#…

C++ RPC ORM 高速解析

支持所有常用编程语 https://capnproto.org/GitHub - capnproto/capnproto: Capn Proto serialization/RPC system - core tools and C library https://capnproto.org/capnproto-c-win32-1.0.2.zip 常用命令: capnp help capnp compile -oc myschema.capn…

Qt代码初识

文章目录 Qt代码初识1. Qt Hello World 程序1.1 使⽤ "按钮" 实现1.1.1 纯代码⽅式实现1.1.2 可视化操作实现 1.2 使⽤ "标签" 实现1.2.1 纯代码⽅式实现1.2.2 可视化操作实现 2. 项⽬⽂件解析2.1 .pro ⽂件解析2.2 widget.h ⽂件解析2.3 main.cpp ⽂件解析…

防火墙技术基础篇:解析防火墙的网络隔离机制

防火墙技术基础篇:解析防火墙的网络隔离机制 网络安全在现代社会中扮演着重要的角色,保护网络系统、用户和数据免受未经授权的访问、破坏和窃取。个人、企业和国家都需要加强网络安全意识,采取有效措施保护自身的网络安全。随着网络攻击手段…

VS2022通过C++网络库Boost.asio搭建一个简单TCP异步服务器和客户端

基本介绍 上一篇博客我们介绍了通过Boost.asio搭建一个TCP同步服务器和客户端,这次我们再通过asio搭建一个异步通信的服务器和客户端系统,由于这是一个简单异步服务器,所以我们的异步特指异步服务器而不是异步客户端,同步服务器在…

SQL靶场搭建

概述 简单介绍一下SQL靶场的搭建,以及在搭建过程中遇到的一些问题。使用该软件搭建靶场相对简单,适合新手小白。当然,也可以在自己的虚拟机下进行搭建,相对来说就较为复杂。本章主要讲解使用Phpstudy进行SQL靶场搭建。 这里我推…