G2O使用笔记(面向VSLAM场景)(学习笔记+有待完善+可能有错)

从零开始一起学习SLAM | 掌握g2o顶点编程套路 点“计算机视觉life”关注,置顶更快接收消息! 小白:师兄,上一次将的g2o框架《从零开始一起学习SLAM | 理解图优化,一步步带你看懂g2o代码》真的很清晰,我现在再去看g2o的那些优化的部分,基本都能看懂了呢! 师兄:那太好啦,以后多练习练习,加深理解 小白:嗯,我开始编程时,发现g2o的顶点和边的定义也非常复杂,光看十四讲里面,就有好几种不同的定义,完全懵圈状态。。。师兄,能否帮我捋... 阅读详情

动态内存问题还未优化,近期更新

在这里插入图片描述

类型定义】通过类型模板BlockSolverTraits定义类型g2o::BlockSolverTraits<节点1的维度,误差/节点2的维度>,在此称之为Traits_a_b

#include <g2o/core/block_solver.h>
typedef g2o::BlockSolverTraits<节点1的维度a,误差、节点2的维度b> Traits_a_b;

Traits_a_b中定义了 类型PoseMatrixType,LinearSolverType 等几个类型。
其中LinearSolverType是通过类型模板LinearSolver< PoseMatrixType >定义的一个类型,LinearSolver是linear_solver.h中定义的一个类

类型定义】借助上一步定义的类型,通过类型模板BlockSolver定义类型BlockSolver< Traits_a_b >,在此称之为blocksolver_a_b

#include <g2o/core/block_solver.h>
typedef BlockSolver<Traits_a_b> blocksolver_a_b;

blocksolver_a_b中 重新定义了 类型PoseMatrixType,LinearSolverType等在Traits_a_b已经定义的几个类型(实际上是将其引入了自己的作用域)。
blocksolver_a_b中定义了SparseBlockMatrix< PoseMatrixType >类型的几个成员,其中类模板SparseBlockMatrix定义在sparse_block_matrix.h中。

至此定义了类型(仅定义类类型且未完善,更未实例化):
在这里插入图片描述

对象定义】定义指向blocksolver_a_b::LinearSolverType类型的实例 指针 ,称之为 linearsolver

#include <g2o/solvers/dense/linear_solver_dense.h>//LinearSolverDense定义在此头文件中
#include <g2o/solvers/csparse/linear_solver_csparse.h>//LinearSolverCSparse定义在此头文件中
#include <g2o/solvers/pcg/linear_solver_pcg.h>//LinearSolverPCG定义在此头文件中
#include <g2o/solvers/cholmod/linear_solver_cholmod.h>//LinearSolverCholmod定义在此头文件中
std::unique_ptr<blocksolver_a_b::LinearSolverType> linersolver( new g2o::LinearSolverDense<blocksolver_a_b::PoseMatrixType>());

使其指向由LinearSolver派生出的类型LinearSolverDense<>/LinearSolverPCG<>/LinearSolverCSparse<>/LinearSolverCholmod<>中的某个类型的对象,传入类型的参数为blocksolver_a_b::PoseMatrixType

至此完成了:
在这里插入图片描述

对象定义】定义指向blocksolver_a_b类型的指针对象,称之为blocksolver_a_b_ptr

std::unique_ptr<blocksolver_a_b> blocksolver_a_b_ptr (new blocksolver_a_b( move(linearsolver) ));

blocksolver_a_b类型已经通过上述步骤完善,此步骤调用其构造函数
BlockSolver(LinearSolverType* linearSolver)定义指向该类型的指针,传入的参数是上一步中定义的指针 linearsolver

至此完成了:

在这里插入图片描述也可以说是完成了:
在这里插入图片描述

对象定义】 定义指向优化算法类型的指针对象opti_algorithm_ptr

可选择三种优化算法:Gauss-Newton/Levenberg-Marquardt/Powell’dogleg 之一,其构造函数均需传入类型模板Solver定义的类型的指针作为参数。而BlockSolver类型是Solver的派生的类型模板,故上一步中定义的指针blocksolver_a_b_ptr可以传入。

#include <g2o/core/optimization_algorithm_levenberg.h>//levenberg优化算法定义在此头文件中
g2o::OptimizationAlgorithmLevenberg* opti_algorithm_ptr( new g2o::OptimizationAlgorithmLevenberg( move( blocksolver_a_b_ptr) ) );

#include <g2o/core/optimization_algorithm_gauss_newton.h>//GaussNewton优化算法定义在此头文件中
g2o::OptimizationAlgorithmGaussNewton* opti_algorithem_ptr( new g2o::OptimizationAlgorithmGaussNewton( move( blocksolver_3_2_ptr) ) );

#include <g2o/core/optimization_algorithm_dogleg.h>//Dogleg优化算法定义在此头文件中
g2o::OptimizationAlgorithmDogleg* opti_algorithem_ptr( new g2o::OptimizationAlgorithmDogleg( move( blocksolver_3_2_ptr) ) );


至此完成了:
在这里插入图片描述

对象定义】定义稀疏优化器SparseOptimizer的对象(不是指针对象),称之为optimizer

g2o::SparseOptimizer optimizer;

并将上一步定义的优化算法指针opti_algorithm_ptr 传给其成员函数setAlgorithm()

optimizer.setAlgorithm(opti_algrithm_ptr);

至此完成了:
在这里插入图片描述

创建顶点

创建相机位姿顶点

常采用的节点类:VertexSE3Expmap.
VertexSE3Expmap类是以四元数和平移向量表达位姿的节点,其定义为:class VertexSE3Expmap : public BaseVertex<6, SE3Quat>。
其中SE3Quat是g2o自定义的表达位姿(变换)数据类型,包含该两个成员变量:Eigen::Quaterniond _r和Eigen::Vector3d _t。

#include <g2o/types/sba/types_six_dof_expmap.h>//VertexSE3Expmap定义在此头文件中
g2o::VertexSE3Expmap* pose = new g2o::VertexSE3Expmap;
pose->setId(0);
pose->setEstimate( g2o::SE3Quat(
        T_c_r_estimated_.rotation_matrix(),
        T_c_r_estimated_.translation());
//其他设置如:setMarginalized(true/false)等参数

添加节点

optimizer.addVertex(pose);
创建特征点(3d)顶点

常采用的节点类型:g2o::VertexSBAPointXYZ;

//空间点一般是多个,采用for循环添加
for(int i = 0; i != 3d点数量; ++i ){
	g2o::VertexSBAPoint* point = new g2o::VertexSBAPointXYZ;
	point->setId(i+1)//因为已经添加了一个节点pose,故Id从1开始
	point->setEstimate( 类型为Vector3d的空间点坐标 );
	point->setMarginalised(true);//or false
	optimizer.addVertex(point);
}

如果有需要可以【自定义顶点】

本部分内容来源于高翔博士《视觉SLAM十四讲》

自定义顶点要完成一下几项工作:
1.确定要继承的父类。一般是BaseVertex类
2.确定优化变量的维度。
3.确定优化变量的数据类型。
4.重写setToOriginImpl()函数。//该函数作用是更新顶点的估计值,保存到_estimate。
5.重写oplusImpl()函数。//该函数作用是重置顶点的估计值,保存到_estimate。
6.重写read和write函数。

自定义顶点的格式如下:

class MyVertex: public g2o::BaseVertex<优化变量的维度, 优化变量的类型>
{
public:
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
    //顶点估计值重置函数
    virtual void setToOriginImpl();
    //顶点估计值更新函数 
    virtual void oplusImpl( const double* update ) 
    // 存盘和读盘:可以留空
    virtual bool read( istream& in ) {}
    virtual bool write( ostream& out ) const {}
};

创建相机模型

CameraParameters定义在头文件types_six_dof_expmap.h中。

g2o::CameraParameters* camera = new g2o::CameraParameters(double focal_length, const Vector2D & principle_point, double baseline );
camera->setId ( 0 );//这里设置的id是该参数(相机)在optimizer._parameters中的索引值
optimizer.addParameter ( camera )//将该参数(相机)保存在optimizer的成员_parameters(类型是ParameterContainer)中

创建边

同时优化相机位姿和空间点的边

常采用的边类型g2o::EdgeProjectXYZ2UV;

//边也有多条,借助for循环进行添加
for(int i = 0; i != 边的数量; ++i ){
	g2o::EdgeProjectXYZ2UV* edge = new g2o::EdgeProjectXYZ2UV;
	edge->setId(i);
	edge->setVertex(0,dynamic_cast<g2o::VertexSBAPointXYZ*>(optimizer.vertex(i+1)));
	//其中的optimizer.vertex()是定义在optimizable_graph.h中的类型OptimizableGraph中的成员函数,
	//它按照参数将添加到优化器(此处的optimizer)中的相应顶点(Id=参数)转化为Vertex*类型后返回,
	//因此此处需要使用dynamic_cast<>()将其类型复原。
	//该成员函数的声明与定义如下:
	//inline Vertex* vertex(int id) { return reinterpret_cast<Vertex*>(HyperGraph::vertex(id));}
	edge->setVertex(1,pose);
	edge->setMeasurement( 类型为Vector2d的像素坐标);
	edge->setParameterId(0,0);
	//Edge中有成员变量std::vector<int> _parameterIds,保存该边所用
	//到的parameter在optimizer中添加的参数中索引值,即添加Parameter
	//时用setId()添加的参数Id。edge->setParameterId(a,b),a是Edge
	//中_parameterIds的元素索引,b是optimizer中Parameter的Id。
	edge->Information(Eigen::Matrix2d::Identity());
	optimizer.addEdge(edge);
}

如果想仅优化相机位姿,而不优化空间点可以【自定义相应的边】

本部分内容来源于高翔博士《视觉SLAM十四讲》
得益于C++的继承机制,我们直接从g2o的已有边类类型中衍生出我们需要的边

自定义g2o的边,要进行以下几项工作:
1.确定继承的父类,你肯定不想从头写一个类类型吧
2. 确定观测值的维度
3. 确定观测值的类型,同时也是边的成员_error的数据类型
4. 确定连接节点的类型
5. 重写compute()函数。该函数作用是取出边所连接节点的估计值,根据模型计算观测值的比较值,并与观测值进行比较将结果保存到Edge的成员_error(_error=观测值向量-计算出的观测值的比较值向量)
6. 重写linearizeOplus()函数。该函数计算当前_error关于节点每个维度的的Jacobian矩阵_jacobianOplusXi(这是父类中预定义的成员)。该函数好像也可以省略,g2o会自动求导,但能够写出的话,建议提供。
8. 重写read和l write}函数
9. 添加一些需要用到的成员变量、成员函数
格式如下(一元边)

class  MyEdge: public g2o::BaseUnaryEdge<观测值的维度, 观测值的类型(也是_error的类型),连接节点的类型>
{
public:
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
   
    //误差计算函数
    virtual void computeError();   
    //Jacobain矩阵计算函数
    virtual void linearizeOplus();    
    //读取与写入函数
    virtual bool read( std::istream& in ){}
    virtual bool write(std::ostream& os) const {};    
};

对于本例:
1.仅优化当前位姿,故只有一个节点,以BaseUnaryEdge为父类
2.观测值为像素坐标,维度为2
3.像素坐标采用Eigen::Vector2d类型
4.节点类型:g2o::VertexSE3Expmap
7.我们不进行读写操作,read和write函数留空
8.参加数据成员:Vector3d 空间点坐标、Camera* 相机模型方便计算。

class  Edge_PoseOnly: public g2o::BaseUnaryEdge<2, Eigen::Vector2d, g2o::VertexSE3Expmap>
{
public:
    EIGEN_MAKE_ALIGNED_OPERATOR_NEW
   
    //误差计算函数
    virtual void computeError();   
    //Jacobain矩阵计算函数
    virtual void linearizeOplus();    
    //读取与写入函数
    virtual bool read( std::istream& in ){}
    virtual bool write(std::ostream& os) const {};    
public:
    Eigen::Vector3d point_; 
    myslam::Camera::Ptr camera_;//Camera类是自定义的,这是个一般的过程,不再赘述
};
void Edge_PoseOnly::computeError()
{
    const g2o::VertexSE3Expmap* v = static_cast<const g2o::VertexSE3Expmap*>(_vertices[0]);
    _error = _measurement - camera_->camera2pixel( v->estimate().map(point_));
}

void Edge_PoseOnly::linearizeOplus()
{
    const g2o::VertexSE3Expmap* v = static_cast<const g2o::VertexSE3Expmap*>(_vertices[0] );
    Eigen::Vector3d xyz = v->estimate().map( point_);
    double x = xyz[0];
    double y = xyz[1];
    double z = xyz[2];
    double z_2 = z*z;
    
    _jacobianOplusXi ( 0,0 ) =  x*y/z_2 *camera_->fx_;
    _jacobianOplusXi ( 0,1 ) = - ( 1+ ( x*x/z_2 ) ) *camera_->fx_;
    _jacobianOplusXi ( 0,2 ) = y/z * camera_->fx_;
    _jacobianOplusXi ( 0,3 ) = -1./z * camera_->fx_;
    _jacobianOplusXi ( 0,4 ) = 0;
    _jacobianOplusXi ( 0,5 ) = x/z_2 * camera_->fx_;

    _jacobianOplusXi ( 1,0 ) = ( 1+y*y/z_2 ) *camera_->fy_;
    _jacobianOplusXi ( 1,1 ) = -x*y/z_2 *camera_->fy_;
    _jacobianOplusXi ( 1,2 ) = -x/z *camera_->fy_;
    _jacobianOplusXi ( 1,3 ) = 0;
    _jacobianOplusXi ( 1,4 ) = -1./z *camera_->fy_;
    _jacobianOplusXi ( 1,5 ) = y/z_2 *camera_->fy_;
}

启动优化

optimizer.setVerbose ( true );//输出信息
optimizer.initializeOptimization();//启动
optimizer.optimize ( 100 );//迭代次数100

结果

Eigen::Isometry3d ( pose->estimate() ).matrix()

其它_1:关于节点成员函数setToOriginImpl(),oplusImpl(),setEstimate()的解析

OptimizableGraph:: G2O_CORE_API Vertex : public HyperGraph::Vertex, public HyperGraph::DataContainer
	void setToOrigin() { setToOriginImpl(); updateCache();}

	virtual void oplusImpl(const double* v) = 0;//纯虚函数

	virtual void setToOriginImpl() = 0;//纯虚函数

class BaseVertex : public OptimizableGraph::Vertex 
	void setEstimate(const EstimateType& et) { _estimate = et; updateCache();}//不是虚函数故子类直接使用,无法重写,用于设定_estimate的值
	BaseVertex没有声明定义父类oplusImpl(),setToOriginImpl两个纯虚函数
	BaseVertex没有重写父类setToOrigin()函数
	BaseVertex用作模板,不可直接使用

class G2O_TYPES_SBA_API VertexSE3Expmap : public BaseVertex<6, SE3Quat>
	virtual void setToOriginImpl() {_estimate = SE3Quat();}
	//重写了从祖父继承来的setToOriginImpl(),用于初始化_estimate为0

	virtual void oplusImpl(const double* update_)  {
	    Eigen::Map<const Vector6d> update(update_);
	    setEstimate(SE3Quat::exp(update)*estimate());
	  }
	//重写了从祖父继承来的soplusImp(),用于更新_estimate,其调用从父类继承来setEstimate()向_estimate写入值

其它_2:节点继承关系

{(G2O_CORE_API HyperGraphElement -> G2O_CORE_API HyperGraph::Vertex )+ G2O_CORE_API HyperGraph::DataContainer} -> G2O_CORE_API OptimizableGraph::Vertex -> BaseVertex ->{ G2O_TYPES_SBA_API VertexSE3Expmap / G2O_TYPES_SBA_API VertexSBAPointXYZ}

其它_3:边的继承关系

G2O_CORE_API HyperGraphElement -> G2O_CORE_API HyperGraph::Edge -> G2O_CORE_API optimizeble_graph BaseEdge -> BaseBinaryEdge -> G2O_TYPES_SBA_API EdgeProjectXYZ2UV

VSLAM框架对比 格VSLAM特点介绍: (一)ORB-SLAM2 (二)ORB-SLAM3 (三)LSD-SLAM (四) 阅读详情

相关推荐

vslam初总结报告

下载的【不】是高翔博士用的源代码,但是是同一个妈生的代码,因为我以前装的ros是kinetic版本,看了一下区别不大。感觉跟着他的教程走会容易一些。师兄如果你换了代码吼我一声~!在家也没有太多事有些远程也是䘅搞的…… vslam系统框架 来源参考博客:https://blog.youkuaiyun.com/qq_27550989/article/details/78341904 比较合适的两个框架: RGB...

qq_37994458的博客 471

3d-2d g2o基本流程 以及 BlockSolverTraits的定义

在使用g2o的时候,通常要线设定g2o的顶点类型和边类型。 其中BlockSolverTraits<M,N>参数总是让人琢磨不透。 以下为代码示例,接下来给出解答。

hhz_999的博客 2090

基于深度摄像头的vslam(二)

最近有点忙,人情世故,再加上给舍友填坑,又出现了一点其他的遭心事,忙完之后正好在元旦假期,就给自己放假了,逃避回来之后还能怎么办,继续做阿…… 参考网址: https://blog.youkuaiyun.com/hu_helloworld/article/details/80251237 http://blog.sciencenet.cn/blog-571755-694742.html (二)准备工作 下载代...

qq_37994458的博客 816

【SLAM】G2O优化库超详细解析

通用图优化。为何叫通用呢?G2O的核里带有各种各样的求解器,而它的顶点、边的类型则多种多样。通过自定义顶点和边,事实上,只要一个优化问题能够表达成图,那么就可以用G2O去求解它。常见的,比如bundle adjustment、ICP、数据拟合,都可以用G2O来做。所谓图优化,是把优化问题表现成图的一种方式,这里的图是图论意义上的图。一个图由若干个顶点,以及连着这些顶点的边组成。在这里,我们用顶点表示优化变量,而用边表示残差项。

Yngz_Miao的博客 1万+

g2o从入门到精通

前言 这里将我对g2o的一些常见用法,做个简单总结,便于后续温习回顾,如能对大家起到半点借鉴作用,实乃我之幸事。 一 先看两个案例 1.1 案例一: // compute uwb pose by mutli distances using least square estimate // fix_xy means only optimize z EdgeUwbDistanceToPose::EdgeUwbDistanceToPose() { } EdgeUwbDistanceToPose::EdgeU

3D视觉工坊 522

ORB-SLAM_地图点优化_固定位姿_g2o定义_雅可比矩阵推导

在构建vslam点云地图时,如何固定位姿,仅仅对地图点进行优化的问题。

惊鸿一博 402

【g2o】 解决 g2o::BlockSolverTraits<-1, -1>]: Assertion `_sizePoses > 0 && “allocating with wrong size“‘

Thirdparty/g2o/g2o/core/block_solver_impl.h:70: void g2o::BlockSolver::resize(int*, int, int*, int, int) [with Traits = g2o::BlockSolverTraits]: Assertion `_sizePoses > 0 && “allocating with wrong size”’ failed参考 issue 中的解决方式我在 中修改 进行了修改。...

qq_45110581的博客 705

手把手教你学Simulink--双足机器人分数阶PID控制仿真

分数阶PID(Fractional-order PID, FOPID)控制是一种先进的控制策略,它扩展了传统的整数阶PID控制器的概念。FOPID控制器允许积分和微分项的阶次不是严格的整数,而是可以是任意实数,这为系统提供了更多的设计自由度,并可能带来更好的性能。在双足机器人控制中,分数阶PID控制可以用于改善机器人的平衡控制、轨迹跟踪等任务的性能。下面我们将详细介绍如何使用Simulink进行基于分数阶PID控制方法的双足机器人仿真研究。

MHD0815的博客 877

欢迎走进VSLAM

1 开启新技术之门 SLAM,全称叫做Simultaneous Localization and Mapping,中文叫做同时定位与建图。SLAM技术发展到如今已经几十年,目前以激光雷达作为主传感器的SLAM技术比较稳定、可靠,仍然是主流的技术方案。但随着最近几年计算机视觉技术的快速发展,SLAM技术越来越多的应用于家用机器人、无人机、AR设备,基于视觉的Visual SLAM(简称VSLAM)逐...

abcdef123456gg的博客 5673

SNAP计算哨兵二号的叶面积指数(LAI)

对于哨兵二号数据以及LANDSAT8数据,SNAP提供已经集成好的模块计算LAI。在Optical->Thematic Land Processing->Biopyhsical Processor目录下面。 对于经过Sen2Cor处理好的数据,需经过重采样才可进行计算。重采样工具在Raster->Geometric->Resampling。 如果选择Biopyhsical Processor S2_10m进行计算,需要将所有的波段都重采样为10米(哨兵二号的第二波段为10米,可据此波

gxwwww的博客 9410

AD20 Channel-Offset Error 解决办法

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言AD20 PCB相同电路模块ROOM格式复用时出现 Channel-Offset Error 解决办法一、问题现象二、解决办法 前言 AD20 PCB相同电路模块ROOM格式复用时出现 Channel-Offset Error 解决办法 一、问题现象 我们经常在使用Room格式快速布局相同模块电路时出现以下问题, 二、解决办法 相同模块电路PCB布局复制的过程网上有很多,这里不再做赘述,步骤都差不多,只说问题根源; 1:.

m0_47201213的博客 7618

VSLAM依赖库版本配置(CMake)

在开发VSLAM程序的过程中,我需要不断地学习开源程序,如ORB-SLAM2、SVO、LSD-SLAM、DSO、LearnVIORB、ygz-stereo-inertial、svo_degelet、ORB-TGZ-SLAM等等,其中依赖的库较多,主要的有OpenCV、g2o、eigen3、Sophus等。 不同的程序使用的版本往往不一样,由于需要学习不同的开源程序并转化为自己的知识,进...

403

CH340驱动安装全攻略:从Windows到MacOS的避坑指南(2025最新版)

本文提供2025年最新版CH340驱动安装全攻略,涵盖Windows、MacOS和Linux三大操作系统。详细解析了驱动安装的核心原理、标准流程,并针对Windows设备管理器报错、MacOS系统安全限制等常见“坑点”提供了深度排错与解决方案,旨在帮助开发者快速稳定地完成USB转串口通信配置。

earth的博客 425

终极指南:如何用stella_vslam构建强大的视觉SLAM系统

在当今机器人、自动驾驶和增强现实领域,**视觉SLAM系统**(Simultaneous Localization and Mapping)是实现环境感知和自主导航的核心技术。stella_vslam作为一款开源的多功能视觉SLAM框架,为你提供了从单目、双目到RGBD相机的完整解决方案。 ## 🚀 项目亮点:为什么选择stella_vslam? stella_vslam是一个高度模块化的*

gitblog_00075的博客 734

【3天快速入门WPF】1-从最简单的xaml开始

首先我们要知道xaml语法中声明即定义,意思就是“见到元素就相当于创建实例”,MainWindow.xaml的主干是一个元素里包含着一个 元素。这段程序就是在定义一个Window类的实例,这个实例的一个组成部分是一个Grid类的实例。

Zy100Papa的博客 1621

一文读懂OpenClaw:核心组件与工作原理深度解析

Agent核心:负责理解意图、规划任务、协调执行消息系统:统一的消息格式,实现组件间解耦工具注册表:可扩展的工具系统,支持自定义工具模型适配层:多模型支持,统一API接口安全机制:沙箱隔离、权限确认、操作审计性能优化:并行执行、智能缓存、增量更新理解这些核心组件和工作原理,将帮助你更好地使用OpenClaw,也为后续开发自定义扩展打下坚实基础。在下一篇文章中,我们将详细介绍OpenClaw的界面操作,包括命令行与交互模式的各种技巧。

gaoxiang_120的专栏 832

如何快速上手stella_vslam:视觉SLAM的完整入门指南

stella_vslam是一个功能强大的开源视觉SLAM(同时定位与地图构建)框架,支持单目、双目和RGBD相机,能够处理多种相机模型包括透视、鱼眼和等矩形投影。无论你是机器人开发者、AR/VR研究者还是计算机视觉爱好者,这个项目都能帮助你快速构建自己的视觉定位系统。😊 ## 🚀 项目亮点:为什么选择stella_vslam? stella_vslam作为OpenVSLAM的社区分支版本,

gitblog_01000的博客 502

SAP-ABAP:SAP采购业务核心表关联关系详解

MM(核心)、FI(财务)、SD(计划协议):PR → PO → GR → MIRO → FI过账。

baidu_35680696的博客 930

5个核心功能让你轻松掌握stella_vslam视觉SLAM框架

stella_vslam是一个功能强大的视觉同步定位与地图构建(Visual SLAM)框架,支持单目、双目和RGBD相机,兼容透视、鱼眼和等矩形投影等多种相机模型。这个开源项目基于OpenVSLAM社区分支开发,提供了完整的视觉SLAM解决方案,特别适合机器人导航、增强现实和自动驾驶等应用场景。 ## 🎯 为什么选择stella_vslam而不是其他SLAM框架? 与其他视觉SLAM系统相

gitblog_00086的博客 833

数据库课程案例——电力公司收费管理系统分析与实践,完整带SQL语句

某电力公司收费管理信息系统实现客户信息、用电类型(类别号、类别名、电价)及业务员管理;实现客户用电信息管理(客户号、月份、用电类别号、用电度数);实现客户费用管理(客户号、月份、费用、收费标志),收费标志的默认值为“未收”;实现收费登记(客户、月份、应收费用、实收费用、业务员),并自动修改收费标志(用触发器实现);创建触发器,实现收费时自动更加应收费用和实收费用,计算本次结余,然后修改客户信息表中的结余金额;创建存储过程统计指定月份应收费用和实收费用;创建存储过程查询指定月份未交费的用户信息,以便崔费;创建

qq_44242804的博客 2761

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

vslam中尺度不确定因子

在VSLAM(Visual Simultaneous Localization and Mapping,视觉同时定位与建图)中,尺度不确定因子主要产生于单目相机在仅依赖图像信息时无法直接获取场景的真实尺度。

weixin_41150257的博客 1059

深度学习工具包 DeepLearningToolbox

深度学习工具包Deprecation notice.-----This toolbox is outdated and no longer maintained.There are much better tools available for deep learning than this toolbox, e.g. [Theano](http://deeplearning.net/software/theano/), [torch](http://torch.ch/) or [tensorflow](http://www.tensorflow.org/)I would suggest you use one of the tools mentioned above rather than use this toolbox.Best, Rasmus.DeepLearnToolbox================A Matlab toolbox for Deep Learning.Deep Learning is a new subfield of machine learning that focuses on learning deep hierarchical models of data.It is inspired by the human brain's apparent deep (layered, hierarchical) architecture.A good overview of the theory of Deep Learning theory is[Learning Deep Architectures for AI](http://www.iro.umontreal.ca/~bengioy/papers/ftml_book.pdf)For a more informal introduction, see the following videos by Geoffrey Hinton and Andrew Ng.* [The Next Generation of Neural Networks](http://www.youtube.com/watch?v=AyzOUbkUf3M) (Hinton, 2007)* [Recent Developments in Deep Learning](http://www.youtube.com/watch?v=VdIURAu1-aU) (Hinton, 2010)* [Unsupervised Feature Learning and Deep Learning](http://www.youtube.com/watch?v=ZmNOAtZIgIk) (Ng, 2011)If you use this toolbox in your research please cite [Prediction as a candidate for learning deep hierarchical models of data](http://www2.imm.dtu.dk/pubdb/views/publication_details.php?id=6284)```@MASTERSTHESIS\{IMM2012-06284, author = "R. B. Palm", title = "Prediction as a candidate for learning deep hierarchical models of data", year = "2012",}```Contact: rasmusbergpalm at gmail dot comDirectories included in the toolbox-----------------------------------`NN/` - A library for Feedforward Backpropagation Neural Networks`CNN/` - A library for Convolutional Neural Networks`DBN/` - A library for Deep Belief Networks`SAE/` - A library for Stacked Auto-Encoders`CAE/` - A library for Convolutional Auto-Encoders`util/` - Utility functions used by the libraries`data/` - Data used by the examples`tests/` - unit tests to verify toolbox is workingFor references on each library check REFS.mdSetup-----1. Download.2. addpath(genpath('DeepLearnToolbox'));Example: Deep Belief Network---------------------```matlabfunction test_example_DBNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit RBM and visualize its weightsrand('state',0)dbn.sizes = [100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);figure; visualize(dbn.rbm{1}.W'); % Visualize the RBM weights%% ex2 train a 100-100 hidden unit DBN and use its weights to initialize a NNrand('state',0)%train dbndbn.sizes = [100 100];opts.numepochs = 1;opts.batchsize = 100;opts.momentum = 0;opts.alpha = 1;dbn = dbnsetup(dbn, train_x, opts);dbn = dbntrain(dbn, train_x, opts);%unfold dbn to nnnn = dbnunfoldtonn(dbn, 10);nn.activation_function = 'sigm';%train nnopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.10, 'Too big error');```Example: Stacked Auto-Encoders---------------------```matlabfunction test_example_SAEload mnist_uint8;train_x = double(train_x)/255;test_x = double(test_x)/255;train_y = double(train_y);test_y = double(test_y);%% ex1 train a 100 hidden unit SDAE and use it to initialize a FFNN% Setup and train a stacked denoising autoencoder (SDAE)rand('state',0)sae = saesetup([784 100]);sae.ae{1}.activation_function = 'sigm';sae.ae{1}.learningRate = 1;sae.ae{1}.inputZeroMaskedFraction = 0.5;opts.numepochs = 1;opts.batchsize = 100;sae = saetrain(sae, train_x, opts);visualize(sae.ae{1}.W{1}(:,2:end)')% Use the SDAE to initialize a FFNNnn = nnsetup([784 100 10]);nn.activation_function = 'sigm';nn.learningRate = 1;nn.W{1} = sae.ae{1}.W{1};% Train the FFNNopts.numepochs = 1;opts.batchsize = 100;nn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.16, 'Too big error');```Example: Convolutional Neural Nets---------------------```matlabfunction test_example_CNNload mnist_uint8;train_x = double(reshape(train_x',28,28,60000))/255;test_x = double(reshape(test_x',28,28,10000))/255;train_y = double(train_y');test_y = double(test_y');%% ex1 Train a 6c-2s-12c-2s Convolutional neural network %will run 1 epoch in about 200 second and get around 11% error. %With 100 epochs you'll get around 1.2% errorrand('state',0)cnn.layers = { struct('type', 'i') %input layer struct('type', 'c', 'outputmaps', 6, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %sub sampling layer struct('type', 'c', 'outputmaps', 12, 'kernelsize', 5) %convolution layer struct('type', 's', 'scale', 2) %subsampling layer};cnn = cnnsetup(cnn, train_x, train_y);opts.alpha = 1;opts.batchsize = 50;opts.numepochs = 1;cnn = cnntrain(cnn, train_x, train_y, opts);[er, bad] = cnntest(cnn, test_x, test_y);%plot mean squared errorfigure; plot(cnn.rL);assert(er<0.12, 'Too big error');```Example: Neural Networks---------------------```matlabfunction test_example_NNload mnist_uint8;train_x = double(train_x) / 255;test_x = double(test_x) / 255;train_y = double(train_y);test_y = double(test_y);% normalize[train_x, mu, sigma] = zscore(train_x);test_x = normalize(test_x, mu, sigma);%% ex1 vanilla neural netrand('state',0)nn = nnsetup([784 100 10]);opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samples[nn, L] = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.08, 'Too big error');%% ex2 neural net with L2 weight decayrand('state',0)nn = nnsetup([784 100 10]);nn.weightPenaltyL2 = 1e-4; % L2 weight decayopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex3 neural net with dropoutrand('state',0)nn = nnsetup([784 100 10]);nn.dropoutFraction = 0.5; % Dropout fraction opts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex4 neural net with sigmoid activation functionrand('state',0)nn = nnsetup([784 100 10]);nn.activation_function = 'sigm'; % Sigmoid activation functionnn.learningRate = 1; % Sigm require a lower learning rateopts.numepochs = 1; % Number of full sweeps through dataopts.batchsize = 100; % Take a mean gradient step over this many samplesnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex5 plotting functionalityrand('state',0)nn = nnsetup([784 20 10]);opts.numepochs = 5; % Number of full sweeps through datann.output = 'softmax'; % use softmax outputopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, train_x, train_y, opts);[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');%% ex6 neural net with sigmoid activation and plotting of validation and training error% split training data into training and validation datavx = train_x(1:10000,:);tx = train_x(10001:end,:);vy = train_y(1:10000,:);ty = train_y(10001:end,:);rand('state',0)nn = nnsetup([784 20 10]); nn.output = 'softmax'; % use softmax outputopts.numepochs = 5; % Number of full sweeps through dataopts.batchsize = 1000; % Take a mean gradient step over this many samplesopts.plot = 1; % enable plottingnn = nntrain(nn, tx, ty, opts, vx, vy); % nntrain takes validation set as last two arguments (optionally)[er, bad] = nntest(nn, test_x, test_y);assert(er < 0.1, 'Too big error');```[![Bitdeli Badge](https://d2weczhvl823v0.cloudfront.net/rasmusbergpalm/deeplearntoolbox/trend.png)](https://bitdeli.com/free "Bitdeli Badge")

德鲁周记06--VSLAM从入门到入坟

VSLAM入门介绍基础知识三维空间的刚体运动欧式变换四元数欧拉角李群与李代数线性拟合相机单目相机双目相机深度相机基本框架视觉里程计特征匹配ORB直接法对比后端优化EKFBA(Bundle Adjustment)回环检测建图最后说点 因为研究生的工程实践我选择了这个方向,这两周一直在学VSLAM,看完了高翔老师的视频和《视觉SLAM十四讲》,强烈推荐!!!入门必看,神书!!当然我第一遍自我感觉是肯定没看太懂的,只能说知道了一个框架和目前的一些主流算法。正好下周要开题,要做PPT所以也写一篇博客记录一下,算是一

qq_44047943的博客 1058

IEM模型,地表粗糙度模拟

利用微波反演土壤水分时候,利用IEM模型可以实现对随机地表的模拟

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

openVSLAM-stella_vslam的编译安装

比较新的视觉SLAM适配的相机硬件有:该算法支持单目、双目还有RGBD的视觉SLAM系统stella_vslam 的一个显着特点是系统可以处理各种类型的相机模型,例如透视、鱼眼和等距柱状。如果需要,用户可以轻松实现额外的相机模型(例如双鱼眼、折反射)。例如,使用(如RICOH THETA系列、insta360系列等)的视觉SLAM算法如上所示。

YOULANSHENGMENG的博客 3080

VSLAM学习记录1(适合小白学习)

本文是vslam一书的学习记录,适合小白学习,里面有不对的地方请指正,有不懂的请联系我。

qq_52383168的博客 1387

VSLAM算法(二):PnP求解 3D-2D 相机位姿及 BA优化算法

BA优化模型如下:优化变量(空间位置P和相机位姿),边(P在相机平面的投影像素坐标) // 调用OpenCV 的 PnP 求解,可选择EPNP,DLS等方法 solvePnP ( pts_3d, pts_2d, K, Mat(), r, t, false ); cv::Rodrigues ( r, R ); // r为旋转向量形式,用Rodrigues公...

qq_29230261的博客 5257
上一篇: 类类型的拷贝构造函数与析构函数,成员中含有动态内存指针时的处理(C++11)
下一篇: Eigen中的矩阵及向量运算
isErik
博客等级 码龄9年 38粉丝 54原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值