eigen

从零开始一起学习SLAM | 掌握g2o顶点编程套路

妖精的绣舞 提交于 2020-05-07 21:59:13
<p style="text-align:center"> 点“计算机视觉life”关注,置顶更快接收消息! </p> 小白:师兄,上一次将的g2o框架《 从零开始一起学习SLAM | 理解图优化,一步步带你看懂g2o代码 》真的很清晰,我现在再去看g2o的那些优化的部分,基本都能看懂了呢! 师兄:那太好啦,以后多练习练习,加深理解 小白:嗯,我开始编程时,发现g2o的顶点和边的定义也非常复杂,光看十四讲里面,就有好几种不同的定义,完全懵圈状态。。。师兄,能否帮我捋捋思路啊 师兄:嗯,你说的没错,入门的时候确实感觉很乱,我最初也是花了些时间才搞懂的,下面分享一下。 g2o的顶点(Vertex) 从哪里来的? 师兄:在《g2o: A general Framework for (Hyper) Graph Optimization》这篇文档里,我们找到那张经典的类结构图。也就是上次讲框架用到的那张结构图。其中涉及到顶点 (vertex) 的就是下面 加了序号的3个东东了。 小白:记得呢,这个图很关键,帮助我理清了很多思路,原来来自这篇文章啊 师兄:对,下面我们一步步来看吧。先来看看上图中和vertex有关的第①个类: HyperGraph::Vertex,在g2o的GitHub上( https://github.com/RainerKuemmerle/g2o ),它在这个路径 g2o

Ethzasl MSF源码阅读(2):百川汇海

笑着哭i 提交于 2020-05-05 23:28:47
这里有个感觉,就是百川汇海。即IMU数据和相机的消息数据都汇集到msf_core进行处理。接上一篇, 1. 查看IMUHandler_ROS::IMUCallback和IMUHandler_ROS::StateCallback回调函数。 MUHandler_ROS::IMUCallback,传入的消息sensor_msgs::ImuConstPtr。 1 void IMUCallback( const sensor_msgs::ImuConstPtr & msg) 2 { 3 static int lastseq = constants::INVALID_SEQUENCE; 4 if (static_cast< int >(msg->header.seq) != lastseq + 1 5 && lastseq != constants::INVALID_SEQUENCE) { 6 MSF_WARN_STREAM( 7 " msf_core: imu message drop curr seq: " << msg-> header.seq 8 << " expected: " << lastseq + 1 ); 9 } 10 lastseq = msg-> header.seq; 11 12 msf_core::Vector3 linacc; 13 linacc << msg-

Ethzasl MSF源码阅读(1):程序入口和主题订阅

折月煮酒 提交于 2020-05-05 23:23:03
关于IMU融合知乎上的一篇问答: 有哪些开源项目是关于单目+imu做slam的? Ethz的Stephen Weiss的工作,是一个IMU松耦合的方法。 1.程序入口:ethzasl_msf\msf_updates\src\pose_msf\main.cpp 1 #include " pose_sensormanager.h " 2 3 int main( int argc, char ** argv) 4 { 5 ros::init(argc, argv, " msf_pose_sensor " ); 6 msf_pose_sensor::PoseSensorManager manager; 7 ros::spin(); 8 return 0 ; 9 } PoseSensorManager类,查看构造函数。PoseSensorManager继承自msf_core::MSF_SensorManagerROS,继承自msf_core::MSF_SensorManager<EKFState_T> 1 PoseSensorManager(ros::NodeHandle pnh = ros::NodeHandle( " ~/pose_sensor " )) 2 { 3 bool distortmeas = false ; // < Distort the pose measurements

高博SLAM基础课第四讲——相机模型

喜你入骨 提交于 2020-05-05 15:00:14
(1)本节内容 1、针孔相机模型 2、误差来源——畸变 3、双目相机模型 (2)需要的基础知识 单独成章节,不需要太多基础 (3)开发环境 编译平台:ubuntu16.04, 编译软件:IDE:Clion 编译器:Cmake 语言标准:C++11 (4)学习内容 1、针孔相机模型 小孔模型能够把三维世界中的物体投影到一个二维成像平面。同理,可以用这个简单的模型来解释相机的成像模型。 对这个简单的针孔模型进行几何建模。设O−x−y−zO−x−y−z为相机坐标系,习惯上让z轴指向相机前方,x向右,y向下。O和为摄像机的光心,也是针孔模型中的针孔。现实世界的空间点P,经过小孔O投影之后,落在物理成像平面O′−x′−y′−z′上,成像点为P′。设P的坐标为[X,Y,Z]T,P′为[X′,Y′,Z′]T,并且设物理成像平面到小孔的距离为ff焦距)。那么,根据三角形相似关系,有: 其中负号表示成的像是倒立的。为了简化模型,可以将成像平面对称到相机前方,和三维空间点一起放在摄像机坐标系的同一侧,如图4-2中间的样子所示。这样可以把公式中的负号去掉,使式子更加简洁: 整理得: 上式描述了点P和它的像之间的空间关系。不过,在相机中,最终获得的是一个个的像素,这需要在成像平面上对像进行采样和量化。为了描述传感器将感受到的光线转换成图像像素的过程,在物理成像平面上固定一个像素平面o−u−v

第4章 探索性数据分析(多因子与复合分析)

被刻印的时光 ゝ 提交于 2020-05-02 10:28:40
4.1、多因子 4.1.1 假设检验与方差检验   假设检验适用于( 数据样本较小时 )   方差检验适用于( 数据样本较大时 ) import numpy as np import scipy.stats as ss #生成一20个数的标准正态分布 norm_dist = ss.norm.rvs(size=20) #检测norm_dist是否是正态分布,使用的方法是基于峰度和偏度的 print(ss.normaltest(norm_dist)) #结果:NormaltestResult(statistic=0.2025598777545946, pvalue=0.9036800223028876) #第一个是统计值,第二个值是p值 (1) P分布 检验常用于比较 两种样本是否一致 (例如:临床医疗上药物是否有效); (2) 独立分布 t检验 用于检测 两组值的均值是都有比较大的差异性 print(ss. ttest_ind (ss.norm.rvs(size=10),ss.norm.rvs(size=20))) #结果:Ttest_indResult(statistic=-0.575484958550556, pvalue=0.5695598474341583)   由于 p值大于 0.05(假定),可以接受该假设 (3) 卡方检验 常常用于确定 两因素件是否有比较强的联系

一起做RGB-D SLAM (4)

核能气质少年 提交于 2020-04-29 12:40:54
第四讲 点云拼接   广告:“一起做”系列的代码网址:https://github.com/gaoxiang12/rgbd-slam-tutorial-gx 当博客更新时代码也会随着更新。 SLAM技术交流群:374238181   读者朋友们大家好!尽管还没到一周,我们的教程又继续更新了,因为暑假实在太闲了嘛! 上讲回顾   上一讲中,我们理解了如何利用图像中的特征点,估计相机的运动。最后,我们得到了一个旋转向量与平移向量。那么读者可能会问:这两个向量有什么用呢?在这一讲里,我们就要使用这两个向量,把两张图像的点云给拼接起来,形成更大的点云。   首先,我们把上一讲的内容封装进slamBase库中,代码如下:   include/slamBase.h 1 // 帧结构 2 struct FRAME 3 { 4 cv::Mat rgb, depth; // 该帧对应的彩色图与深度图 5 cv::Mat desp; // 特征描述子 6 vector<cv::KeyPoint> kp; // 关键点 7 }; 8 9 // PnP 结果 10 struct RESULT_OF_PNP 11 { 12 cv::Mat rvec, tvec; 13 int inliers; 14 }; 15 16 // computeKeyPointsAndDesp 同时提取关键点与特征描述子 17

windows环境VS2015编译TensorFlow C++程序完全攻略

空扰寡人 提交于 2020-04-26 08:06:51
本文参考和综合了多篇网络博客文章,加以自己的实践,最终终于在windows环境下,编译出可以用于C++程序调用tensorflow API的程序,并执行成功。 考虑到网络上关于这方面的资料还较少,特总结全过程如下,希望能帮助到有需要的码农朋友,文中有部分文字步骤是借鉴他人文章,引用路径在最后列出。 一、环境准备: 操作系统:windows8.1 安装visual stduio2015 安装 Swigwin-3.0.12 ,注意其下载解压以后即可使用,本人放置路径在 D:/lib/swigwin-3.0.12, 可执行文件地址为 D:/swigwin-3.0.12/swig.exe 安装 python3.5 ,安装时注意选择将路径添加到环境变量。 安装 CMake-3.8.0 ,安装时注意选择将路径添加到环境变量。 安装 Git ,用于在编译过程中从GitHub上下载依赖项。 将GitHub上 TensorFlow的master分支 下载并解压到文件夹D:\tf中,编辑文件 tensorflow/tensorflow/contrib/cmake/CMakeLists.txt ,将第87行至93行修改如下: 1 if (tensorflow_OPTIMIZE_FOR_NATIVE_ARCH) 2 include(CheckCXXCompilerFlag) 3 CHECK_CXX

Eigen实现坐标转换

和自甴很熟 提交于 2020-04-20 04:00:27
(《视觉SLAM十四讲》第三讲习题7)设有小萝卜一号和二号在世界坐标系中。一号位姿q1 = [0.35, 0.2, 0.3, 0.1],t1=[0.3, 0.1, 0.1]。二号位姿q2=[-0.5, 0.4, -0.1, 0.2], t2=[-0.1, 0.5, 0.3].某点在一号坐标系下坐标为p=[0.5, 0, 0.2].求p在二号坐标系下的坐标 假设在世界坐标系中p点的坐标为P。 用四元数做旋转则有(在Eigen中四元数旋转为q×v,数学中则为q×v×q^-1): q1 × P + t1 = p1 q2 × P + t2 = p2 由上两式分别解算出: P = q1^-1 × (p1 - t1) P = q2^-1 × (p2 - t2) 两式联立求解则得到: p2 = q2 × q1^-1 × (p1 - t1) + t2 如果用欧拉矩阵(设一号欧拉矩阵为T1,二号欧拉矩阵为T2)则有: p1 = T1 × P p2 = T2 × P 求解P: P = T1^-1 × p1 P = T2^-1 × p2 联立求解则有: p2 = T2 × T1^-1 × p1 以下则是用Eigen实现的代码: #include <iostream> using namespace std; #include <eigen3/Eigen/Core> #include <eigen3

开发者说丨手把手教你写扩展卡尔曼滤波器

笑着哭i 提交于 2020-04-09 06:35:00
本文作者:Apollo开发者社区 卡尔曼滤波器 是一种由卡尔曼(Kalman)提出的用于时变线性系统的递归滤波器。这个系统可用包含 正交状态变量的微分方程模型 来描述,这种滤波器是将过去的测量估计误差合并到新的测量误差中来估计将来的误差。 当系统状态方程 不符合线性假设时 ,采用卡尔曼滤波无法获得理想的最优估计;在描述机器人状态时常常不满足卡尔曼滤波的假设,为了仍然能够使用卡尔曼滤波,我们采用 对 非线性系统进行线性化 等方法来扩大卡尔曼滤波的使用范围。扩展卡尔曼滤波与卡尔曼滤波主要 区别 在于:对状态方程和观测方程 泰勒展开 。 本文由 百度Apollo智能汽车事业部 自动驾驶工程师——陈光 撰写,对 扩展卡尔曼滤波器 进行了详细讲解,希望感兴趣的同学能通过阅读这篇文章有所收获。 以下,ENJOY 前言 在之前分享的 《开发者说 | 手把手教你写卡尔曼滤波器 》 中 , 以一个匀速运动小车的模型为例,让读者从感性上认识了卡尔曼滤波器的基本原理,它包含 预测(Prediction) 和 测量值更新(Measurement update) 两大过程。预测和测量值更新的交替执行,实现了卡尔曼滤波在状态估计中的闭环。 随后,我从 理性分析 的角度,以无人驾驶中 激光雷达 测量障碍物位置的数据为例,结合卡尔曼滤波所用到的公式,使用C+

Exposing Eigen::Tensor To Python Using Pybind11

心已入冬 提交于 2020-04-07 09:40:29
问题 I am trying to expose an Eigen tensor to python using pybind11. I can compile everything with no issue and can successfully import it to python. However, the data cannot be converted to a python type. I tried two methods. One is directly exposing the data and second using mapping. Both fail in python environment. #include <pybind11/pybind11.h> #include <pybind11/stl.h> #include <pybind11/stl_bind.h> #include <pybind11/numpy.h> #include <pybind11/eigen.h> #include <unsupported/Eigen/CXX11