CL关于ORB_SLAM的那些事(PnPsolver)

ceres_solver解PnP平差问题、Matlab数据制作 网上的PnP平差没有数据,很痛苦,自己制作数据来解 根据其次坐标的推导公式 在Matlab中制作数据(矩阵运算比较方便_) clc clear X = zeros(15, 3); x = zeros(15, 2); K=[25 0 0;0 25 0;0 0 1;]%相机内参数矩阵 R=[0.4770710827172032, -0.7476726229304006, -0.4619402893831741;%旋转矩阵 0.653281340399395, 0.653280157390419, -0.38 阅读详情

PnPsolver部分的学习总结

之前看的代码基本都是整个部分的功能,今天开始看一些求解器的cpp,主要就是两个吧,PnPsolver还有Sim3Solver。
,开始吧!

.h部分的浏览

包含的头文件有,opencv、MapPoint.h、Frame.h
PnPsolver类维护的变量(都是私有的):
double uc, vc, fu, fv:内参?
double * pws, * us, * alphas, * pcs:4个double的指针
int的匹配最大数量
double的两个二维数组(4行3列)
double的行列式值
存放MapPoint的容器
存放二维点的容器
存放Sigma2的float容器
存放三维点的容器
存放关键点在帧内索引的容器
double 3行3列的旋转矩阵
double 3行的平移向量
Mat 第i个变换矩阵
存放是否是内点的标志位的容器
int 内点的数量
int 迭代的次数
存放是否是best内点标志位的容器
int best的内点数量
Mat best变换矩阵
Mat 精制的变换矩阵
存放精制之后是否是内点的标志位容器
int 精制之后内点的数量
int 匹配上的点对的数量
存放随机选择的关键点的索引容器
double RANSAC的概率
Ransac最小的内点数
Ransac最大的迭代次数
Ransac被期望的内点数和总数的比例
Ransac的阈值
Ransac最小集
存放float的最大误差

PnPsolver类中的函数方法:
public:
构造函数
析构函数
设置Ransac参数的函数
find函数
迭代函数
private:
校核内点函数
精制函数
设置最大匹配数量函数
重置匹配函数
添加匹配关系函数
计算位姿函数
相对误差函数
打印位姿函数
重投影误差函数
选择控制点函数
计算重心坐标函数
填充M矩阵函数
计算ccs函数
计算pcs函数
sign的求解器函数
找到find_betas_approx_1函数
找到find_betas_approx_2函数
找到find_betas_approx_3函数
qr求解器函数
两个数的点乘函数
计算距离的平方函数
compute_rho()计算不知道啥的函数
compute_L_6x10()计算啥的函数
高斯牛顿计算函数
计算A和b高斯牛顿的函数
计算旋转和平移矩阵
拷贝旋转和平移矩阵
将Mat转四元数的函数

function by function

cpp文件中包含的除了自身的头文件还有opencv的基本头文件和词袋的头文件
构造函数
PnPsolver()
函数的参数列表:常数帧、常数的存放MapPoint指针的容器
列表初始化:pws(0), us(0), alphas(0), pcs(0), 最大的匹配数量为0, 匹配上的数量为0,最小的内点数为0,迭代次数为0,最好的内点数为0, N(0)
MapPoint的匹配关系被赋值传入的MapPoint指针的容器
维护变量中存放2D、Sigma平方、3D点、关键点索引和所有的索引的容器的大小都是传入帧内MapPoint的数量
定义int索引,初始化为0
循环遍历匹配的MapPoint,取其中的MapPoint,在是MapPoint且不是bad的情况下,取其对应的关键点,获取对应的2D点坐标、该点对应的Sigma平方、该点的3D坐标、关键点的索引和这个点在所有索引的索引值,定义的索引值++
获取该帧相机的标定参数,赋值给fu = F.fx;fv = F.fy;uc = F.cx;vc = F.cy;
最后调用Ransac的参数

析构函数
~PnPsolver()
直接delete [] pws;
delete [] us;
delete [] alphas;
delete [] pcs;

设置Ransac参数的函数
SetRansacParameters()
函数的参数列表:double的概率、内点的数量、最大的迭代的次数、最小的设置、epsilon值和阈值
将传入的概率赋值给Ransac的概率变量
将传入的最小内点数量赋值给Ransac的最小内点数
将传入的最大迭代次数赋值给Ransac的最大迭代次数
将传入epsilon值赋值给Ransac的epsilon变量
将最小的设置值赋值给Ransac的最小设置值
获取2D关键点的数量N
设置存放内点的容器的大小为N
######根据关键点的数量调整参数#############
定义了最小内点数,初始化为N×epsilon
如果定义的这个值小于Ransac的最小内点数,将定义的值赋值为Ransac的最小内点数。
如果定义的这个值小于最小设置值,将定义的值赋值为最小设置值
将定义的最小内点数赋值给Ransac的最小内点数。
如果Ransac的epsilon值小于Ransac的最小内点数/N,就将Ransac的epsilon的值赋值为Ransac的最小内点数/N
定义迭代次数
如果Ransac的最小内点数等于N,迭代次数为1;如果不是,迭代次数为取log(1-Ransac的概率)/log(1-Ransac的3次方)的ceil
给Ransac最大迭代次数赋值为max(1,min(nIterations,mRansacMaxIts))
设置存放最大误差的容器的大小为存放Sigma平方容器的大小
循环赋值最大误差值,最误差值为Sigma的平方*传入的阈值

寻找函数
find()
函数的参数列表:存放bool的内点容器和内点的数量
定义bool的标志位
return 迭代函数的值iterate()

迭代函数
iterate()
函数的参数列表:迭代的次数、不再多的标志位、存放bool类型标志位的内点容器和内点的数量
不再多的标志位置false
清空内点标志位的容器
内点的数量为0
调用set_maximum_number_of_correspondences()函数,设置最大的匹配数量
如果关键点的数量小于Ransac最小的内点数量,将不再多的标志位置true,直接返回空Mat
定义可获取的索引的容器
定义当前迭代的次数为0
当迭代的次数小于Ransac的最大迭代次数或者当前迭代的次数小于迭代次数,一直while循环,当前迭代次数++,总的迭代次数++,调用重置匹配数量函数reset_correspondences(),将所有索引的容器赋值给可获得的索引值容器,循环Ransac的最小设置值,随机产生一个int值,在可获取的索引容器内获取对应位置的索引值,调用添加联系的函数add_correspondence(),用容器的最后一个索引覆盖被抽到的那个索引,最后将最后一个索引pop。通过这个循环获取一个Ransac的点集。调用计算位姿的函数 compute_pose(),调用校核内点的函数CheckInliers(),如果内点的数量不少于Ransac的最小内点数,如果内点的数量大于最好的内点数量,将内点的数量赋值给最好的内点数量,计算得到的旋转和平移矩阵,转换成变换矩阵,判断精制Redine()函数的返回值,如果是true,就把精制的内点数量赋值给内点数,定义存放bool标志位的容器(大小为匹配上的MapPoint的数量,初始化为false)给内点的容器。循环遍历关键点,如果在精制内点的容器内有索引,就在内点容器的该索引处置true,返回精制后的变换矩阵。结束while循环
如果迭代的次数不小于Ransac的最大迭代次数,不再多的标志位置true,如果最好的内点数不小于Ransac的最小内点数,内点数被赋值最好的内点数,同样也定义存放bool标志位的容器(大小为匹配上的MapPoint的数量,初始化为false)给内点的容器,如果在最好内点的容器内有索引,就在内点容器的该索引处置true,返回最好的变换矩阵。
返回空的Mat矩阵。

精制函数
Refine()
定义存放int类型的索引容器,容器的大小为最好内点的数量
循环遍历存放最好内点的容器,将好的内点索引存入刚刚定义的容器内
调用设置最大的联系点数量的函数set_maximum_number_of_correspondences()传入参数索引点的数量
调用重置联系的函数reset_correspondences()
循环遍历索引值的容器,获取索引值,取该索引位置的三维点坐标和二维点坐标,传入add_correspondence()函数
调用计算相机位姿的函数compute_pose()
校核内点的数量CheckInliers()
将内点的数量赋值给精制过的内点数量
将vb的内点数量赋值给精制过的vb内点数量
如果内点的数量大于Ransac的最小内点数量,取出计算出的相机的位姿,转换成变换矩阵赋值给精制的变换矩阵,返回true。
return false

校核内点数
CheckInliers()
将内点的数量初始化为0
循环遍历关键点,获取对应的三维点坐标和二维点的坐标
通过旋转和平移矩阵将三维坐标转换到相机坐标系下
再将相机坐标系下的坐标转换成像素坐标
计算u、v方向的误差
计算像素坐标系下的距离平方
如果距离误差小于最大的误差,将vb内点容器的对应位置置true,内点数++;如果不是,vb内点容器的对应位置置false

设置最大联系点数量
set_maximum_number_of_correspondences()
函数的参数列表:int型的整数
如果传入的要设置最大联系点的数量大于原本的值,对于非零的pws,us,alphas,pcs直接delete
将最大联系点的数量赋值为出传入的值
重新给这个四个数组分配内存

重置联系点数量
reset_correspondences()
将联系点的数量初始化为0

添加联系关系
add_correspondence()
函数的参数列表:三维坐标的x、y、z和二维坐标的u、v
将三维坐标存入pws的数组内
将二维坐标存入us的数组内
联系点的数量++

选择控制的点
choose_control_points()
将cws数据的第一行的1到3列赋值为0
循环遍历联系点的数量,取出三维坐标存入cws的数组中,相当于累加,cws中存入了三维坐标在各个方向上的坐标之和。
对cws数组进行平均值处理
定义创建了联系点数量行、3列float的Mat矩阵
定义了pw0tpw0[3 * 3], dc[3], uct[3 * 3]
定义了其对应的Mat矩阵,3行3列、3行1列、3行3列
循环联系点的数量,获取去均值之后的三维坐标,存入了PW0
调用opencv中的cvMulTransposed函数,将取均值之后的三维坐标,再进行如下操作,
在这里插入图片描述
对上面的得到的矩阵进行SVD分解,得到特征值矩阵和U矩阵
调用释放Mat指针的函数,释放PW0的指针
循环3次,取对应的特征值矩阵除上联系点的数量再开平方,得到类似的奇异值,循环遍历均值坐标的三个轴,在原有的基础上再加对应奇异值×U矩阵对应的坐标值,这样做的本质,就是获取在整个大坐标系下的PCA方向。

计算重心坐标
compute_barycentric_coordinates()
定义double的数组cc[3 * 3], cc_inv[3 * 3]
创建3行3列的float的mat矩阵
创建3行3列的float的mat矩阵,这个矩阵是上面矩阵的逆矩阵
循环遍历,得到以均值点作为原点的特征向量的坐标,将这个三个方向组成矩阵
计算得到该矩阵的逆矩阵
定义一个double的指针ci指向这个逆矩阵
循环遍历(联系点的数量),定义行指针,其中再循环三次,计算该逆矩阵乘上去均值之后的三维坐标,alphas的第一列值为1-后面三列的和。经过这样的变换得到由这四个控制点表示的系数。

填充M矩阵
fill_M()
函数的参数列表:Mat的M矩阵、行数、double类型的指针、常量double的u、v值
定义了指向M矩阵的行指针,具体指向哪一行由传入的行参数决定
定义了另一个行指针,该指针永远指向上面那个指针的下一行
循环填补M矩阵中的参数,利用传入的double类型的数组,利用相机内参的反投影u、v方向上的值

计算CCS
compute_ccs()
函数的参数列表:常double的指针betas、常double的指针ut
循环将ccs矩阵中的每个元素置0。ccs为4行3列的矩阵
循环计算在当前坐标系内的4个控制点坐标

计算PCS
compute_pcs()
循环联系点数量次,每次定义两个行指针指向两个矩阵alphas和pcs
下面的一个循环,计算这四个控制点下的3D点在相机坐标系下的坐标,存入pcs矩阵内。

计算位姿
compute_pose()
函数的参数列表:旋转矩阵和平移矩阵
调用选择控制点函数choose_control_points()
调用计算重心坐标函数compute_barycentric_coordinates()
创建M矩阵,2×联系点数量行,12列
循环填充M矩阵,调用填充M矩阵的函数,回过头来看看fill_M()函数就很容易理解了
定义M转置乘M的12行12列的方阵
定义特征值矩阵
定义u转置的特征向量分解矩阵
调用cvMulTransposed()函数,获得M矩阵的转置乘M矩阵的方阵
利用cvSVD()函数分解得到特征值矩阵和特征向量矩阵
释放M矩阵的内存
定义l_6x10[6 * 10], rho[6]矩阵
调用计算l_6x10矩阵的函数compute_L_6x10(),函数的参数传入ut和l_6x10
调用计算rho的函数compute_rho(),函数的参数传入rho
定义double Betas[4][4],rep_errors[4],Rs[4][3][3],ts[4][3]
调用find_betas_approx_1()函数
调用gauss_newton()函数
调用 compute_R_and_t()函数,返回的重投影误差赋值给rep_errors[1]
调用find_betas_approx_2()函数
调用gauss_newton()函数
调用 compute_R_and_t()函数,返回的重投影误差赋值给rep_errors[2]
调用find_betas_approx_3()函数
调用gauss_newton()函数
调用 compute_R_and_t()函数,返回的重投影误差赋值给rep_errors[3]
定义int N并初始化为1
取误差最小的那一组
拷贝计算得到旋转和平移矩阵
最后return该组旋转矩阵和平移矩阵的误差

拷贝旋转和平移矩阵
copy_R_and_t()
函数的参数列表:常double的原始旋转矩阵、常double的原始平移矩阵、拷贝之后的旋转矩阵和拷贝之后的平移矩阵
循环遍历将原始的数据拷贝给拷贝的数据内

计算距离的平方
dist2()
函数的参数列表:两个点的坐标值
直接返回两个点之间距离的平方

点乘
dot()
函数的参数列表:两个向量的首地址
直接返回两个向量点乘的结果

计算重投影误差
reprojection_error()
函数的参数列表:旋转和平移矩阵
定义double的距离的平方sum2变量,初始化为0
循环遍历所有的联系点,取其三维点,然后乘上旋转矩阵,加上平移矩阵,乘上相机的内参矩阵,得到像素坐标,计算与原来像素坐标之间的投影误差,sum2累加误差。
最后返回平均投影误差

估计旋转和平移矩阵
estimate_R_and_t()
函数的参数列表:旋转矩阵和平移矩阵
定义在世界坐标系下的坐标pw0[3]和相机坐标系下的坐标pc0[3],都初始化为0
循环遍历各个联系点,定义两个行指针指向两个数组的首地址,循环将每个点的坐标进行相加,x、y和z方向的分别累加
循环,计算三个方向的平均值
定义了double abt[3 * 3], abt_d[3], abt_u[3 * 3], abt_v[3 * 3],第一个矩阵是要分解的矩阵,第二个矩阵是特征值矩阵,第三个是分解出来的u矩阵,最后一个矩阵是分解出来的v矩阵
将这四个矩阵和cvMat的数据结构关联起来
将要分解的矩阵置0
循环构建ABT(看到这边就需要回去看pcs是怎么来的)
在这里插入图片描述
对该矩阵进行SVD分解,得到U、V矩阵和特征值矩阵
通过从分解的U、V矩阵中计算获取旋转矩阵
验证该旋转矩阵的行列式是否为1,如果不是就将第三行取反,保证其行列式为正1
将世界坐标系下的坐标乘上旋转矩阵,去除了旋转矩阵的影响,用相机坐标系下的坐标减去刚刚的坐标得到平移矩阵

打印出位姿信息
print_pose()
函数的参数列表:旋转矩阵和平移向量
直接利用cout,标准输入输出把矩阵内的每一个矩阵元素打印出来

解决符号
solve_for_sign()
判断在相机坐标系下的三维点坐标的Z值是否小于0,如果小于0的话,将ccs内的4个控制点取反,将相机坐标系下的三维坐标也取反。

计算旋转和平移矩阵
compute_R_and_t()
函数的参数列表为:SVD之后的U矩阵,4个控制点的表示系数、旋转矩阵和平移向量
调用compute_ccs(betas, ut)、compute_pcs()函数,得到三维点在相机坐标系下的坐标
调用solve_for_sign()、estimate_R_and_t(R, t)函数,计算得到旋转和平移矩阵
调用reprojection_error(R, t)函数,返回最后这组旋转和平移矩阵计算得到的重投影矩阵

寻找合适的控制点的系数
find_betas_approx_1()
往下涉及到的一些内容需要结合EPnP: An Accurate O(n) Solution to the PnP Problem这篇论文的公式来看一下会更清楚一点。
这个函数是1,后面还有2和3。他们之间的主要区别是选取的系数的数量不一样,所以对应的估计方法也会存在一些差异。
// betas10    = [B11 B12 B22 B13 B23 B33 B14 B24 B34 B44]
// betas_approx_1 = [B11 B12 B13 B14]
当前这个函数取了4个向量,用到的组合是B11 、B12、B13和B14
从L矩阵内取出对应的元素,组成新的L矩阵
调用cvSolve()函数,计算得到参数系数。
后面的两个差不多,这边就不进行一一展示了。

计算L矩阵
compute_L_6x10()
函数的参数列表:SVD分解出的U矩阵和L矩阵
取矩阵的最后四行,因为分解出的奇异向量是按照奇异值从大到小排列的。最后一行是最小的,依次递增。
在这里插入图片描述

计算rho矩阵
compute_rho()
函数的参数列表:rho矩阵
计算世界坐标系下的四个控制点两两之间的距离

计算A矩阵和进行高斯牛顿优化
compute_A_and_b_gauss_newton()
函数的参数列表:l矩阵、rho矩阵、4个系数、A矩阵和b矩阵
这边的A矩阵是6个梯度矩阵
b矩阵是世界坐标系下控制点两两之间的距离与对应相机坐标系下的距离之差
在这里插入图片描述
高斯牛顿优化
gauss_newton()
函数的参数列表:L矩阵、Rho矩阵和4个系数
定义迭代的次数为5(根据论文里的描述,进行不到10次的优化就可以得到好的结果)
往下就是调用compute_A_and_b_gauss_newton()函数,进行两个矩阵的计算
最后调用 qr_solve()函数,计算得到这一次迭代结果
循环将得到的结果累加到4个系数上
在这里插入图片描述
QR分解
qr_solve()
函数的参数列表:A矩阵、b矩阵和未知数X矩阵
关于QR分解,我在上一篇博客里有进行学习和总结,这边就不一一赘述。
经过这个函数之后,就能得到变换的系数。

计算相对误差
relative_error()
函数的参数列表:旋转误差、平移误差、真的旋转矩阵、真的平移矩阵、估计的旋转矩阵和估计的平移矩阵
定义真实的四元数和估计的四元数
将真实和估计的旋转矩阵转换成四元数
计算rot_err1:真实和估计之间差值平方和的开方除上真实的四元数的平方和的开方
计算rot_err2:真实和估计之和的平方和的开方除上真实的四元数的平方和的开方
将两个误差比较,取小的那个作为最后旋转的误差
计算平移的误差transl_err:真实和估计之间差值平方和的开方除上真实平移的平方和的开方

将Mat转四元数
mat_to_quat()
函数的参数列表:旋转矩阵和四元数
计算旋转矩阵主元的和,也就是矩阵的迹
定义一个double的变量n4
在这里插入图片描述

时间:2019年09月08日
作者:hhuchen
机构:河海大学机电工程学院

无人机航拍图像匹配——ORB算法实践(含代码) 无人机航拍图像,用orb算法进行匹配 阅读详情

相关推荐

相机位姿估计(一):基本原理之如何解PNP问题

关于PNP问题就是指通过世界中的N个特征点与图像成像中的N个像点,计算出其投影关系,从而获得相机或物体位姿的问题。 以下讨论中设相机位于点Oc,P1、P2、P3……为特征点。 Case1: 当N=1时 当只有一个特征点P1,我们假设它就在图像的正中央,那么显然向量OcP1就是相机坐标系中的Z轴,此事相机永远是面对P1,于是相机可能的位置就是在以P1为球心的球面上,再一个就是球的半径也无法...

minione_2016的博客 5587

【亲测免费】 PnP_Solver:一个高效、灵活的Perspective-n-Point(PnP)问题解决方案

PnP_Solver:一个高效、灵活的Perspective-n-Point(PnP)问题解决方案 项目简介 是一个开源的C++库,专门用于解决计算机视觉中的Perspective-n-Point(PnP)问题。PnP问题在现实世界的应用中非常广泛,例如在机器人定位、AR/VR、无人机导航等领域,都需要计算相机相对于已知3D点集的位置和姿态。PnP_Solver提供了多种算法实现,旨在提供快速且精...

gitblog_00100的博客 698

【逐函数详细讲解ORB_SLAM2算法和C++代码|PnPsolver|1-22】

类在ORB-SLAM2系统中负责计算相机位姿,它使用EPnP算法从2D-3D点对之间的关系中进行估计。同时,使用RANSAC方法提高鲁棒性,剔除异常值。它实现了一种名为EPnP(Efficient Perspective-n-Point)的算法,该算法能够从2D-3D点对之间的关系中估计相机的位姿。类中还定义了许多私有方法,主要用于实现EPnP算法的内部计算和RANSAC迭代过程。

小秋 AI SLAM 入门实战教程 529

ORB_SLAM2 PnPSolver

EPNP:已知4组3D-2D匹配点,构建参考点,通过计算参考点的相机坐标,线性组合成路标点的相机坐标。然后使用ICP估计相机间的位姿变换。 构造函数 PnPsolver::PnPsolver(const Frame &F, const vector<MapPoint*> &vpMapPointMatches): (1)保存每一个路标点、特征点的信息。 (2)设置相机内参 (3)设置RANSAC参数。   设置RANSAC参数 /** * @brief 设置RANSAC迭代的参

weixin_43828675的博客 950

SLAM ORB-SLAM2(28)PnP估计姿态过程

分析了 ORB-SLAM2 中的 PnPsolver 的迭代过程。

氢键H-H 9447

(01)ORB-SLAM2源码无死角解析-(44) EPnP 源代码分析(4)→PnPsolver::qr_solve():QR分解

通过上一篇博客建立了高斯牛顿增量方程AΔβ=ΔB(01)AΔβ=ΔB(01)那么接下来就是对该方程的求解,源码中使用的方法是 QR分解(豪斯霍尔德Householder变换),具体的推导过程可以参考博客:(01)ORB-SLAM2源码无死角解析-(40) EPnP 算法原理详解→理论基础四:QR分解(豪斯霍尔德Householder变换)输入:输入:向量x=(x1,x2,⋯,xn)T≠0x=(x1​,x2​,

江南才尽江南山,年少无知年少狂! 983

ORBSLAM2理论与实战(23) 代码解读PnPsolver类

PnPsolver类 PnPsolver.h #ifndef PNPSOLVER_H #define PNPSOLVER_H #include <opencv2/core/core.hpp> #include "MapPoint.h" #include "Frame.h" namespace ORB_SLAM2 { class PnPsolver { public: ...

算法攻城狮 2545

视觉SLAM笔记(37) 求解 PnP

使用 EPnP 求解位姿、李代数位姿、空间点位置、投影方程边、Bundle Adjustment(光束平差法)

氢键H-H 1万+

认真的虎ORBSLAM2源码解读(十一):PnPsolver,PnP求解器

目录1.前言1.1.参考博客 1.前言 1.1.参考博客 一起学ORBSLAM2(9)ORBSLAM的PNP解决方案

认真的虎的博客 2516

PnP solvers C++版本,包括P3Pf,Epnp等

PnP solvers C++版本,包括P3Pf,Epnp等位姿解算算法,

基于STM32的频率计(采用外部中断的方式)

前言 最近在了解电赛相关的东西,和指导老师交流一下,我决定先从最简单的频率计做起。 频率计是来检测信号的频率的,在做频率计的时候可以用信号发生器发出的信号来进行测试。 原理 这是最基础的方波,我们可以通过检测上升沿的方式来测量其频率。从周期的角度出发连续两个上升沿的时间就是这个方波的周期,那这个周期分之一就是这个方波的频率了。 在思考了一段时间~~(我是萌新。。)~~ 我觉得有两个方法可以实现,第一个是采用stm32定时器的输入捕获功能,第二个就是用外部中断来实现这个功能。正如标题,我这次采用外部中断的方

qq_45784922的博客 6171

不同PNP求解算法性能测试

关键词:OpenCV::solvePnP 文章类型:方法封装、测试 @Author:VShawn(singlex@foxmail.com) @Date:2016-11-27 @Lab: CvLab202@CSU 前言 今天给大家带来的是一篇关于程序功能、性能测试的文章,读过《相机位姿估计1:根据四个特征点估计相机姿态》一文的同学应该会发现,直接使用OpenCV的

yuyangyg的博客 1万+

骗分导论 CSP、NOIP、蓝桥杯、PAT、USACO等竞赛的算法骗分技巧 轻松省三

问题来了,那么多座桥,炸一座就破坏岛屿的联系,可能性微乎其微(除非特别设计数据)。它们的价值极大,不仅能初步帮你检验程序的对错,而且,如果你不会做这道题,你就可以直接输出样例!在OI考试中最后难的题数据最后的几个,他们往往不会创造新的数据,此时就可以直接输出最后几个数据了。需要运用《骗分导论》第3章中学到的知识,先写出朴素算法,然后造一些数据,可能就会发现规律。有些时候,问题的答案可能很有特点:对于大多数情况,答案是一样的。据说,在NOIP2013中,有人最后一题不会,愤然打了个随机数,结果得了。

星卯教育-信奥教练tony 6404

opencv 纹理对象的实时姿态估计 PLY网格模型 三维纹理 ORB鲁棒匹配 PnPRansac 卡尔曼滤波去除错误的姿态估计

opencv 纹理对象的实时姿态估计 PLY网格模型 三维纹理 ORB鲁棒匹配 PnPRansac 卡尔曼滤波去除错误的姿态估计 github 博文末尾支持二维码赞赏哦_ # 纹理对象的实时姿态估计 [官方参考](https://docs.opencv.org/trunk/dc/d2c/tutorial_real_time_pose.html) # 运行 一、生成物体三维纹理模型...

万有文的博客 3380

【Unity】入门教程第一期-下载安装Unity编辑器(下)

讲解如何在Unity Hub中下载Unity编辑器以及IED环境

Xiaoxin的博客 2040

相控阵雷达仿真入门:TWS与TAS模式实战解析(附代码示例)

本文深入解析相控阵雷达仿真中的TWS(边搜索边跟踪)与TAS(搜索加跟踪)模式,提供实战代码示例和优化策略。通过简化模型设计和对象化建模,帮助开发者快速构建高效仿真系统,适用于军事推演和装备评估。文章涵盖核心逻辑、数据结构设计及性能优化技巧,提升仿真效率与准确性。

weixin_30687051的博客 453

ORB-SLAM3源码阅读笔记(6)-MLPnP

MLPnPsolver.cc用于在重定位时计算当前帧和候选帧的位姿变换,利用了3D-2D匹配。与ORB-SLAM2中的EPnP算法不同,MLPnP不依赖于相机模型,主要根据相机的反投影函数计算bearing vector。代码中的数学原理和公式都出自这篇论文,我仅对代码进行一下梳理。 1、构造函数 MLPnPsolver::MLPnPsolver(const Frame &F, const vector<MapPoint *> &vpMapPointMatches)://3D(地

qq_41861406的博客 894

SolidWorks+ADAMS双验证:你的机械臂力矩计算真的靠谱吗?

本文探讨了机械臂力矩计算中手工计算的局限性,并介绍了SolidWorks和ADAMS双验证方法的重要性。通过实际案例展示了动态工况下传统计算方法的误差,详细解析了SolidWorks精准质心捕捉和ADAMS动力学仿真的关键技术,帮助工程师构建计算-仿真-实测闭环验证流程,确保机械臂设计的可靠性和安全性。

grafana6viz的博客 228

图像配准之ORB算子角点检测

ORB算子角点检测 1. ORB角点检测原理 ORB 是 Oriented Fast and Rotated Brief 的简称,可以用来对图像中的关键点快速创建特征向量,这些特征向量可以用来识别图像中的对象。 其中,Fast 和 Brief 分别是特征检测算法和向量创建算法。ORB 首先会从图像中查找特殊区域,称为关键点。关键点即图像中突出的小区域,比如角点,比如它们具有像素值急剧的从浅色变为深色的特征。然后 ORB 会为每个关键点计算相应的特征向量。ORB 算法创建的特征向量只包含 1 和 0,称为二元

娇娇的跟班的博客 2260

微信小程序通过MQTT协议实现智能家居远程控制——基于阿里云物联网平台

本文详细介绍了如何利用微信小程序与MQTT协议,结合阿里云物联网平台,构建一套完整的智能家居远程控制系统。文章从平台配置、MQTT协议核心概念、小程序开发实战到单片机端对接,提供了全链路实践指南,并重点阐述了通过规则引擎实现消息路由与设备绑定的关键步骤,帮助开发者快速实现安全、稳定的自定义智能家居解决方案。

1207

27、物联网中的量子密钥分发:安全通信新范式

本文探讨了物联网(IoT)快速发展所带来的安全挑战,并提出量子密钥分发(QKD)作为应对新兴威胁的新范式。文章详细介绍了QKD的基础原理、BB84协议的实现流程以及其在物联网中的应用前景,同时强调了安全专业人员提升技能、制定标准化指南以及跨学科合作的重要性。通过利用量子力学特性,QKD能够提供更高的通信安全性,抵御量子计算等未来威胁,为物联网的安全发展提供保障。

tequila的博客 156

软件工程应用与实践第十二篇

ORB-SLAM3 PnPSolver.cc相关代码分析 2021SC@SDUSC 文章目录ORB-SLAM3 PnPSolver.cc相关代码分析前言一、算法原理及步骤二、代码分析 前言 之前对PnPSolver.cc做过一篇代码分析,这是第二篇,会对更细节的代码进行分析 一、算法原理及步骤 针对PnP问题,使用了RANSAC, EPnP两种算法共同求解位姿 。为了得到更加准确的值,在RANSAC算法框架下迭代使用EPnP算法,最后获得误差最小的。 1.RANSAC步骤 cv::Mat iterat

m0_46689170的博客 280

AVDepthData、LiDAR 深度数据与人像模式全解析:iOS 真实景深图采集与处理实战

在 iOS 高端影像系统中,真实景深信息的采集与利用已成为区分旗舰设备与基础设备的重要能力。Apple 自 iPhone 7 Plus 引入双摄虚化以来,逐步发展出基于 AVDepthData、TrueDepth 与 LiDAR 的多维深度感知技术,并开放接口供开发者获取高精度深度图,构建背景虚化、人像分割、3D 重建等多种功能。本文将深入解析 AVDepthData 的结构与使用方式,系统讲解 LiDAR 采集架构、人像模式的景深融合逻辑,以及如何在实际项目中采集、预览并处理深度图数据,实现具备工程可用性

努力分享一些人工智能、计算机视觉、影像等相关的知识干货! 1863

一起研究ORB-SLAM(四)--程序结构

转载自:一起研究ORB-SLAM(四)--程序结构 今天的内容很少,主要是介绍关于啊ORB-SLAM的工程结构,主要是他的每个文件的作用。 我想大多数人在第一次看到ORB-SLAM的时候是不是脑子变得大大,因为不知到怎么下手去处理,连个目录程序的主要入口都不知到,我也是,迷糊了一段时间,然后明白了,就分享给大家了。 以往关于ORB-SLAM文章 一起研究ORB-SLAM(一

u013474432的专栏 2074

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

(01)ORB-SLAM2源码无死角解析-(41) EPnP 源代码分析(1)→PnPsolver总体流程与思路

通过前面的博客,相信大家 EPnP 的理论已经有了一些了解,那么接下来就是对其源码进行分析了。逻辑思路 : 先把 2 D图像点通过内参变换到相机坐标系下的 3 D点,然后用ICP来求解 3 D - 3 D的变换就得到了位姿。那么很明显,其难点在于如何通过2D信息,加上一些约束,来得到相机坐标系下的3D点。这里使用到的为:因为位姿变换是欧式空间下的刚体变换,所以点之间的相对距离信息在不同坐标系(世界坐标系与相机坐标系)下是不变的。

江南才尽江南山,年少无知年少狂! 1182

蓝牙模块HM-10手册

蓝牙模块HM-10手册,该手册对蓝牙模块HM-10进行了详细的介绍和使用方法以及一些AT指令。

上一篇: CL关于矩阵分解方法的学习理解
下一篇: CL关于SLAM优化的推导和理解
EyeToTheWorld
博客等级 码龄10年 25粉丝 26原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值