VINS简介与代码结构

2023-05-16

VINS-Mono和VINS-Mobile是香港科技大学沈劭劼团队开源的单目视觉惯导SLAM方案。是基于优化和滑动窗口的VIO,使用IMU预积分构建紧耦合框架。并且具备自动初始化,在线外参标定,重定位,闭环检测,以及全局位姿图优化功能。

方案最大的贡献是构建了效果很好的融合算法,视觉闭环等模块倒是使用了较为常见的算法。

系列博客将结合课题组发表的paper,从代码层面,逐步剖析系统的各个模块,达到对单目VIO整体的把握,帮助自己理解各类算法,并开发出针对应用场景的视觉惯导SLAM系统。最终目标是使用在AR应用中(Android)。

系统pipeline

 

主要分为五部分

1. 传感器数据处理:

  • 单目相机Monocular Camera: Feature detection and Tracking
  • IMU: Pre-integration

2. 初始化:

  • 仅使用视觉构建SfM
  • 将SfM结果和IMU预积分结果对齐

3. 基于滑动窗口的非线性优化:

4. 闭环检测:

5. 4自由度全局位姿图优化:

 

主要依赖的库只有OpenCV, Eigen和Ceres Solver,代码目录如下

 

核心算法都在feature_tracker和vins_estimator包中。

按照REDEME步骤跑EuRoC/MH_05_difficult.bag录好的数据结果如下:

使用rqt_graph得到系统的node和topic关系:

rosbag将记录好的imu数据和单目相机获取的图像数据分别发布到/imu0和/cam0/image_raw话题;/feature_tracker节点通过订阅/cam0/image_raw话题获取图像数据,/vins_estimator节点通过订阅/imu0话题获取imu数据,同时/feature_tracker节点将提取出的图像特征发布到/feature_tracker/feature话题,由/vins_estimator订阅获取。

因此,/feature_tracker节点负责视觉提取和跟踪,/vins_estimator则是融合系统的主要部分。

为了方便看代码,整理了一下各个部分架构图(更新中):

processImage():

系统入口是feature_tracker_node.cpp文件中的main函数

1. 首先创建feature_tracker节点,从配置文件中读取信息(parameters.cpp),包括:

  • ROS中发布订阅的话题名称;
  • 图像尺寸;
  • 特征跟踪参数;
  • 是否需要加上鱼眼mask来去除边缘噪点;
%YAML:1.0

#common parameters
imu_topic: "/imu0"
image_topic: "/cam0/image_raw"

#camera calibration 
model_type: PINHOLE
camera_name: camera
image_width: 752
image_height: 480
distortion_parameters:
   k1: -2.917e-01
   k2: 8.228e-02
   p1: 5.333e-05
   p2: -1.578e-04
projection_parameters:
   fx: 4.616e+02
   fy: 4.603e+02
   cx: 3.630e+02
   cy: 2.481e+02

# Extrinsic parameter between IMU and Camera.
estimate_extrinsic: 1   # 0  Have an accurate extrinsic parameters. We will trust the following imu^R_cam, imu^T_cam, don't change it.
                        # 1  Have an initial guess about extrinsic parameters. We will optimize around your initial guess.
                        # 2  Don't know anything about extrinsic parameters. You don't need to give R,T. We will try to calibrate it. Do some rotation movement at beginning. 
ex_calib_result_path: "/config/euroc/ex_calib_result.yaml"  # If you choose 1 or 2, the extrinsic calibration result will be written vins_folder_path + ex_calib_result_path.                        
#If you choose 0 or 1, you should write down the following matrix.
#Rotation from camera frame to imu frame, imu^R_cam
extrinsicRotation: !!opencv-matrix
   rows: 3
   cols: 3
   dt: d
   data: [0, -1, 0, 
           1, 0, 0, 
           0, 0, 1]
#Translation from camera frame to imu frame, imu^T_cam
extrinsicTranslation: !!opencv-matrix
   rows: 3
   cols: 1
   dt: d
   data: [-0.02,-0.06, 0.01]

#feature traker paprameters
max_cnt: 150            # max feature number in feature tracking
min_dist: 30            # min distance between two features 
freq: 10                # frequence (Hz) of publish tracking result. At least 10Hz for good estimation. If set 0, the frequence will be same as raw image 
F_threshold: 1.0        # ransac threshold (pixel)
show_track: 1           # publish tracking image as topic
equalize: 1             # if image is too dark or light, trun on equalize to find enough features
fisheye: 0              # if using fisheye, trun on it. A circle mask will be loaded to remove edge noisy points

#optimization parameters
max_solver_time: 0.04  # max solver itration time (ms), to guarantee real time
max_num_iterations: 8   # max solver itrations, to guarantee real time
keyframe_parallax: 10.0 # keyframe selection threshold (pixel)

#imu parameters       The more accurate parameters you provide, the better performance
acc_n: 0.2          # accelerometer measurement noise standard deviation. #0.2
gyr_n: 0.02         # gyroscope measurement noise standard deviation.     #0.05
acc_w: 0.0002         # accelerometer bias random work noise standard deviation.  #0.02
gyr_w: 2.0e-5       # gyroscope bias random work noise standard deviation.     #4.0e-5
g_norm: 9.81007     # gravity magnitude


#loop closure parameters
loop_closure: 1   #if you want to use loop closure to minimize the drift, set loop_closure true and give your brief pattern file path and vocabulary file path accordingly;
                     #also give the camera calibration file same as feature_tracker node
pattern_file: "/support_files/brief_pattern.yml"
voc_file: "/support_files/brief_k10L6.bin"
min_loop_num: 25

该config.yaml文件中的其他参数在vins_estimator_node中被读取,属于融合算法的参数。

  • 优化参数(最大求解时间以保证实时性,不卡顿;最大迭代次数,避免冗余计算;视差阈值,用于选取sliding window中的关键帧);
  • imu参数,包括加速度计陀螺仪的测量噪声标准差、零偏随机游走噪声标准差,重力值(imu放火星上需要改变);
  • imu和camera之间的外参R,t;可选(0)已知精确的外参,运行中无需改变,(1)已知外参初值,运行中优化,(2)什么都不知道,在线初始化中标定
  • 闭环参数,包括brief描述子的pattern文件(前端视觉使用光流跟踪,不需要计算描述子),针对场景训练好的DBow二进制字典文件;

2. 监听IMAGE_TOPIC, 有图像信息发布到IMAGE_TOPIC上时,执行回调函数:

ros::Subscriber sub_img = n.subscribe(IMAGE_TOPIC, 100, img_callback);

 

 

3. img_callback()

前端视觉的算法基本在这个回调函数中,步骤为:

  1. 频率控制,保证每秒钟处理的image不多于FREQ;

  2. 对于单目:

    1). readImage;

    2). showUndistortion(可选);

    3). 将特征点矫正(相机模型camodocal)后归一化平面的3D点(此时没有尺度信息,3D点p.z=1),像素2D点,以及特征的id,封装成ros的sensor_msgs::PointCloud消息类型; 

  3. 将处理完的图像信息用PointCloud和Image的消息类型,发布到"feature"和"feature_img"的topic:

pub_img = n.advertise<sensor_msgs::PointCloud>("feature", 1000);
pub_match = n.advertise<sensor_msgs::Image>("feature_img",1000);

 

4. 包含的视觉算法:

1. CLAHE(Contrast Limited Adaptive Histogram Equalization)

cv::Ptr<cv::CLAHE> clahe = cv::createCLAHE(3.0, cv::Size(8, 8));

2. Optical Flow(光流追踪)

cv::calcOpticalFlowPyrLK(cur_img, forw_img, cur_pts, forw_pts, status, err, cv::Size(21, 21), 3);

3. 根据匹配点计算Fundamental Matrix, 然后用Ransac剔除不符合Fundamental Matrix的外点

cv::findFundamentalMat(un_prev_pts, un_forw_pts, cv::FM_RANSAC, F_THRESHOLD, 0.99, status);

4. 特征点检测:goodFeaturesToTrack, 使用Shi-Tomasi的改进版Harris corner

cv::goodFeaturesToTrack(forw_img, n_pts, MAX_CNT - forw_pts.size(), 0.1, MIN_DIST, mask);

 特征点之间保证了最小距离30个像素,跟踪成功的特征点需要经过rotation-compensated旋转补偿的视差计算,视差在30个像素以上的特征点才会去参与三角化和后续的优化,保证了所有的特征点质量都是比较高的,同时降低了计算量。

 

 

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

VINS简介与代码结构 的相关文章

  • makefile:make -C M=参数的使用

    Makefile为 xff0c PWD span class token operator 61 span span class token punctuation span shell pwd span class token punct
  • BW笔记(2011-10-24更新至No.237)

    1 同一个变量名的UID可能有多个 xff0c 记得注意 2 在查找时要注意技术名称还是名称 xff0c 因为查询时会在两个中进行 xff0c 模糊查询时要细心 xff0c FV与V都可以查到 3 复制的时候注意长度 xff0c 过长的会不
  • rpmsg 内核开发 用户层接口

    地址 xff1a https blog csdn net thisway diy article details 129195479 韦东山 Tina Linux E907开发指南 AMP 环境搭建 7 1 rpmsg 内核开发 7 2 r
  • __raw_writel, writel_relaxed 和 writel的区别

    因为对别的平台不了解 xff0c 下面仅谈它们在ARM上的区别 raw writel xff1a 因为有volatile关键字 xff0c 所以编译器不会打乱多个 raw writel的执行顺序 对于ARM而言 xff0c 当多个写以代码的
  • WFE和WFI的区别

    1 概念 xff1a WFI Wait for interrupt 和WFE Wait for event 是两个让ARM核进入low power standby模式的指令 xff0c 由ARM architecture定义 xff0c 由
  • Ubuntu16.04安装中文输入法

    转载地址 xff1a http blog csdn net suxiang198 article details 52040283 Ubuntu16 04安装完后 xff0c 和12 04以及14 04都不一样 xff0c 并没有中文输入功
  • QT linux安装

    转载地址 xff1a http www cnblogs com tangkaixuan p 6504102 html 文章来自https lug ustc edu cn sites qtguide 1 4 Qt在Linux下安装 Qt在Li
  • Linux CAN编程详解

    转载地址 xff1a http velep com archives 1181 html Linux CAN编程详解 是一篇百度文库上的文档 xff0c 主要描述了以下内容 xff1a can总线介绍及其帧类型 xff1b Linux 系统
  • buildroot学习(十)——at91sam9g45软件平台更新

    转载地址 xff1a https blog csdn net srf1986 article details 52474697 xff08 xff11 xff13 xff16 xff09 spice protocol In computin
  • killall 、kill 、pkill 命令详解

    转载地址 xff1a https www cnblogs com rsky p 4886043 html killall 命令 Linux系统中的killall命令用于杀死指定名字的进程 xff08 kill processes by na
  • PCIe扫盲——PCIe简介

    转载地址 xff1a http blog chinaaet com justlxy p 5100053066 PCI Express是继ISA和PCI总线之后的第三代I O总线 xff0c 即3GIO 由Intel在2001年的IDF上提出
  • Adaptive Autosar通讯层:ARA::COM中的Instance Identifiers

    一般概念 实例标识符 在收发两端都是要用的 是很核心的概念 proxy端用来搜索服务 xff0c skeleton端用来创建服务实例 站在API的角度来看 xff0c 这样的识别符是和特定的技术绑定的 所以 xff0c 标识符的结构和内容都
  • BW:数据源抽取机制(这篇是以前的笔记,写得很差,有不少错的地方,留着给自己看)

    题记 xff1a 忽然想到这么个问题 xff0c 后勤数据源和非后勤数据初始化有何区别 xff0c 然后进行周边的拓展 xff0c 所以就形成了下文 大部分知识源于 TBW350 和 SAP SDN 对数据源抽取机制的深入探讨 一 什么数据
  • 【ARA com API】ara::core::Optional

    文章目录 ara core Optional 是什么标准中的代码示例 ara core Optional 是什么 实际上就是std optional 但是当前的AP标准没有支持到那么新版本的C 43 43 标准 xff08 我没有具体研究是
  • ROS学习总结(1)--入门、学习路线

    最近由于项目需要 xff0c 我被分配到机器人驱动模块 xff0c 由此开始研究学习ROS xff0c 在此记录学习ROS的方法 过程 经历与应用 本节记录ROS学习路线 ROS xff08 robot operation system x
  • 使用uart数据起飞

    使用uart得到的位置信息进行起飞 在得到了位置信息的前提下 xff0c 我们开始进行模拟起飞 xff0c 即使用usb供电 xff0c 人工控制其高度 xff0c 在上位机查看油门大小 xff0c 电机的pwm输出 commander c
  • AirSim(五)---理解篇: Airsim世界坐标系、NED坐标系、机体坐标系以及控制相关API接口函数

    目录 1 坐标系 coordinate system 1 AirSim API的坐标系 xff1a NED 坐标系 with SI unit 2 Unreal Engine的坐标系 xff08 3 xff09 AirSim全局坐标系 61
  • 深度学习中常用的优化算法(SGD, Nesterov,Adagrad,RMSProp,Adam)总结

    深度学习中常用的优化算法 SGD Nesterov Adagrad RMSProp Adam 总结 1 引言 在深度学习中我们定义了损失函数以后 xff0c 会采取各种各样的方法来降低损失函数的数值 xff0c 从而使模型参数不断的逼近于真
  • 双系统安装ubuntu 22.04 LTS(一步到位)

    作为一个拥有两次都是一次成功安装好双系统的经验的人 xff0c 我觉得我可以借这个文章仔细讲述一下 xff0c 让大家都可以双系统安装都是一次成功 为什么有着两次安装经验呢 xff0c 第一次安装完成后由于电脑的内存不太够了 xff0c 然
  • UART、RS232、RS485 串行通信详解

    一 UART通信 UART是Universal Asynchronous Receiver Transmitter的缩写 xff0c 意即通用异步串行通信接口 xff0c 是最常用的通信技术之一 xff0c 广泛用于设备与电脑之间 设备与设

随机推荐

  • I2C总线基础知识及操作详解

    I2C总线是一种简单的双向两线式同步串行总线 xff0c 最初由Philips公司开发 xff0c 后又经过几次发展和完善 xff0c 目前已被业界厂商广泛采用 xff0c 成为最常用的板级通信总线之一 xff0c 大量应用于处理器与外围设
  • 对AI的理解及应用的思考

    1 概述 1 1 常用术语 1 2 AI学习方式及地位 序号 学习方法 地位 1 强化学习 Reinforcement Learning 犹如蛋糕上的一颗樱桃 2 监督学习 Supervised Learning 犹如蛋糕外的一层糖霜 3
  • (65)如何根据句柄从二级、三级结构句柄表中找到内核对象

    一 回顾 上一篇博客介绍了如何遍历一级句柄表 一级句柄表非常简单 xff0c 就是一个4KB页 xff0c 最多存储512个句柄表项 如果句柄数量在 512 1024 512 之间 xff0c 句柄表就是二级结构 xff1b 如果句柄数量大
  • BW:BW与第三方BI接口设计与实现:APD、Open Hub、RFM

    最近公司新上了国内某 CRM系统 xff0c SAP的 CRM也光荣下线了 但是紧接着就出现了一些需求 xff0c CRM自带一款小型 BI xff0c 需要一些 SD的数据 xff0c 但是把 R3的数据给他们进行计算的话 xff0c 不
  • Ubuntu下查看CPU、内存和硬盘详细信息的几个命令

    转载自https www cnblogs com shixiangwan p 7066085 html CPU xff1a 型号 xff1a grep 34 model name 34 proc cpuinfo awk F 39 39 39
  • python 小点心---execvp

    execvp会用即将运行的进程的内存替换掉调用进程的内存 xff0c 更进一步讲 xff0c 就是把当前进程的机器指令都清空 xff0c 然后载入被execvp运行起来的进程的机器指令 coding 61 utf 8 import os i
  • jenkins + gitlab + docker + harbor 实现自动触发更新

    当使用微服务方案后 xff0c 面临在大量的项目构建和部署工作 xff0c 借助于jenkins的持续集成 xff0c 可以快速把应用打包成docker镜像 xff0c 实现自动部署 xff0c 加快项目的迭代 一 环境部署 系统IP主机名
  • C++ -- STL文件解析

    1 STL文件格式 STL文件是一种用许多空间小三角形面片逼近三维实体表面的3D模型 STL模型给出了组成三角形法向量的3个分量 用于确定三角面片的正反方向 及三角形的3个顶点坐标 一个完整的STL文件记录了组成实体模型的所有三角形面片的法
  • Ubuntu 查看CPU信息

    Ubuntu 查看cpu个数及核心数 总核数 span class token operator 61 span 物理CPU个数 X 每颗物理CPU的核数 总逻辑CPU数 span class token operator 61 span
  • 韩顺平老师Java基础听课笔记(一)

    Java运行机制 xff1a 1 javac 编译 java文件 生成 class文件 javac Hello java 2 java运行编译后的 class文件 xff08 java Hello xff09 编译后可在Windows Li
  • 韩顺平老师 Java基础听课笔记(二)

    变量 xff1a xff08 先声明后使用 xff09 定义变量 xff1a 1 int a 61 1 2 int b b 61 2 变量在同一个作用域 xff08 同一个方法 xff09 内不能重名 变量三要素 xff1a 变量名 变量值
  • VScode上传到git仓库详细教程

    文章有点啰嗦 坚持看完 xff01 xff01 xff01 首先下载git https git scm com downloads 下载成功之后 xff0c 一直点击next直到安装成功 xff0c 在桌面上点击鼠标右键出现 点击Git B
  • [视觉测距]单目视觉定位测距的两种方式(1)

    单目定位和双目定位的选择 xff0c 我觉得主要还是成本和时间的考虑 之前也尝试过双目定位 xff0c 感觉要更精准些 xff0c 但双目测距需要对两幅图像进行图像变换和极线匹配 xff0c 稍微耗时了一些 这几天尝试了一下单摄像头进行测距
  • [学习SLAM]Quaternion 插值/ 用四元数插值来对齐IMU和图像帧

    小白 xff1a 师兄 xff0c 好久没见到你了啊 xff0c 我最近在看IMU xff08 Inertial Measurement Unit xff0c 惯性导航单元 xff09 相关的东西 xff0c 正好有问题求助啊 师兄 xff
  • 【学习SLAM】vins笔记

    VINS ROS source catkin ws devel setup bash 3 1 1 Open three terminals launch the vins estimator rviz and play the bag fi
  • CSDN 还是不能改头像!!!

    都好几个月了 xff0c 技术问题么 xff0c 还是爬梯开大会 xff0c 连这个都不让改了 真不爽
  • 【计算机视觉】opencv姿态解算6 理论算法调研 PNP问题 5种算法

    关于PnP xff08 pespective n point xff09 的一些方法 最小PnP问题 P3P问题中假设没有噪声 xff0c 使用几何约束 xff0c 可以解得相机的位姿 不具有唯一解 P4P问题中分为线性方法和基于P3P的方
  • 【计算机视觉】 相机姿态估计之标记检测-相机标定ArUco和ChArUco 5

    相机标定ArUco和ChArUco 原文来源 opencv http docs opencv org master da d13 tutorial aruco calibration html ArUco模块也可以用来相机标定 相机标定是获
  • 【泡泡机器人公开课】公开课链接 机器人俱乐部

    1 工业相机选型及介绍 刘富强 链接 https pan baidu com s 1nuGw4Vv 密码 tjag 2 深度学习及应用 颜沁睿 链接 https pan baidu com s 1c31ZcE 密码 r42j 3 SVO a
  • VINS简介与代码结构

    VINS Mono和VINS Mobile是香港科技大学沈劭劼团队开源的单目视觉惯导SLAM方案 是基于优化和滑动窗口的VIO xff0c 使用IMU预积分构建紧耦合框架 并且具备自动初始化 xff0c 在线外参标定 xff0c 重定位 x