VINS技术路线

转自:https://blog.csdn.net/wangshuailpp/article/details/78461171

   写在前面:本文整和自己的思路,希望对学习VINS或者VIO的同学有所帮助,如果你觉得文章写的对你的理解有一点帮助,可以推荐给周围的小伙伴们,当然,如果你有任何问题想要交流,欢迎随时探讨。话不多说,下面上正文。

VINS代码地址:https://github.com/HKUST-Aerial-Robotics/VINS-Mono

参考文档:1.VINS-Mono A Robust and Versatile Monocular Visual-Inertial State Estimator

2.Quaternion kinematics for the error-state Kalman filter

如果想单独了解某一块内容,可以看分开讨论的部分,内容相同:

VINS理论与代码详解0——理论基础白话篇

VINS理论与代码详解1——框架解析

VINS理论与代码详解2——单目视觉跟踪

VINS理论与代码详解3——IMU预积分(最近更新IMU残差雅各比计算推导)

VINS理论与代码详解4——初始化

VINS理论与代码详解5——基于滑动窗口的单目视觉紧耦合后端优化模型(最近更新视觉雅各比计算推导)

最近整理了ORB_SLAM2视觉惯性紧耦合的理论分析,想了解的可以点开下面的连接:

ORB_SLAM2视觉惯性紧耦合定位算法详解

如果只想单独了解ORB_SLAM2视觉惯性紧耦合的理论分析某一块的话,可以看分开讨论的部分,内容都是相同的:

ORB_SLAM2视觉惯性紧耦合定位技术路线与代码详解0——整体框架与理论基础知识

ORB_SLAM2视觉惯性紧耦合定位技术路线与代码详解1——IMU流型预积分

ORB_SLAM2视觉惯性紧耦合定位技术路线与代码详解2——IMU初始化

ORB_SLAM2视觉惯性紧耦合定位技术路线与代码详解3——紧耦合优化模型

在这些博客中经常提到的一些关键数学知识总结到下面,随时更新欢迎阅读指正:

视觉SLAM常见的QR分解SVD分解等矩阵分解方式求解满秩和亏秩最小二乘问题(最全的方法分析总结)

凸函数的Hessian矩阵与高斯牛顿下降法增量矩阵半正定性的理解

   VINS代码主要包含在两个文件中,分别是feature_tracker和vins_estimate,feature_tracker就像文件的名字一样,总体的作用是接收图像,使用KLT光流算法踪;vins_estimate包含相机和IMU数据的前端预处理(也就是预积分过程)、单目惯性联合初始化(在线的标定过程)、基于滑动窗口的BA联合优化、全局的图优化和回环检测等。要想真正的理解一个SLAM框架,必须真正搞懂其对应的算法模型,然后才能研究其代码逻辑,最后做到相得益彰的效果,因此本次讲解主要是结合论文中的理论知识这和两个文件中的代码进行详细的探讨。整体的框架都比较熟悉,如下图所示,第一部分是Measuremen Preprocessing:观测值数据预处理,包含图像数据跟踪IMU数据预积分;第二部分是Initialization:初始化,包含单纯的视觉初始化和视觉惯性联合初始化;第三部分Local Visual-Inertia BA and Relocalization:局部BA联合优化和重定位,包含一个基于滑动窗口的BA优化模型;第四部分Global Pose Graph Optimization:全局图优化,只对全局的位姿进行优化;第五部分Loop detection:回环检测。

 

一.Feature_tracker文件夹中

 

        首先讲第一部分,也就是纯粹的图像处理部分内容,在论文中的第IV点观测值预处理的A部分视觉前端处理,为了更好的理解代码,有必要将论文中的相关内容和大家讨论一番。

         论文内容:每当进入新的图像,都会使用KLT稀疏光流法进行跟踪,同时提取100-300个角点信息,我的理解是角点是用来建立图像,光流跟踪是用来快速定位。同时在这里还进行了关键帧的选取,主要是两个剔除关键帧的策略,分别是平均视差法和跟踪质量法。平均视差法:如果当前帧的和上一个关键帧跟踪点的平均视差超出了一个设定的阈值,就将当前帧设为关键帧。这里有一个问题,就是旋转和平移都会产生视差(不只是平移哦),当出现纯旋转的时候特征点无法被三角化,无法计算出旋转值,也就无法计算跟踪点间的平均视差,为了解决这一问题,采用短时的陀螺仪观测值来补偿旋转,从而计算出视差,这一过程只应用到平均视差的计算,不会影响真实的旋转结果。

         具体代码实现:主要负责图像角点提取和光流跟踪,只有一个主线程。主要是三个源程序,分别是feature_tracker、feature_tracker_node以及parameters。feature_tracker_node是特征跟踪线程的系统入口,feature_tracker是特征跟踪算法的具体实现,parameters是设备等参数的读取和存放。

1.      feature_tracker_node.cpp系统入口

(1)      main()函数

步骤1:readParameters(n);读取参数,是config->euroc->euroc_config.yaml中的一些配置参数。

步骤2: trackerData[i].readIntrinsicParameter(CAM_NAMES[i]);在这里NUM_OF_CAM设置成常量1,只有一个摄像头(单目),读取相机内参。

步骤3:判断是否加入鱼眼mask来去除边缘噪声

步骤4: ros::Subscriber sub_img = n.subscribe(IMAGE_TOPIC, 100,img_callback); 订阅话题和发布话题,监听IMAGE_TOPIC(/cam0/image_raw),有图像发布到这个话题上的时候,执行回调函数,这里直接进入到img_callback函数中接收图像,前端视觉的算法基本在这个回调函数中。

1)  img_callback(const sensor_msgs::ImageConstPtr &img_msg)接收图像

步骤1: 频率控制,保证每秒钟处理的image不多于FREQ,这里将平率控制在10hz以内。

步骤2: 处理单目相机

步骤2.1: trackerData[i].readImage(ptr->image.rowRange(ROW * i, ROW *(i + 1)));读取到的图像数据存储到trackerData中,读取完之后如果图像太亮或太黑(EQUALIZE=1),使用createCLAHE对图像进行自适应直方图均衡化,如果图像正常,设置成当前图像。在读取图像的时候进行光流跟踪和特征点的提取。FeatureTracker类中处理的主要函数就是readImage(),这里涉及到3个img(prev_img, cur_img, forw_img)和pts(prev_pts,cur_pts, forw_pts),两者是相似的。刚开始看不是太好理解,cur和forw分别是LK光流跟踪的前后两帧,forw才是真正的“当前”帧,cur实际上是上一帧,而prev是上一次发布的帧,它实际上是光流跟踪以后,prev和forw根据Fundamental Matrix做RANSAC剔除outlier用的,也就是rejectWithF()函数. readImage()的处理流程为:

①先调用cv::CLAHE对图像做直方图均衡化(如果EQUALIZE=1,表示太亮或则太暗)

PS:CLAHE是一种直方图均衡算法,能有效的增强或改善图像(局部)对比度,从而获取更多图像相关边缘信息有利于分割,比如在书架识别系统的书脊切割中,使用CLAHE可以比传统的直方图增强方法达到更好的增强书脊边界直线的效果,从而有利于后续的书脊边界直线的检测和提取。还能够有效改善AHE中放大噪声的问题,虽然在实际中应用不多,但是效果确实不错。

②调用calcOpticalFlowPyrLK()跟踪cur_pts到forw_pts,根据status,把跟踪失败的点剔除(注意:prev, cur,forw, ids, track_cnt都要剔除),这里还加了个inBorder判断,把跟踪到图像边缘的点也剔除掉.

③如果不需要发布特征点,则到这步就完了,把当前帧forw赋给上一帧cur, 然后退出.如果需要发布特征点(PUB_THIS_FRAME=1), 则执行下面的步骤

④先调用rejectWithF()对prev_pts和forw_pts做ransac剔除outlier.(实际就是调用了findFundamentalMat函数), 在光流追踪成功就记被追踪+1,数值代表被追踪的次数,数值越大,说明被追踪的就越久

⑤调用setMask(), 先对跟踪点forw_pts按跟踪次数降排序, 然后依次选点, 选一个点, 在mask中将该点周围一定半径的区域设为0, 后面不再选取该区域内的点. 有点类似与non-max suppression, 但区别是这里保留track_cnt最高的点.

⑥在mask中不为0的区域,调用goodFeaturesToTrack提取新的角点n_pts, 通过addPoints()函数push到forw_pts中, id初始化-1,track_cnt初始化为1.

整体来说需要注意的是:光流跟踪在②中完成,角点提取在⑥中完成

 

步骤2.2:判断是否需要显示畸变。

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

步骤3: 发布消息的数据

pub_img.publish(feature_points);

pub_match.publish(ptr->toImageMsg())

将处理完的图像信息用PointCloud实例feature_points和Image的实例ptr消息类型,发布到"feature"和"feature_img"的topic(此步骤在main函数中完成)

 

至此,已经将图像数据包装成特征点数据和图像数据发布出来了,下面就是在开一个线程,发布一个话题,接收这两种消息,也就是下面的vins_esitimate文件中做的事。

下面是具体的流程图:

 

二.Vins_estimate文件夹中

 

       下面到第二部分了,也是整个框架的重点和难点,估计要花很长的时间学习和总计理论知识和代码逻辑,这一部分还是从论文的理论知识讲起,然后再附上代码消化理解。     

         论文内容:

1.      论文第IV点的B部分IMU预积分,

IMU预积分的作用是计算出IMU数据的观测值(就是IMU预积分值)以及残差的协方差矩阵和雅各比矩阵,那就要清楚的明白为什么要计算这三个量?计算出这三个量为什么就可以和视觉观测值进行耦合?如果你现在回答不出来,请好好想一想自己以前学到的知识,关于视觉的这三个量,视觉中观测值是用来计算残差的(也就是误差),残差的雅各比矩阵是优化中下降的方向(也就是梯度),很少提及的协方差矩阵(但很重要)其实是观测值对应的权值(因为有很多观测值),现在是不是很清楚明白了?具体使用来说,这三个量为后面的联合初始化提供初值以及后端优化提供IMU的约束关系。原始陀螺仪和加速度计的观测值数据:

 

第一个式子等式左边是加速度测量值(你可以从加速度计中读到的值,带尖括号的是带误差的数据),等式右边是加速度真实值(其实就是准确的值,我们需要得到的是这个真实值)加上加速度计的偏置、重力加速度(注意是世界坐标系下)和加速度噪声项。第二个式子等式左边是陀螺仪测量值,等式右边是陀螺仪真实值加上陀螺仪偏置和陀螺仪噪声项。这里的值都是IMU(body)帧坐标系下的。这里假设噪声是服从高斯正态分布,而偏置服从随机游走模型。

         有上面最原始的式子积分就可以计算出下一时刻的p、v和q:

 

状态量上标代表的是所处的坐标系,下标是具体哪一帧数据。这里等式左边的值都是世界坐标系下(W)bk+1帧的值。从整个式子可以看出来这里的状态传播需要bk帧下的旋转,平移和速度,当这些开始的状态发生改变的时候,就需要重新传播IMU观测值,也就是说状态传播方程要重新计算和修改,我们想要一次性就求出bk和bk+1之间的状态传播,因此选用预积分模型(其实这里我也没有完全搞明白,但是有一点是明白的,这里是在世界坐标系下求解状态,但是由条件里需要世界坐标系下的旋转,明显冲突啊,因此可以使用预积分将世界坐标系下的状态转换到IMU的bk帧坐标系下,最初提出预积分的外国大佬是将世界坐标系转换到求状态的变化量,其实两者的原理都一样,预积分求的值都是变化量),两边同时乘以世界到bk帧坐标系的转换,如下图所示,然后提出等式右边只与加速度和角速度有关的量进行积分,如公式6:

 

到这里其实只要求出公式6中的积分值,真的预积分的值就得到了,这里bk是参考帧,从式6中可以看出,在bk到bk+1帧间,这里要求的三个临时状态量只与IMU的偏置有关系,而与其他状态无关,也就是说每个式子相当于一个二元一次方程(f(x,y)=ax+by+c,x相当于加速度计偏置,y相当于陀螺仪偏置),这里就是为了求解这个二元一次方程,当这里的偏置变化特别小的时候,我们可以使用一阶线性展开来调整临时状态量,这里提一下雅可比矩阵就是一阶偏导,如下公式12 所示:

 

所以要想求出这个临时的状态量,就必须求出等式右边的两部分值,第一个部分还是原来的积分形式(就像公式6那样),是预积分的主体,论文中使用的是最简单的欧拉积分法进行展开(取第i时刻值的斜率乘以时间差加上i时刻的初值,就得到i+1时刻的值),但是在代码中作者也提出了采用的是中值积分(顾名思义这里的斜率取得是i和i+1中点(2i+1)/2的时刻斜率).公式7是采用欧拉积分的结果。这里前面有一定的说明,一开始abkbk,bbkbk等是零,旋转是单位旋转,注意整个过程把噪声设为0。

 

 

 

         第二部分其实就是对应的一阶偏导(对加速度计偏置和陀螺仪偏置的),一阶偏导的求法在下面进行介绍,到这里我们已经求出了临时状态量的测量值,也就可以求出状态量测量值。

论文到这一步预积分其实已经做了一半了,也就是完成了测量值的求解,还差什么呢?当然是协方差矩阵了,下面重点求解协方差矩阵,顺便把上面没有求出的陀螺仪和加速度计偏置的雅各比矩阵求出来。

         如何求协方差矩阵呢?怎么从数学的定义里去求呢?这里要用到SLAM中的神作state estimation for robotic,建立一个线性高斯误差状态传播方程,由线性高斯系统的协方差,就可以推导出方程协方差矩阵了,也就是测量状态的协方差矩阵了。也就是说还是需要前面求解状态测量值的公式6。注意代码中真正求解公式6使用的是中值法,所以为了和代码中相一致,下面的求解过程我也才用中值法的方式,为求解需求我们先补充点干货:

首先需要将上面的四自由度的旋转转换成三个维度的状态量,这是由于四自由度的旋转存在过参数数化的情况,过参数化求解会需要引入额外的约束(单位四元数性质),因此将误差看成是一个扰动定义式8:

然后有下面的两张图定义出来离散状态下的预积分过程:

 

 

 

然后有下面的两张图定义出来离散状态下的预积分过程:

 

 

 

 

        最后得到图中的线性误差状态传播模型,由此得到IMU预积分测量值的协方差矩阵和雅各比矩阵,预积分的雅各比矩阵直接代入到公式12中计算出更加精确的传播状态值,而协方差矩阵自然是在后端优化中使用。

        需要格外注意上面求出的雅各比矩阵是预积分值的雅各比,我们还需要求一个IMU残差的雅各比矩阵,WHAT?还有两个雅各比矩阵,惊不惊喜意不意外?但情况确实如此,所以还不赶快从床上爬起来继续撸一把公式。上面求得的雅各比矩阵是用来计算预积分值时用到的,下面要求的IMU残差的雅各比矩阵是在紧耦合的时候做下降梯度,在最前面已经提到过。在求残差的雅各比之前,再提一下残差是如何计算的吧,预积分相当于测量值(就是真值,因为没有比这个更准确的值了,那当然就是真值了),要估计的状态就是估计值,所以预积分测量值减去状态估计值就是残差,在后面会提到需要估计的IMU估计值有p,v,q,ba,bg。P和q的估计值初始值比较好得到(和视觉相关,可以直接用视觉的初值),而v,ba,bg这三个量的估计值初始值就比较难得到了,因为视觉没有这三个初始量,就会用到下面的联合初始化得到初始的这三个量。下面直接上残差公式和要优化的状态量:

 

需要求解的残差雅各比矩阵是残差对估计状态量的一阶偏导,残差向量有三个,状态向量有2*5=10个。所以需要计算残差向量对状态向量的一阶偏导。首先需要提出的是对于偏置求偏导是比较复杂的,所以对于预积分的计算采取的是一阶泰勒展开,这样就相对简单了。也就是论文中的公式(12)。

(1)旋转四元数残差的雅各比矩阵

 

 

 

可以看出旋转四元数残差包含的状态量只有qi,qj,big这三个变量,也就是一个三元函数求偏导过程。

(2)速度残差的雅各比矩阵

未完待续,其实可以自己推导试试。

(3)位移残差的雅各比矩阵

未完待续,其实可以自己推到试试。

到这里恭喜你已经完成了数据前端处理的所有步骤,下面直接进入初始化的过程吧!

2.      基于滑动窗口的纯视觉单目初始化

在介绍纯视觉初始化前我们首先讲一讲为什么要初始化?初始化要做什么?以及初始化的作用?我们初始化的原因是单目惯性紧耦合系统是一个非线性程度很高的系统,首先单目是无法获得空间中的绝对尺度,而IMU又必然存在偏置,在后面进行求解的时候还需要用到重力加速度(包括大小和方向),对于速度比较敏感的条件下,比如说无人机,又要精确的速度信息,因此,如何有效的在紧耦合系统处理之前计算出这些量,对整个紧耦合系统的鲁棒性有着重大的意义(其实这里就可以理解成相机标定一样,没有正确的标定好相机的内参,相机在进行定位的时候必然不准,而且很有可能会挂掉)。所以初始化要做的事其实说起来很简单,就是计算出绝对尺度s、陀螺仪偏置bg、加速度偏置ba、重力加速度G和每个IMU时刻的速度v,VINS中重点说明了加速度计偏置值一般都会和重力加速度耦合到一起(也就是被重力加速度给吸收掉),重力加速度的量级要远大于其加速度偏置,而且在初始化时间内加速度计偏置比较小,很难真正的计算得到,因此忽略加速度计偏置的影响,在初始化中不再计算。初始化的作用是不言而喻的,直接影响整个紧耦合系统的鲁棒性以及定位精度,并且初始化一般都需要一个比较漫长的时间,VINS大概需要十秒左右,ORB_SLAM2结合IMU的时间设定在15秒完成初始化。话不多说,直接进入正题。

         纯视觉初始化在第V点的A部分,首先构建一个滑动窗口,包含一组数据帧。论文中提及使用的是对极几何模型的5点法求解单目相机的相对变换,包括相对旋转和无尺度信息的位移。其实基本上每个单目模型都是使用对极几何在初始化中求解两帧的相对变换,这里需要注意的是旋转是具有尺度不变性的(其实就是单位旋转,不会有尺度信息,你仔细想想是不是?),至于为什么单目没有尺度信息,我想罗嗦一句,但其实很多学习单目视觉SLAM的人都没有真正搞明白过,单目视觉没有尺度的源头是最开始两帧间的对极几何求位姿,再具体点就是求F/E或者H的时候需要将其降参一位,F从6维降到5维,H从9维降到8维,这里所降的维度就是尺度,而且必须要降。然后三角化得到相应的3d点坐标,有这些3d点和滑动窗口中其他的帧的2d点就可以进行PNP求解获得滑动窗口中的所有的位姿和特征点3d坐标,至此,纯视觉初始化就完成了。是不是很简单?当然啊,毕竟只是简单的视觉初始化,而真正复杂的是视觉惯性联合初始化,也就是我们初始化的重点和难点,所以下面的知识点一定要打起精神学啦!

 

3.      视觉惯性联合初始化

视觉惯性联合初始化在第V点的B部分,这里作者给定义的名字叫Visual-Inertia Alignment,即视觉惯性联合初始化(而在ORBSLAM2+IMU的论文里,作者定义的名称就叫IMU initialization,即IMU初始化),为什么定义这样一个名词,我觉得有两个意义,第一在进行陀螺仪偏置初始化的时候要同时使用到IMU测量的旋转和视觉测量的旋转,也就是要联合视觉和惯性的数据。第二这里求得的尺度S的值不仅仅是IMU的,还是视觉和IMU整个系统的尺度。在具体的讲解初始化每个过程的时候,有必要来个总体的概括,初始化在物理意义上的定义其实就是固有参数的标定,在数学模型上的定义其实就是公式(6)的矩阵方程求解,而公式(6)其实就是来自于最原始的PVQ积分公式,其中Q旋转对应着陀螺仪,而PV对应着加速度计,如果不明白的话,不要紧,看完下面的整体推导过程相信聪明的你一定会茅塞顿开。

(1)      陀螺仪偏置标定

旋转我们可以通过两种方式求得,一种是陀螺仪测量值,一种就是视觉观测值。按照正常的理解两者的大小一定是相等的(假设没有误差),但实际情况肯定有误差,我们就来看看各自的误差。陀螺仪的误差有两部分测量噪声和陀螺仪偏置,噪声暂时可以忽略(毕竟太小),而视觉的误差就只有观测噪声(也可以忽略不管),因此两者差值的绝对值就是陀螺仪偏置,将整个滑动窗口的所有的旋转做差构成了一个最小化误差模型:

公式15中第一个式子的第一项和第二项作四元数旋转的广义乘积就可以得到bk+1坐标系下相机从bk+1到bk下的相对旋转(相对bk+1),第三项是bk坐标系下陀螺仪从b到bk k+1下的相对旋转(相对bk),两者在做广义乘积,就是首先从bk到bk+1旋转,然后再从bk+1到bk旋转,相当于做差(OA+AO=0),第二个式子就是前面预积分提到的一阶线性近似。然后取最小二乘,当然也可以使用SVD分解等方法求解。注意在求得陀螺仪偏置之后要再次将陀螺仪偏置代入到预积分中再求一次预积分的值,会更加精确。

(2)      速度、重力加速度和尺度标定

作者在这里将这三个状态量统一到一个状态向量中,如公式16所示:

速度的是在bk坐标系下的,重力加速度在初始相机坐标系下,就像前面提到的,求解着几个量是由P、V数学模型求得,在滑动窗口中考虑到两个连续关键帧bk和bk+1,下面进行论文中公式17和19的推导:

 

 

 

公式推导之后就会得到论文中的公式17、18和19,我们重点关注下为什么要这样推导,以及推导得到的运动方程关系。首先为什么要进行这样的推导,这完全取决于状态向量的定义方式,我们最终要得到的方程形式左边一定是以状态向量的形式来表达的,而且还要满足其他量都是已知的(从IMU预积分和视觉跟踪得到),因此就需要将方程进行如此的变化,才能满足这样的关系。然后是最后的形式我们可以看到状态向量最终的形式维度是(n+1)*3+3+1,两个连续帧产生的运动方程的维度是3+3+3+1(vbkbk,vbk+1bk+1,gc0,s),gc0是第一个相机坐标系下的重力加速度,剩下的就是解最小二乘问题了,论文中采用的是快速的Cholesky分解。对于最小二乘求解这类方程如果有不懂的可以翻看我的另一篇博客,希望可以帮到你:

http://blog.csdn.net/wangshuailpp/article/details/80209863

(3)      重力优化

上面其实已经得到了重力加速度的大小和方向,这里为什么还需要对重力进行优化呢?理由很简单,这里计算的重力吸收了重力加速度计的偏置,虽然不需要计算重力加速度计的偏置,但重力还是需要优化的,说到优化重力加速度,肯定包含两个量,大小和方向,也就是三个维度,但是一般来说大小是确定已知的(这里设为9.8),因此其实我们要做的就是优化方向,是一个两维的向量,下图是优化重力的方法以及b1,b2单位向量的方向确定模型。

 

 

4.      基于滑动窗口的单目视觉紧耦合后端优化模型

终于讲到了真正的视觉惯性紧耦合系统了,(在这里插一句,算是写博客和学习一个SLAM系统的心得吧,一开始我们可能抱着一个必胜的心态打算征服所有的知识点和难点,但到了整个过程的中期,总会出现或多或少的问题,阻碍着我们前进的步伐,你可能想放松警惕,不想太深究具体的公式和内容,急功心切的想看到终点到底是什么,但是我要提醒大家,也包括自己,最美好的以及最有价值的永远是过程,是在过程中学到的可以为一生所用的经验,只是一味着冲到终点,而忘记了过程,你最终会发现得到的只有失望。如果你不想失望的话,那就再接再厉,给自己继续加油吧!)到这里才是整个系统的重点,前面所有提及的其实都是松耦合方式,目的是给整个系统提供优化初值和状态。视觉惯性紧耦合优化模型在第VI部分,我理解的紧耦合系统是将视觉和惯性的原始观测量进行有效的组合,也就是在数据处理前就进行数据融合,VINS中是将滑动窗口内的状态量整合到一个状态向量中,如公式21所示:

 

 

 

第一个式子是滑动窗口内整个状态向量,其中n是帧数,m是滑动窗口中的特征点总数,维度是15*n+6+m,第二个式子xk是在第k帧图像捕获到的IMU状态,包括位姿,速度,旋转,加速度计和陀螺仪偏置,第三个式子是相机外参,λ是特征点深度值得逆(大家一定会问,问什么这里只用特征点深度值的逆,也就是逆深度,主要是考虑稳定和满足高斯系统,不懂得可以参考高博的十四讲)。从状态向量就可以看出xk只与IMU项以及Marginalization有关,特征点的深度值只与camera和Marginalization有关,所以下面建立BA紧耦合模型的时候按照这个思路,下面建立一个视觉惯性的BA优化模型以及鲁棒核函数模型:

 

从公式中可以明显的看出来,BA优化模型被分成了三个部分,分别是Marginalization(边缘化)残差部分(从滑动窗口中去掉的位姿和特征点的约束),IMU残差部分(滑动窗口中相邻帧间的IMU产生)和视觉代价误差函数部分(滑动窗口中特征点在相机下的投影产生),其中鲁棒核函数针对代价函数设定(具体作用请参见视觉SLAM十四讲)。下面具体介绍着三个部分。

 

(1)  IMU观测值残差

考虑到的是两个连续帧bk和bk+1之间的观测值,与前面的预积分模型相同,如公式24所示,还记得在IMU预积分的时候求得到协方差矩阵和观测值吗?那里求得的观测值就是测量值,协方差矩阵就是这里的协方差矩阵,而公式24前面的项就是预测的值,也称估计值,估计值和测量值之间的差值就是残差,其实这里的公式24是由公式5的右边左移得到,你发现了吗?

 

(2)  视觉观测值残差

与传统的针孔相机模型定义的重投影误差不同,论文中使用的是单位半球体的相机观测残差,是一个宽视野鱼眼或者全方位相机。相机的残差模型如下公式25所示:

 

第一个式子就是残差的表达式,第二个式子是鱼眼相机反投影函数将观测到的像素坐标转换成单位向量的观测值数据,b1和b2是此单位向量的切平面上的一组基。第三个式子是重投影估计模型。其实VINS代码中也可以使用普通的针孔相机模型。

 

(3)  Marginalization

这一部分借鉴博客:http://blog.csdn.net/q597967420/article/details/76099443

sliding windowsbounding边界化了优化问题中pose的个数, 从而防止pose和特征的个数随时间不断增加, 使得优化问题始终在一个有限的复杂度内, 不会随时间不断增长。然而, 将pose移出windows时, 有些约束会被丢弃掉, 这样势必会导致求解的精度下降, 而且当MAV进行一些退化运动(如: 匀速运动)时, 没有历史信息做约束的话是无法求解的. 所以, 在移出位姿或特征的时候, 需要将相关联的约束转变成一个约束项作为prior放到优化问题中. 这就是marginalization要做的事情。

         VINS-MONO中,为了处理一些悬停的case,引入了一个two-way marginalization, 简单来说就是:如果倒数第二帧是关键帧, 则将最旧的pose移出sliding window, 将最旧帧相关联的视觉和惯性数据边缘化掉,也就是MARGIN_OLD,作为一部分先验值,如果倒数第二帧不是关键帧, 则将倒数第二帧pose移出sliding window,将倒数第二帧的视觉观测值直接舍弃,保留相关联的IMU数据, 也就是MARGIN_NEW。选取关键帧的策略是视差足够大,在悬停等运动较小的情况下, 会频繁的MARGIN_NEW, 这样也就保留了那些比较旧但是视差比较大的pose. 这种情况如果一直MARGIN_OLD的话, 视觉约束不够强, 状态估计会受IMU积分误差影响, 具有较大的累积误差。

到这里整体VINS理论的框架基本上算是介绍完毕了,对于后面的重定位,全局位姿优化和回环检测等有时间再做下讨论,现在有没有一个比较清晰的思路?如果还比较困惑的话,那就赶紧进行下面的代码实战环节吧。下面就从代码角度来分析VINS的整个第二部分。

 

(4)单目视觉雅可比计算(参考贺大佬)

视觉SLAM十四讲中第162页有提到,将空间坐标系下的3D点投影到像素坐标系下做最小二乘,求出该最小二乘模型的雅各比矩阵既可以得到高斯牛顿或者LM方法的下降梯度,从而优化位姿和路标点,具体的内容请参照书本。需要注意的是VINS在计算视觉雅各比时与书上有三点不同:

①VINS中由feature_tracker传过来的像素点坐标吸收了内参K且做了归一化,因此是吸收内参的归一化图像坐标。

②VINS中使用Q旋转四元数来优化位姿,因此在计算位姿对应的雅各比矩阵时和书上的公式不完全相同。

③VINS是基于滑动窗口,优化的位姿包含滑动窗口中的11帧位姿,但同时是依靠特征点来确定所优化哪两帧的位姿,每次传入视觉残差模型是遍历特征点来确定的,设定i帧为最开始观测到次特征点的相机,则j(不等于i)就为其他共视关键帧。

4.1视觉j帧残差计算(其实也可以计算i帧残差,过程基本相似)

明白上面三个不同点就可以进行下面的公式推导了,首先下图是残差计算模型,VINS选取的是j帧图像的残差计算模型。

 

4.2整体雅各比公式

传入到上面的j帧视觉残差模型的优化状态量分别是7维的i帧位姿,7维的j帧位姿,7维的相机和IMU外参数以及1为的特征点逆深度。因此需要计算的雅各比如下图所示:

 

 

 

VINS系统的所有结果的参考坐标都是世界坐标,同时都是对应IMU时刻在世界坐标系下的旋转,平移,速度等,而且逆深度的值时相对于i时刻的相机,因此我们需要整理4.1得到的i时刻的关键帧对应到j时刻的归一化相机坐标Pj的重投影方程如下图所示:(我们需要求的是Pj对于i、j时刻关键帧,相机外参以及i时刻的逆深度,所以需要构建这样一个重投影方程,才能满足偏导数求解)

由最终的公式可以看到Pj由i,j时刻的位姿(旋转和平移),相机外参(旋转和平移)以及逆深度表示,下面可以直接求雅各比(偏导数)。

4.3视觉i帧的状态量(位移和旋转)在Pj下的雅各比

这里和视觉SLAM十四讲中有出入,但是解算原理基本相同,利用了旋转四元数和差乘的性质。得到下面的偏导后整个J[0]就可以相乘得到了。

 

4.4视觉j帧的状态量、相机和IMU之间外参数(位移和旋转)在Pj下的雅各比

这里的雅各比推导过程就不重复了,和上面的过程相似,就直接给结果了

 

4.6特征点你深度在Pj下的雅各比

逆深度求偏导就比较简单了,就是一个反函数求偏导过程,得到下面的偏导后整个J[3]就可以相乘得到了。

 

至此,整个基于滑动窗口的视觉残差和雅各比模型就完成了。其协方差矩阵较为简单,代码中直接赋值即可,不需要计算。

 

         第二部分的系统入口是estimator_node.cpp,(整体介绍未完待续)

 

1.      estimator_node.cpp系统入口

首先初始化设置节点vins_estimator,同时读取参数和设置相应的参数,为节点发布相应的话题,为节点订阅三个话题,分别用来接收和保存IMU数据、图像特征数据和原始图像数据,分别是在三个回调函数中imu_callback、feature_callback和raw_image_callback,每当订阅的节点由数据送过来就会进入到相应的回调函数中。

(1)      接收IMU数据

imu_callback函数中首先执行imu_buf.push(imu_msg);将IMU数据保存到imu_buf中,同时执行con.notify_one();唤醒作用于process线程中的获取观测值数据的函数,这里唤醒以及互斥锁的作用很重要到下面真正要使用的时候在详细讨论,然后预测未考虑观测噪声的p、v、q值,同时将发布最新的IMU测量值消息(pvq值),这里计算得到的pvq是估计值,注意是没有观测噪声和偏置的结果,作用是与下面预积分计算得到的pvq(考虑了观测噪声和偏置)做差得到残差。

(2)      接收原始图像和图像特征点数据

feature_callback和raw_image_callback函数中主要是将特征数据和原始图像数据分别保存到feature_buf和image_buf中,在feature_callback也用到了con.notify_one()和互斥锁;。

2.      process()处理观测值数据线程

(1)      得到观测值(IMU数据和图像特征点数据)

定义观测值数据类measurements,包含了一组IMU数据和一帧图像数据的组合的容器,这里比较有意思的是使用了互斥锁和条件等待的功能,互斥锁用来锁住当前代码段,条件等待是等待上面两个接收数据完成就会被唤醒,然后从imu_buf和feature_buf中提取观测数据measurements = getMeasurements(),需要注意的是在提取观测值数据的时候用到的互斥锁会锁住imu_buf和feature_buf等到提取完成才释放,也就是说在提取的过程中上面两个回调函数是无法接收数据的,同时上面两个回调函数接收数据的时候也使用了互斥锁,锁住了imu_buf和feature_buf,这里也不能提取imu_buf和feature_buf中的数据。因此整个数据获取的过程是:回调函数接收数据,接收完一组数据唤醒提取数据的线程,提取数据的线程提取完数据后,回调函数就可以继续接收数据,依次往复。这就是线程间通信的曼妙啊!

1)  getMeasurements()返回观测值数据

函数的作用顾名思义,就是得到一组IMU数据和图像特征数据组合的容器。首先保证存在IMU数据和图像特征数据,然后还要判断图像特征数据和IMU数据是否对齐。这里使用的是队列数据结构(先进先出front是先进的数据,back是后进的数据),需要满足两个条件就能保证数据对齐,第一是IMU最后一个数据的时间要大于图像特征最开始数据的时间,第二是IMU最开始数据的时间要小于图像特征最开始数据的时间。满足数据对齐就可以数据从队列中按对齐的方式取出来。这里知道把缓存中的图像特征数据或者IMU数据取完,才能够跳出此函数,返回数据。

(2)      处理IMU数据和图像特征数据

步骤1:处理IMU数据

遍历调用send_imu(imu_msg)将单个IMU数据的dt,线加速度值和角加速度值计算出来送给优化器处理,优化器调用estimator.processIMU(dt, Vector3d(dx, dy, dz), Vector3d(rx, ry,rz));方法。

1)Estimator::processIMU(doubledt, const Vector3d &linear_acceleration, const Vector3d&angular_velocity)处理IMU数据方法

步骤1调用imu的预积分,调用push_back函数,函数中将时间,加速度和角速度分别存入相应的缓存中,同时调用了propagation函数 ,计算对应的状态量、协方差和雅可比矩阵

①propagate(double _dt, const Eigen::Vector3d &_acc_1, constEigen::Vector3d &_gyr_1)

预积分传播方程,在预积分传播方程propagate中使用中点积分方法midPointIntegration计算预积分的测量值,中点积分法中主要包含两个部分,分别是得到状态变化量result_delta_q,result_delta_p,result_delta_v,result_linearized_ba,result_linearized_bg和得到跟新协方差矩阵和雅可比矩阵(注意,虽然得到了雅各比矩阵和协方差矩阵,但是还没有求残差和修正偏置一阶项的状态变量),由于使用的是中点积分,所以需要上一个时刻的IMU数据,包括测量值加速度和角速度以及状态变化量,初始值由构造函数提供。需要注意的是这里定义的delta_p等是累积的变化量,也就是说是从i时刻到当前时刻的变化量,这个才是最终要求的结果(为修正偏置一阶项),而result_delta_q等只是一个暂时的变量,最后残差和雅可比矩阵、协方差矩阵保存在pre_integrations中,还有一个函数这里暂时还没有用到,是在优化的时候才被调用的,但是其属于预积分的内容,evaluate函数在这个函数里面进行了状态变化量的偏置一阶修正以及残差的计算。

步骤2预积分公式(3)未考虑误差,提供imu计算的当前旋转,位置,速度,作为优化的初值

步骤2:处理图像特征数据

这里进来的数据不是图像数据哦,而是前面已经跟踪匹配好的归一化平面坐标。将当前帧的特征存放在image中,image的第一个元素类型是特征点的编号,第二个元素是相机编号,第三个是特征点坐标,然后直接进入到处理图像特征数据的线程中estimator.processImage(image, img_msg->header)。

1)Estimator::processImage(constmap<int, vector<pair<int, Vector3d>>> &image, conststd_msgs::Header &header)处理图像特征数据方法

         首先对进来的图像特征数据根据视差判断是否是关键帧,选择丢弃当前帧(但保留IMU数据)或者丢弃滑动窗口中最老的一帧。

步骤1:将图像数据和时间存到图像帧类中:首先将数据和时间保存到图像帧的对象imageframe中(ImageFrame对象中包含特征点,时间,位姿R,t,预积分对象pre_integration,是否是关键帧),同时将临时的预积分值保存到此对象中(这里的临时预积分初值就是在前面IMU预积分的时候计算的),然后将图像帧的对象imageframe保存到all_image_frame对象中(imageframe的容器),更新临时预积分初始值。

步骤2:标定相机和IMU的外参数:接着如果没有外部参数就标定外部参数,参数传递有的话就跳过这一步(默认有,如果是自己的设备,可以设置为2对外参进行在线标定)。

步骤3:初始化系统同时进行BA优化:当求解器处于可初始化状态时(初始状态是可初始化,初始化成功就设置为不可初始化状态),判断当前frame_count是否达到WINDOW_SIZE,确保有足够的frame参与初始化,这里的frame_count是滑动窗口中图像帧的数量,一开始被初始化为0,滑动窗口总帧数是10。有外部参数同时当前帧时间戳大于初始化时间戳0.1秒,就进行初始化操作。

步骤3.1:initialStructure()系统初始化,首先初始化Vision-only SFM,然后初始化Visual-Inertial Alignment,构成整个初始化过程。

①保证IMU充分运动,通过线加速度判断,一开始通过线加速度的标准差(离散程度)判断保证IMU充分运动,加速度标准差大于0.25则代表imu充分激励,足够初始化。

②纯视觉初始化,对SlidingWindow中的图像帧和相机姿态求解sfm问题,这里解决的是关键帧的位姿和特征点坐标。

步骤1.首先构建SFMFeature对象sfm_f,SFMFeature数组中包含了特征点状态(是否被三角化),id,2d点,3d坐标以及深度,将特征管理器中的特征信息保存到SFMFeature对象sfm_f中sfm_f.push_back(tmp_feature)。

步骤2.接着由对极约束中的F矩阵恢复出R、t,主要调用方法relativePose(relative_R, relative_T, l)。relativePose方法中首先通过FeatureManeger获取(滑动窗口中)第i帧和最后一帧的特征匹配corres,当corres匹配足够大时,考察最新的keyFrame和slidingwindow中某个keyFrame之间有足够feature匹配和足够大的视差(id为l=i),满足这两个条件,然后这两帧之间通过五点法恢复出R,t并且三角化出3D的特征点feature point,这里是使用solveRelativeRT(corres, relative_R, relative_T),solveRelativeRT方法定义在solv_5pts.cpp类中,由对极约束中的F矩阵恢复出R、t,直接调用opencv中的方法,没什么好说的,这里值得注意的是,这种relativePose得到的位姿是第l帧的,第l帧的筛选是从第一帧开始到滑动窗口所有帧中一开始满足平均视差足够大的帧,这里的第l帧会作为参考帧到下面的全局SFM使用。到这里就已经得到图像的特征点2d坐标的提取,相机第l帧和最后一帧之间的旋转和平移(注意暂时还没有得到特征的3d点坐标),有了这些信息就可以构建全局的SFM类GlobalSFM sfm,在这里调用sfm.construct(frame_count + 1, Q, T, l,relative_R, relative_T,sfm_f,sfm_tracked_points),这里以第l帧作为参考帧,在进行PNP求解之前,需要判断当前帧数要大于第l帧,这保证了第l帧直接跳过PNP步骤,首先执行下面的第l帧和最后一帧的三角化,得到共视的特征点,供下面第l+1帧和最后一帧求解PNP,然后利用pnp求解l+1帧到最后一帧的位姿R_initial,P_initial,最后的位姿都保存在Pose中,一次循环,得到l+1,l+2…n-1帧的位姿。跳出步骤2 的循环后,至此得到了l+1,l+2…n-1帧的位姿以及l+1,l+2…帧与n-1帧的特征点三角化。然后再三角化l帧和i帧(在第l帧和最后一帧之间的帧)之间的3d坐标,(这里不明白为什么要做两次,是可以三角化出更多的特征点吗????),接着PNP求解l-1,l-2…0帧和l帧之间的位姿已经三角化相应的特征点坐标,最后三角化其他所有的特征点。至此得到了滑动窗口中所有相机的位姿以及特征点的3d坐标。第6部就是进行BA优化,使用的是ceres优化位姿和特征点,这里可以参考视觉SLAM第十讲中的内容,优化方式相同。

步骤4:visualInitialAlign中调用VisualIMUAlignment方法,真正的视觉惯性联合初始化,imu与视觉对齐,获取绝对尺度等。这个方法定义在initial/initial_alignment.h中。

步骤4.1:solveGyroscopeBias计算陀螺仪偏置,整个方法的计算模型由论文中给出,使用LTLD方法求解最小二乘问题,delta_bg = A.ldlt().solve(b);这里A +=tmp_A.transpose() * tmp_A,b += tmp_A.transpose() * tmp_b,其实就是处理AT*A*x=AT*b问题,一般的最小二乘问题直接处理Ax=b也就是Ax-b=0即可,这里是使用LDLT方法,两边同乘以A矩阵的转置得到的AT*A一定是可逆的,因此就可以直接两边同乘以其逆即可,相应的说明详见LDLT方法。得到陀螺仪偏置之后将其值保存到前面定义的Bgs[]中,最后在重新计算一次预积分。

步骤4.2:LinearAlignment计算尺度,重力加速度和速度。论文中给出的公式是相邻两个速度的模型,映射到整个n+1个速度模型中,A矩阵一定是一个正定矩阵(实对称矩阵),代码中定义的A和b即是最总的H和b,tmp_A和tmp_b相邻速度间的临时变量。最后的求解方法:x = A.ldlt().solve(b);然后调用RefineGravity重新计算重力加速度方向,得到最优解。

步骤4.3:将所有的状态量由相机坐标C0转换到世界坐标W下,这里世界坐标系的定义是根据重力加速度的方向和初始相机C0坐标系的方向定义的R0 = Utility::ypr2R(Eigen::Vector3d{-yaw, 0, 0}) * R0; 定义的rot_diff就是坐标旋转矩阵q_wc0。最后将Ps[i]、Rs[i]和Vs[i]由相机C0坐标系旋转到定义的世界坐标下,这里需要说明,一般的SLAM系统世界坐标系即是C0坐标系,这里自定义了一个世界坐标系,那么最后得到的结果都是以这个世界坐标系为参考,如果想要和真值进行比较就需要注意坐标系问题了。

2)  基于滑动窗口的紧耦合优化

这部分主要是在solveOdometry()和slideWindow()方法中,当初始化完成后就会调用这两个方法。

步骤1:solveOdometry()进行BA优化,在内部调用了BA优化的方法optimization()

步骤1.未完待续

 

 

查看全文
如若内容造成侵权/违法违规/事实不符,请联系编程学习网邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

相关文章

  1. 前后端分离开发技术的一些思考

    在网站开发过程中&#xff0c;对于前后端的分界线似乎一直是众说纷纭。从一开始完全没有前后端的概念&#xff0c;到后来的纠缠不清。 传统的分离方法 在我的脑海中一提到前端和后端&#xff0c;基本上第一个出现的区别点就是:后端是跟数据库跟服务器打交道的&#xff0c;前端…...

    2024/4/21 13:13:42
  2. SegmentFault 技术周刊 Vol.1 - Vue.js 起手式

    优质阅读感受及更多讨论&#xff0c;请查看原文&#xff1a; https://segmentfault.com/a/1190000006579616 2014 年 3 月&#xff0c;Vue.js 0.10 发布&#xff0c;10 月开始逐渐被大范围发现使用&#xff0c;12 月 SegmentFault 社区内出现第一篇关于 Vue.js 的文章&#xf…...

    2024/4/21 13:13:40
  3. 前端技术浪潮与应用

    前端技术浪潮与应用 文章目录前端技术浪潮与应用一、前端基建01.前端可视化01-1.页面可视化搭建①页面可视化背景-前端行业提效分析②业界-前端行业提效轮子&#xff1a;[前端可视化搭建工具业界的轮子](https://juejin.im/post/6858881797490098190)③背景-提效轮子总结归纳④…...

    2024/4/21 13:13:39
  4. 与国内外六位前端专家周末相约,共讨前端技术难点与创新实践

    由CSDN全力打造的“前端开发创新实践”线上峰会将于7月8日&#xff08;周六&#xff09;召开。峰会邀请到多位国内外知名企业前端技术专家&#xff0c;共话当前主流、热门前端技术&#xff0c;分享企业优秀前端项目研发实践。 本峰会已邀请到来自Smashing Magazine、美国Hulu、…...

    2024/4/21 13:13:37
  5. web前端入门到实战:12个HTML和CSS必须知道的重点难点问题

    这12个问题&#xff0c;基本上就是HTML和CSS基础中的重点难点了&#xff0c;也是必须要弄清楚的基本问题&#xff0c;其中定位的绝对定位和相对定位到底相对什么定位&#xff1f;这个还是容易被忽视的&#xff0c;浮动也是一个大坑&#xff0c;有很多细节。这12个知识点是我个人…...

    2024/4/21 13:13:37
  6. 极乐技术周报(第二十期)

    栈和队列的区别是啥?吃多了拉就是队列;吃多了吐就是栈 1.Spring Boot 配置大全 Spring Boot 配置大全 链接地址 2.HTTP/2的历史、特性、调试、性能 相比之前的传输协议&#xff0c;HTTP/2在底层方面做了很多优化。有安全、省时、简化开发、更好的适应复杂页面、提供缓存利用…...

    2024/4/21 13:13:37
  7. 妈妈给的双眼皮用的什么技术

    ...

    2024/4/21 13:13:34
  8. react源代码重点难点分析

    网上已经有不少react源码分析文档&#xff0c;但都是分析主流程和主要功能函数&#xff0c;没有一个是从reactDOM.render()入口开始分析源码把流程逻辑走通尤其是把重点难点走通直到把组件template编译插入网页生效结束这样一个从头到尾的完整过程。本文从ReactDom.Render()入口…...

    2024/4/21 13:13:33
  9. Echarts数据可视化grid直角坐标系(xAxis、yAxis)详解:

    mytextStyle={color:"#333", //文字颜色fontStyle:"normal", //italic斜体 oblique倾斜fontWeight:"normal", //文字粗细bold bolder lighter 100 | 200 | 300 | 400...fontFamily:"sans-serif",…...

    2024/4/24 18:49:57
  10. 网校系统开发会用到哪些技术?

    网校系统开发作为当下比较火热的领域&#xff0c;备受资本主义市场的青睐。虽然现如今已经有不少教培机构捷足先登&#xff0c;试水该领域&#xff0c;但是对于新手来说&#xff0c;还是一头雾水&#xff0c;不清楚开发网校系统需要用到哪些专业技术。今天&#xff0c;我们就来…...

    2024/4/21 13:13:32
  11. 双眼皮全切手术多长时间恢复

    ...

    2024/4/28 1:19:06
  12. 双眼皮手术价格表多少钱知金宪俊

    ...

    2024/4/21 13:13:29
  13. angular学习笔记(三)-视图绑定数据的两种方式

    绑定数据有两种方式: <!DOCTYPE html> <html ng-app> <head><title>2.2显示文本</title><meta charset"utf-8"><script src"../angular.js"></script><script src"script.js"></scrip…...

    2024/4/20 16:04:17
  14. js覆盖less全局变量_JS 引擎 V8 发布 v7.4,性能又大幅提高了

    JS 引擎 V8 发布 v7.4详情&#xff1a;https://v8.dev/blog/v8-release-74目前处于 beta 阶段&#xff0c;正式版将于几个星期后与 Chrome 74 Stable 一起发布。此版本带来了一些新特性&#xff0c;并极大提升了性能&#xff1a;V8 现在不需要运行时分配可执行内存就可以执行 J…...

    2024/4/20 16:04:15
  15. 割双眼皮多久之后可以接睫毛

    ...

    2024/4/25 4:08:22
  16. 全切双眼皮开外眼角的利弊

    ...

    2024/4/20 16:04:13
  17. 做双眼皮术需要恢复多久

    ...

    2024/4/28 0:02:58
  18. 双眼皮内眼角提肌要多长时间

    ...

    2024/4/21 13:13:28
  19. 割完双眼皮多久可以睫毛嫁接

    ...

    2024/4/21 13:13:26
  20. 做三点双眼皮手术要多久才能恢复

    ...

    2024/4/21 13:13:25

最新文章

  1. wps用js宏给文档增加用户名密码验证

    偶然看见别人一个给office文档增加验证的vba教程&#xff0c;觉得很有意思&#xff0c;就打开wps验证了一下 wps在windows版本支持vba和js&#xff0c;js默认&#xff0c;vba需要自己下载相关插件折腾&#xff0c;linux版本wps个人版默认没有支持2次开发的高级功能&#xff0c…...

    2024/5/3 14:57:44
  2. 梯度消失和梯度爆炸的一些处理方法

    在这里是记录一下梯度消失或梯度爆炸的一些处理技巧。全当学习总结了如有错误还请留言&#xff0c;在此感激不尽。 权重和梯度的更新公式如下&#xff1a; w w − η ⋅ ∇ w w w - \eta \cdot \nabla w ww−η⋅∇w 个人通俗的理解梯度消失就是网络模型在反向求导的时候出…...

    2024/3/20 10:50:27
  3. Java深度优先搜索DFS(含面试大厂题和源码)

    深度优先搜索&#xff08;Depth-First Search&#xff0c;简称DFS&#xff09;是一种用于遍历或搜索树或图的算法。DFS 通过沿着树的深度来遍历节点&#xff0c;尽可能深地搜索树的分支。当节点v的所在边都已被探寻过&#xff0c;搜索将回溯到发现节点v的那条边的起始节点。这个…...

    2024/5/3 10:02:23
  4. JVM总结

    类加载器与类的加载过程 ClassLoader只负责class文件的加载&#xff0c;至于它是否可以运行&#xff0c;则由Execution Engine决定。 加载阶段 通过一个类的全限定名获取定义此类的二进制字节流 将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构 在内存中生成…...

    2024/5/2 2:32:37
  5. 【外汇早评】美通胀数据走低,美元调整

    原标题:【外汇早评】美通胀数据走低,美元调整昨日美国方面公布了新一期的核心PCE物价指数数据,同比增长1.6%,低于前值和预期值的1.7%,距离美联储的通胀目标2%继续走低,通胀压力较低,且此前美国一季度GDP初值中的消费部分下滑明显,因此市场对美联储后续更可能降息的政策…...

    2024/5/1 17:30:59
  6. 【原油贵金属周评】原油多头拥挤,价格调整

    原标题:【原油贵金属周评】原油多头拥挤,价格调整本周国际劳动节,我们喜迎四天假期,但是整个金融市场确实流动性充沛,大事频发,各个商品波动剧烈。美国方面,在本周四凌晨公布5月份的利率决议和新闻发布会,维持联邦基金利率在2.25%-2.50%不变,符合市场预期。同时美联储…...

    2024/5/2 16:16:39
  7. 【外汇周评】靓丽非农不及疲软通胀影响

    原标题:【外汇周评】靓丽非农不及疲软通胀影响在刚结束的周五,美国方面公布了新一期的非农就业数据,大幅好于前值和预期,新增就业重新回到20万以上。具体数据: 美国4月非农就业人口变动 26.3万人,预期 19万人,前值 19.6万人。 美国4月失业率 3.6%,预期 3.8%,前值 3…...

    2024/4/29 2:29:43
  8. 【原油贵金属早评】库存继续增加,油价收跌

    原标题:【原油贵金属早评】库存继续增加,油价收跌周三清晨公布美国当周API原油库存数据,上周原油库存增加281万桶至4.692亿桶,增幅超过预期的74.4万桶。且有消息人士称,沙特阿美据悉将于6月向亚洲炼油厂额外出售更多原油,印度炼油商预计将每日获得至多20万桶的额外原油供…...

    2024/5/2 9:28:15
  9. 【外汇早评】日本央行会议纪要不改日元强势

    原标题:【外汇早评】日本央行会议纪要不改日元强势近两日日元大幅走强与近期市场风险情绪上升,避险资金回流日元有关,也与前一段时间的美日贸易谈判给日本缓冲期,日本方面对汇率问题也避免继续贬值有关。虽然今日早间日本央行公布的利率会议纪要仍然是支持宽松政策,但这符…...

    2024/4/27 17:58:04
  10. 【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响

    原标题:【原油贵金属早评】欧佩克稳定市场,填补伊朗问题的影响近日伊朗局势升温,导致市场担忧影响原油供给,油价试图反弹。此时OPEC表态稳定市场。据消息人士透露,沙特6月石油出口料将低于700万桶/日,沙特已经收到石油消费国提出的6月份扩大出口的“适度要求”,沙特将满…...

    2024/4/27 14:22:49
  11. 【外汇早评】美欲与伊朗重谈协议

    原标题:【外汇早评】美欲与伊朗重谈协议美国对伊朗的制裁遭到伊朗的抗议,昨日伊朗方面提出将部分退出伊核协议。而此行为又遭到欧洲方面对伊朗的谴责和警告,伊朗外长昨日回应称,欧洲国家履行它们的义务,伊核协议就能保证存续。据传闻伊朗的导弹已经对准了以色列和美国的航…...

    2024/4/28 1:28:33
  12. 【原油贵金属早评】波动率飙升,市场情绪动荡

    原标题:【原油贵金属早评】波动率飙升,市场情绪动荡因中美贸易谈判不安情绪影响,金融市场各资产品种出现明显的波动。随着美国与中方开启第十一轮谈判之际,美国按照既定计划向中国2000亿商品征收25%的关税,市场情绪有所平复,已经开始接受这一事实。虽然波动率-恐慌指数VI…...

    2024/4/30 9:43:09
  13. 【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试

    原标题:【原油贵金属周评】伊朗局势升温,黄金多头跃跃欲试美国和伊朗的局势继续升温,市场风险情绪上升,避险黄金有向上突破阻力的迹象。原油方面稍显平稳,近期美国和OPEC加大供给及市场需求回落的影响,伊朗局势并未推升油价走强。近期中美贸易谈判摩擦再度升级,美国对中…...

    2024/4/27 17:59:30
  14. 【原油贵金属早评】市场情绪继续恶化,黄金上破

    原标题:【原油贵金属早评】市场情绪继续恶化,黄金上破周初中国针对于美国加征关税的进行的反制措施引发市场情绪的大幅波动,人民币汇率出现大幅的贬值动能,金融市场受到非常明显的冲击。尤其是波动率起来之后,对于股市的表现尤其不安。隔夜美国股市出现明显的下行走势,这…...

    2024/5/2 15:04:34
  15. 【外汇早评】美伊僵持,风险情绪继续升温

    原标题:【外汇早评】美伊僵持,风险情绪继续升温昨日沙特两艘油轮再次发生爆炸事件,导致波斯湾局势进一步恶化,市场担忧美伊可能会出现摩擦生火,避险品种获得支撑,黄金和日元大幅走强。美指受中美贸易问题影响而在低位震荡。继5月12日,四艘商船在阿联酋领海附近的阿曼湾、…...

    2024/4/28 1:34:08
  16. 【原油贵金属早评】贸易冲突导致需求低迷,油价弱势

    原标题:【原油贵金属早评】贸易冲突导致需求低迷,油价弱势近日虽然伊朗局势升温,中东地区几起油船被袭击事件影响,但油价并未走高,而是出于调整结构中。由于市场预期局势失控的可能性较低,而中美贸易问题导致的全球经济衰退风险更大,需求会持续低迷,因此油价调整压力较…...

    2024/4/26 19:03:37
  17. 氧生福地 玩美北湖(上)——为时光守候两千年

    原标题:氧生福地 玩美北湖(上)——为时光守候两千年一次说走就走的旅行,只有一张高铁票的距离~ 所以,湖南郴州,我来了~ 从广州南站出发,一个半小时就到达郴州西站了。在动车上,同时改票的南风兄和我居然被分到了一个车厢,所以一路非常愉快地聊了过来。 挺好,最起…...

    2024/4/29 20:46:55
  18. 氧生福地 玩美北湖(中)——永春梯田里的美与鲜

    原标题:氧生福地 玩美北湖(中)——永春梯田里的美与鲜一觉醒来,因为大家太爱“美”照,在柳毅山庄去寻找龙女而错过了早餐时间。近十点,向导坏坏还是带着饥肠辘辘的我们去吃郴州最富有盛名的“鱼头粉”。说这是“十二分推荐”,到郴州必吃的美食之一。 哇塞!那个味美香甜…...

    2024/4/30 22:21:04
  19. 氧生福地 玩美北湖(下)——奔跑吧骚年!

    原标题:氧生福地 玩美北湖(下)——奔跑吧骚年!让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 让我们红尘做伴 活得潇潇洒洒 策马奔腾共享人世繁华 对酒当歌唱出心中喜悦 轰轰烈烈把握青春年华 啊……啊……啊 两…...

    2024/5/1 4:32:01
  20. 扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!

    原标题:扒开伪装医用面膜,翻六倍价格宰客,小姐姐注意了!扒开伪装医用面膜,翻六倍价格宰客!当行业里的某一品项火爆了,就会有很多商家蹭热度,装逼忽悠,最近火爆朋友圈的医用面膜,被沾上了污点,到底怎么回事呢? “比普通面膜安全、效果好!痘痘、痘印、敏感肌都能用…...

    2024/4/27 23:24:42
  21. 「发现」铁皮石斛仙草之神奇功效用于医用面膜

    原标题:「发现」铁皮石斛仙草之神奇功效用于医用面膜丽彦妆铁皮石斛医用面膜|石斛多糖无菌修护补水贴19大优势: 1、铁皮石斛:自唐宋以来,一直被列为皇室贡品,铁皮石斛生于海拔1600米的悬崖峭壁之上,繁殖力差,产量极低,所以古代仅供皇室、贵族享用 2、铁皮石斛自古民间…...

    2024/4/28 5:48:52
  22. 丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者

    原标题:丽彦妆\医用面膜\冷敷贴轻奢医学护肤引导者【公司简介】 广州华彬企业隶属香港华彬集团有限公司,专注美业21年,其旗下品牌: 「圣茵美」私密荷尔蒙抗衰,产后修复 「圣仪轩」私密荷尔蒙抗衰,产后修复 「花茵莳」私密荷尔蒙抗衰,产后修复 「丽彦妆」专注医学护…...

    2024/4/30 9:42:22
  23. 广州械字号面膜生产厂家OEM/ODM4项须知!

    原标题:广州械字号面膜生产厂家OEM/ODM4项须知!广州械字号面膜生产厂家OEM/ODM流程及注意事项解读: 械字号医用面膜,其实在我国并没有严格的定义,通常我们说的医美面膜指的应该是一种「医用敷料」,也就是说,医用面膜其实算作「医疗器械」的一种,又称「医用冷敷贴」。 …...

    2024/5/2 9:07:46
  24. 械字号医用眼膜缓解用眼过度到底有无作用?

    原标题:械字号医用眼膜缓解用眼过度到底有无作用?医用眼膜/械字号眼膜/医用冷敷眼贴 凝胶层为亲水高分子材料,含70%以上的水分。体表皮肤温度传导到本产品的凝胶层,热量被凝胶内水分子吸收,通过水分的蒸发带走大量的热量,可迅速地降低体表皮肤局部温度,减轻局部皮肤的灼…...

    2024/4/30 9:42:49
  25. 配置失败还原请勿关闭计算机,电脑开机屏幕上面显示,配置失败还原更改 请勿关闭计算机 开不了机 这个问题怎么办...

    解析如下&#xff1a;1、长按电脑电源键直至关机&#xff0c;然后再按一次电源健重启电脑&#xff0c;按F8健进入安全模式2、安全模式下进入Windows系统桌面后&#xff0c;按住“winR”打开运行窗口&#xff0c;输入“services.msc”打开服务设置3、在服务界面&#xff0c;选中…...

    2022/11/19 21:17:18
  26. 错误使用 reshape要执行 RESHAPE,请勿更改元素数目。

    %读入6幅图像&#xff08;每一幅图像的大小是564*564&#xff09; f1 imread(WashingtonDC_Band1_564.tif); subplot(3,2,1),imshow(f1); f2 imread(WashingtonDC_Band2_564.tif); subplot(3,2,2),imshow(f2); f3 imread(WashingtonDC_Band3_564.tif); subplot(3,2,3),imsho…...

    2022/11/19 21:17:16
  27. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机...

    win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”问题的解决方法在win7系统关机时如果有升级系统的或者其他需要会直接进入一个 等待界面&#xff0c;在等待界面中我们需要等待操作结束才能关机&#xff0c;虽然这比较麻烦&#xff0c;但是对系统进行配置和升级…...

    2022/11/19 21:17:15
  28. 台式电脑显示配置100%请勿关闭计算机,“准备配置windows 请勿关闭计算机”的解决方法...

    有不少用户在重装Win7系统或更新系统后会遇到“准备配置windows&#xff0c;请勿关闭计算机”的提示&#xff0c;要过很久才能进入系统&#xff0c;有的用户甚至几个小时也无法进入&#xff0c;下面就教大家这个问题的解决方法。第一种方法&#xff1a;我们首先在左下角的“开始…...

    2022/11/19 21:17:14
  29. win7 正在配置 请勿关闭计算机,怎么办Win7开机显示正在配置Windows Update请勿关机...

    置信有很多用户都跟小编一样遇到过这样的问题&#xff0c;电脑时发现开机屏幕显现“正在配置Windows Update&#xff0c;请勿关机”(如下图所示)&#xff0c;而且还需求等大约5分钟才干进入系统。这是怎样回事呢&#xff1f;一切都是正常操作的&#xff0c;为什么开时机呈现“正…...

    2022/11/19 21:17:13
  30. 准备配置windows 请勿关闭计算机 蓝屏,Win7开机总是出现提示“配置Windows请勿关机”...

    Win7系统开机启动时总是出现“配置Windows请勿关机”的提示&#xff0c;没过几秒后电脑自动重启&#xff0c;每次开机都这样无法进入系统&#xff0c;此时碰到这种现象的用户就可以使用以下5种方法解决问题。方法一&#xff1a;开机按下F8&#xff0c;在出现的Windows高级启动选…...

    2022/11/19 21:17:12
  31. 准备windows请勿关闭计算机要多久,windows10系统提示正在准备windows请勿关闭计算机怎么办...

    有不少windows10系统用户反映说碰到这样一个情况&#xff0c;就是电脑提示正在准备windows请勿关闭计算机&#xff0c;碰到这样的问题该怎么解决呢&#xff0c;现在小编就给大家分享一下windows10系统提示正在准备windows请勿关闭计算机的具体第一种方法&#xff1a;1、2、依次…...

    2022/11/19 21:17:11
  32. 配置 已完成 请勿关闭计算机,win7系统关机提示“配置Windows Update已完成30%请勿关闭计算机”的解决方法...

    今天和大家分享一下win7系统重装了Win7旗舰版系统后&#xff0c;每次关机的时候桌面上都会显示一个“配置Windows Update的界面&#xff0c;提示请勿关闭计算机”&#xff0c;每次停留好几分钟才能正常关机&#xff0c;导致什么情况引起的呢&#xff1f;出现配置Windows Update…...

    2022/11/19 21:17:10
  33. 电脑桌面一直是清理请关闭计算机,windows7一直卡在清理 请勿关闭计算机-win7清理请勿关机,win7配置更新35%不动...

    只能是等着&#xff0c;别无他法。说是卡着如果你看硬盘灯应该在读写。如果从 Win 10 无法正常回滚&#xff0c;只能是考虑备份数据后重装系统了。解决来方案一&#xff1a;管理员运行cmd&#xff1a;net stop WuAuServcd %windir%ren SoftwareDistribution SDoldnet start WuA…...

    2022/11/19 21:17:09
  34. 计算机配置更新不起,电脑提示“配置Windows Update请勿关闭计算机”怎么办?

    原标题&#xff1a;电脑提示“配置Windows Update请勿关闭计算机”怎么办&#xff1f;win7系统中在开机与关闭的时候总是显示“配置windows update请勿关闭计算机”相信有不少朋友都曾遇到过一次两次还能忍但经常遇到就叫人感到心烦了遇到这种问题怎么办呢&#xff1f;一般的方…...

    2022/11/19 21:17:08
  35. 计算机正在配置无法关机,关机提示 windows7 正在配置windows 请勿关闭计算机 ,然后等了一晚上也没有关掉。现在电脑无法正常关机...

    关机提示 windows7 正在配置windows 请勿关闭计算机 &#xff0c;然后等了一晚上也没有关掉。现在电脑无法正常关机以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;关机提示 windows7 正在配…...

    2022/11/19 21:17:05
  36. 钉钉提示请勿通过开发者调试模式_钉钉请勿通过开发者调试模式是真的吗好不好用...

    钉钉请勿通过开发者调试模式是真的吗好不好用 更新时间:2020-04-20 22:24:19 浏览次数:729次 区域: 南阳 > 卧龙 列举网提醒您:为保障您的权益,请不要提前支付任何费用! 虚拟位置外设器!!轨迹模拟&虚拟位置外设神器 专业用于:钉钉,外勤365,红圈通,企业微信和…...

    2022/11/19 21:17:05
  37. 配置失败还原请勿关闭计算机怎么办,win7系统出现“配置windows update失败 还原更改 请勿关闭计算机”,长时间没反应,无法进入系统的解决方案...

    前几天班里有位学生电脑(windows 7系统)出问题了&#xff0c;具体表现是开机时一直停留在“配置windows update失败 还原更改 请勿关闭计算机”这个界面&#xff0c;长时间没反应&#xff0c;无法进入系统。这个问题原来帮其他同学也解决过&#xff0c;网上搜了不少资料&#x…...

    2022/11/19 21:17:04
  38. 一个电脑无法关闭计算机你应该怎么办,电脑显示“清理请勿关闭计算机”怎么办?...

    本文为你提供了3个有效解决电脑显示“清理请勿关闭计算机”问题的方法&#xff0c;并在最后教给你1种保护系统安全的好方法&#xff0c;一起来看看&#xff01;电脑出现“清理请勿关闭计算机”在Windows 7(SP1)和Windows Server 2008 R2 SP1中&#xff0c;添加了1个新功能在“磁…...

    2022/11/19 21:17:03
  39. 请勿关闭计算机还原更改要多久,电脑显示:配置windows更新失败,正在还原更改,请勿关闭计算机怎么办...

    许多用户在长期不使用电脑的时候&#xff0c;开启电脑发现电脑显示&#xff1a;配置windows更新失败&#xff0c;正在还原更改&#xff0c;请勿关闭计算机。。.这要怎么办呢&#xff1f;下面小编就带着大家一起看看吧&#xff01;如果能够正常进入系统&#xff0c;建议您暂时移…...

    2022/11/19 21:17:02
  40. 还原更改请勿关闭计算机 要多久,配置windows update失败 还原更改 请勿关闭计算机,电脑开机后一直显示以...

    配置windows update失败 还原更改 请勿关闭计算机&#xff0c;电脑开机后一直显示以以下文字资料是由(历史新知网www.lishixinzhi.com)小编为大家搜集整理后发布的内容&#xff0c;让我们赶快一起来看一下吧&#xff01;配置windows update失败 还原更改 请勿关闭计算机&#x…...

    2022/11/19 21:17:01
  41. 电脑配置中请勿关闭计算机怎么办,准备配置windows请勿关闭计算机一直显示怎么办【图解】...

    不知道大家有没有遇到过这样的一个问题&#xff0c;就是我们的win7系统在关机的时候&#xff0c;总是喜欢显示“准备配置windows&#xff0c;请勿关机”这样的一个页面&#xff0c;没有什么大碍&#xff0c;但是如果一直等着的话就要两个小时甚至更久都关不了机&#xff0c;非常…...

    2022/11/19 21:17:00
  42. 正在准备配置请勿关闭计算机,正在准备配置windows请勿关闭计算机时间长了解决教程...

    当电脑出现正在准备配置windows请勿关闭计算机时&#xff0c;一般是您正对windows进行升级&#xff0c;但是这个要是长时间没有反应&#xff0c;我们不能再傻等下去了。可能是电脑出了别的问题了&#xff0c;来看看教程的说法。正在准备配置windows请勿关闭计算机时间长了方法一…...

    2022/11/19 21:16:59
  43. 配置失败还原请勿关闭计算机,配置Windows Update失败,还原更改请勿关闭计算机...

    我们使用电脑的过程中有时会遇到这种情况&#xff0c;当我们打开电脑之后&#xff0c;发现一直停留在一个界面&#xff1a;“配置Windows Update失败&#xff0c;还原更改请勿关闭计算机”&#xff0c;等了许久还是无法进入系统。如果我们遇到此类问题应该如何解决呢&#xff0…...

    2022/11/19 21:16:58
  44. 如何在iPhone上关闭“请勿打扰”

    Apple’s “Do Not Disturb While Driving” is a potentially lifesaving iPhone feature, but it doesn’t always turn on automatically at the appropriate time. For example, you might be a passenger in a moving car, but your iPhone may think you’re the one dri…...

    2022/11/19 21:16:57