【视觉SLAM入门】6.1. (基于直接法的视觉里程计)LK光流法,代码解读, 直接法,特征点法对比,稀疏,半稠密,稠密地图

news2024/11/24 3:11:41

"刺卵掷地,逐蝇弃笔"

  • 0. 数据集
  • 1. 光流法(Optical Flow)
    • 1.1. 光流
    • 1.2. LK光流法
    • 1.3 关键代码:
    • 1.4 特点
  • 2. 直接法(Direct Methods)
    • 2.1 分类比较
    • 2.2 优缺点

前置事项: 特征点耗时,丢弃有用信息,特征缺失(长直走廊)失效
对此,有直接法。

0. 数据集

该项目用的是fr1_desk数据集,RGBD的,下载后的全称是rgbd_dataset_freiburg1_desk.tgz。TUM官网数据集下载.
下载后,将rgb,depth文件夹和rgb.txt,depth.txt,groudtruth.txt拷贝到ch8的data/下(覆盖),然后执行脚本

python associate.py rgb.txt depth.txt > associate.txt

1. 光流法(Optical Flow)

1.1. 光流

在这里插入图片描述

直接法前身:光流。上图中 I I I 表示灰度, t t t 表示时间

1.2. LK光流法

  • 描述像素随着时间,在图像之间运动的方法。计算全部像素称为稠密光流,部分像素运动称为稀疏光流,稀疏光流代表作 Lucas-Kanade
  • 仍用特征点,关键点不变,但是用光流取代描述子匹配的环节。
  • 灰度不变假设:同一个空间点的像素灰度值,在各个图像中是固定不变的。

在该假设下,某像素运动到t时刻时灰度不变,则:
I ( x + d x , y + d y , t + d t ) = 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    ⇓ 由于灰度不变    ∂ I ∂ x d x + ∂ I ∂ y d y + ∂ I ∂ t d t = 0    ⇓ 两边除以 d t    ∂ I ∂ x d x d t + ∂ I ∂ y d y d t = − ∂ I ∂ t I(x+dx, y+dy, t+dt) = I(x, y,t) \\\;\\\Downarrow 泰勒展开,保留一阶\\\;\\ I(x+dx, y+dy, t+dt) \approx I(x,y,t)+\frac{\partial I}{\partial x}dx + \frac{\partial I}{\partial y}dy + \frac{\partial I}{\partial t}dt \\\;\\\Downarrow 由于灰度不变\\\;\\ \frac{\partial I}{\partial x}dx + \frac{\partial I}{\partial y}dy + \frac{\partial I}{\partial t}dt=0 \\\;\\\Downarrow 两边除以dt\\\;\\ \frac{\partial I}{\partial x} \frac{dx}{dt} + \frac{\partial I}{\partial y}\frac{dy}{dt} = - \frac{\partial I}{\partial t} I(x+dx,y+dy,t+dt)=I(x,y,t)泰勒展开,保留一阶I(x+dx,y+dy,t+dt)I(x,y,t)+xIdx+yIdy+tIdt由于灰度不变xIdx+yIdy+tIdt=0两边除以dtxIdtdx+yIdtdy=tI
为了简化,做一些记法:

  • d x d t = u \frac{dx}{dt}=u dtdx=u(实则是像素在x轴上的运动速度),
  • d y d t = v \frac{dy}{dt}=v dtdy=v(实则是像素在y轴上的运动速度),
  • ∂ I ∂ x = I x \frac{\partial I}{\partial x}=I_x xI=Ix(实则是图像在该点处x方向梯度),
  • ∂ I ∂ y = I y \frac{\partial I}{\partial y}=I_y yI=Iy(实则是图像在该点处y方向梯度),
  • ∂ I ∂ t = I t \frac{\partial I}{\partial t}=I_t tI=It(实则是图像灰度对时间的变化量)

求解如下矩阵:
[ I x I y ] [ u v ] = − I t \begin{bmatrix} I_x&I_y \end{bmatrix}\begin{bmatrix} u\\v \end{bmatrix} = -I_t [IxIy][uv]=It
在LK光流中,为了求解u,v,需要引入更多约束,假设一个窗口内的像素具有相同运动,即多个点的 u , v u,v u,v 相同,则对于一个 w ⋅ w w\cdot w ww的窗口,有 w 2 w^2 w2 { I x , I y , I t } \{I_x,I_y,I_t\} {Ix,Iy,It}点对,则$有 w 2 w^2 w2 个方程可以用来求解 u , v u,v u,v。超定方程,求最小二乘解,即可得到 u , v u,v u,v

得到了 u , v u,v u,v即图像运动速度后,当给定 t t t 时,就可以计算(估计)某块像素在若干个图像中出现的位置。

在SLAM中,LK光流常常被用来跟踪角点的运动。

1.3 关键代码:

cv::calcOpticalFlowPyrLK( last_color, color, prev_keypoints, next_keypoints, status, error );

OpenCV 库中的一个函数,用于计算光流(optical flow)。
函数的参数解释如下:

  • last_color:    \qquad\qquad\; 输入参数,表示上一帧的彩色图像。
  • color: \qquad\qquad\qquad 输入参数,表示当前帧的彩色图像。
  • prev_keypoints:      \qquad\;\; 输入参数,表示上一帧的关键点(keypoints)位置。
  • next_keypoints:      \qquad\;\; 输出参数,表示当前帧的关键点位置。(主要)
  • status: \qquad\qquad\qquad 输出参数,表示每个关键点的跟踪状态。如果跟踪成功,则状态为 true;否则为 false。跟踪失败的关键点后续可以删除
  • error: \qquad\qquad\qquad 输出参数,表示每个关键点在运动模型下的估计误差。

该函数使用 Lucas-Kanade (LK) 方法计算光流。在给定上一帧的关键点位置和当前帧的图像,函数尝试在当前帧中估计新的关键点位置。函数返回每个关键点的跟踪状态和估计误差。如果跟踪成功,则 next_keypoints 中包含新的关键点位置;否则,这些位置是未定义的。

总的来说效果如下,抽取两张:

                     \;\;\;\;\;\;\;\;\;\;
\qquad\qquad\qquad\qquad\quad t0时刻提取的关键点 \qquad\qquad\qquad\qquad\quad\qquad\qquad\qquad\qquad t0+t时刻提取的关键点

1.4 特点

  • 匹配描述子方法相机运动较大时仍能成功,而光流法要求相机运动微小,鲁棒性差。
  • 光流法不太会误匹配,只会跟丢特征点,优点。

2. 直接法(Direct Methods)

和光流有一定相似性,是基于优化的方法。
仍然基于灰度不变假设: 假设一个空间点在各个视角下,成像的灰度是不变的。
有一个初始位姿(必定不够好),和上一讲一样,但此时最小化的不是重投影误差,而是光度误差 (Photometric Error),也就是P的两个像的亮度误差:
e = I 1 ( p 1 ) − I 2 ( p 2 ) e = I_1(p_1)-I_2(p_2) e=I1(p1)I2(p2)
其余的推导,李群李代数泰勒展开等同优化最小化重投影误差求解相机位姿那一节,最终仍使用G2O求解。

  • G2O没有计算光度误差的边,我们需要自定义一种新的边。

2.1 分类比较

  1. 稀疏直接法: 选点来自稀疏关键点,如L-K光流一样,假设窗口灰度不变,只用数百个像素,不必计算描述子。速度最快,但只能计算稀疏的重构;
  2. 半稠密直接法(Semi-Dense): 选点只使用带有梯度的像素点,对计算运动增量没有贡献的点不用。可以重构一个半稠密结构。
  3. 稠密直接法: 计算所有像素(几十万~几百万个),多数需要GPU加速,但是梯度不明显的点,在运动估计中不会有太大贡献,重构时也难以估计其位置。
  • 稀疏方法可以快速求解相机位姿,稠密方法可以建立完整地图,稀疏直接法可以做到非常快速的效果。

上述只分析了单个像素的差异,周围可能有很多像素和它的亮度差不多,所以我们有时候又使用小的图像块(patch),并且使用更复杂的度量方式,比如归一化相关性。(NCC)

2.2 优缺点

  1. 省时;
  2. 只要有像素梯度即可,无需特征点。图像有渐变,无特征点仍然可用。
  3. 可以构建半稠密地图和稠密地图。

缺点:
4. 非凸性----完全依靠梯度搜索;
5. 单个像素没有区分度;
6. 灰度不变性假设一般不成立:相机曝光等。

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

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

相关文章

vite 配置自动补全文件的后缀名

vite 不建议自动补全,文件的后缀名的 const Home ()>import("/views/Home.vue");文件是必须要加上 .vue 的后缀名的 如果 想要像 webpack 一样的不用写, 可以在vite.config.js中配置如下就可以了

【bug记录】RuntimeError: CUDA error: device-side assert triggered

RuntimeError: CUDA error: device-side assert triggered 我个人使用pytorch lightning时,报错RuntimeError: CUDA error: device-side assert triggered 我个人是因为分类类别数目对不上,但是在gpu上运行是不会提示错误的 解决方案:建议…

kubesphere中部署grafana实现dashboard以PDF方式导出

1,部署grafana-image-renderer 2,部署grafana GF_RENDERING_SERVER_URL http://ip:30323/render #grafana-image-renderer地址 GF_RENDERING_CALLBACK_URL http://ip:32403/ #grafana地址 GF_LOG_FILTERS rend…

【ES】笔记-Promise基本使用

笔记-基本使用 一、初始Promise1. 抽象表达:2. 具体表达:为什么要用 Promise?promise的基本流程 二、fs读取文件三、AJAX请求四、Promise封装fs模块五、util.promisify方法六、Promise封装AJAX操作 一、初始Promise 1. 抽象表达: 1. Promise 是一门新的技术(ES6 规范) 2. Pr…

关于单例模式

单例模式的目的: 单例模式的目的和其他的设计模式的目的都是一样的,都是为了降低对象之间的耦合性,增加代码的可复用性,可维护性和可扩展性。 单例模式: 单例模式是一种常用的设计模式,用简单的言语说&am…

uview ui 1.x ActonSheet项太多,设置滚动(亲测有效)

问题:ActionSheet滚动不了。 使用uview ui :u-action-sheet, 但是item太多,超出屏幕了, 查了一下文档,并没有设置滚动的地方。 官方文档:ActionSheet 操作菜单 | uView - 多平台快速开发的UI框架 - uni-a…

oracle 基础运用2

首先在电脑上安装PLSQL developer,这个是oracle图形化连接工具,然后安装win64_11gR2_client,这个是orace客户端,安装完成后可以在cmd命令行输入sqlplus命令进行验证,如图表示安装成功。 作为sys的连接应该是SySDBA或Sy…

AD中如何给过孔添加盖油

AD中如何给过孔添加盖油 画PCB时通常我们会放一些过孔,起到上下层信号转接或者地过孔的作用,当这些过孔较大较密时如果不做盖油处理,就会影响电气性能而且很不美观。如下图: 如果要盖油,点击对应的过孔,将…

大数据项目实战(完整的搭建大数据集群环境)

一,搭建大数据集群环境 (由于内容过多分为了4个博客,后面有链接分享,也可去我的主页查看) 1.1安装准备 1.1.1虚拟机安装与克隆 1.虚拟机的安装和设置以及启动虚拟机并安装操作系统 安装一台虚拟机主机名为&#x…

mysql通过.frm和.ibd 文件恢复数据库

问题背景:由于强制在服务关闭mysql导致部分数据表以及数据丢失 如下图只有.frm .ibd的文件为我的问题文件 查找不到表结构和表数据目录D:XXXX\mysql-5.7.24-winx64\data\mydata 从frm文件中恢复表结构 先把原来的数据备份一次 避免过程中出错 先备份之前数据的.fr…

大数据处理平台的架构演进:从批处理到实时流处理

文章目录 批处理架构:实时流处理架构:混合架构: 🎈个人主页:程序员 小侯 🎐CSDN新晋作者 🎉欢迎 👍点赞✍评论⭐收藏 ✨收录专栏:大数据系列 ✨文章内容:大数…

Node与Express后端架构:高性能的Web应用服务

在现代Web应用开发中,后端架构的性能和可扩展性至关重要。Node.js作为一个基于事件驱动、非阻塞I/O的平台,以及Express作为一个流行的Node.js框架,共同构建了高性能的Web应用服务。 在本文中,我们将深入探讨Node与Express后端架构…

生命盈品牌发布会在杭举行

​  生命盈品牌将举办"资本之路赚钱之道生命盈"活动,旨在探讨资本与实体经济的结合方式以及后疫情时代实体行业的发展方向。活动将于2023年8月27日下午1点在杭州滨江开元名都一楼举行。 来自全国各地的企业家,品牌创始人和媒体朋友们参加了该…

【ES6】—类与继承

一、 定义类 class People {constructor (name, age) {this.name namethis.age age}showName () {console.log(this.name)} } let p1 new People(xiaoxiao, 30) console.log(p1) // People {name: xiaoxiao, age: 30}小节: 使用class关键字声明类使用construc…

【校招VIP】前端算法考察之排序

考点介绍: 不同的场景中,不同的排序算法执行效率不同。 稳定:冒泡、插入、归并 不稳定:选择、快速、堆排序、希尔排序 『前端算法考察之排序』相关题目及解析内容可点击文章末尾链接查看! 一、考点题目 1、使用js实…

智慧工厂解决方案:推动制造业转型升级的新引擎

随着信息技术的迅猛发展和制造业竞争的加剧,智慧工厂成为了推动制造业转型升级的重要引擎。智慧工厂解决方案通过整合物联网、人工智能、大数据分析等先进技术,实现生产过程的智能化、自动化和高效化,为企业提供了更加灵活、智能的生产模式和…

网页接口导入postman进行接口请求

postman版本:v10.17.4 一、拷贝接口信息 网页打开开发者工具-networkk,在网页上请求一次接口,鼠标指在接口上,点击鼠标右键-copy-copy as cURL(bash) 二、导入postman 打开postman,点击import-Raw text,…

Java简便集成工作流(activiti),通用审批系统

前言 activiti工作流引擎项目,企业erp、oa、hr、crm等企事业办公系统轻松落地,请假审批demo从流程绘制到审批结束实例。 一、项目形式 springbootvueactiviti集成了activiti在线编辑器,流行的前后端分离部署开发模式,快速开发平…

Nelson-Siegel-Svensson in Python;使用纳尔逊-西格尔-斯文森估计即期汇率曲线(1994)

一、说明 Nelson-Siegel-Svensson (1994) 模型通过添加 1987 个额外的曲线估计参数来修改 Nelson-Siegel (2) 模型。虚拟任何收益率曲线形状都可以使用这两种模型进行插值,这两种模型在世界各地的银行中广泛使用。 图1…

oracle19c-静默安装(centos7)

目录 一.环境准备1.关闭防火墙2.关闭SELINUX3.配置本地yum源4.安装ORACLE先决条件的软件包5.修改LINUX的内核文件6.添加下列参数到/etc/security/limits.conf7.添加下列条目到/etc/pam.d/login8.环境变量中添加下列语句9.创建文件目录和相应的用户10.配置oracle用户的环境变量1…