- 博客(78)
- 收藏
- 关注
原创 相机标定笔记(单、双、鱼眼)
opencv 中相机标定calibrateCamera() 接口的实现,总结如下:(1. 因为镜头畸变的影响比较小,首先假定相机是理想无畸变的,根据闭式解来计算初始的相机内参;2. 估计相机位姿,也就是求解相机外参,opencv使用solvePnP来实现,支持迭代和 P3P 等多种算法求解;3. 应用最小二乘求解实际的径向畸变系数(4. 根据求解的内外参对objectPoints进行重投影,应用全局Levenberg-Marquardt优化算法来最小化重投影和原投影点之间的误差。
2025-04-07 00:03:48
851
原创 VINS-Mono学习(六):回环检测
VINS最后一个节点 pose_graph 是和回环检测相关内容。节点订阅 图像话题 和 vins_estimator节点发布的话题。1.ros初始化、设置句柄;2.创建一些publisher;3.从launch文件读取参数和参数文件config中的参数;4.回环检测下的处理,如从yaml文件读取参数、读取训练好的二进制词袋、描述子pattern、如果需要加载离线地图及对应的处理;5.订阅七个话题;6.创建五个话题的发布;7.主线程process;8.接收键盘回调值的线程,“s” 保存地图。
2025-04-01 15:31:51
921
原创 VINS-Mono学习(五):非线性优化
i++)// para_Pose是位姿 前三维是平移 后四维是旋转// para_SpeedBias是 速度、加速度计偏置、陀螺仪偏置//?为什么位姿有local_parameterization,速度、加速度计偏置、陀螺仪偏置没有local_parameterization// 因为位姿中的旋转使用四元数表示,四元数带约束,PoseLocalParameterization类中重载了Plus()函数类需要重载类的两个函数:Plus。
2025-03-29 20:47:00
743
原创 VINS-Mono学习(四):关键帧和初始化
到此,已经求解了陀螺仪零偏Bgs、所有帧在自己坐标系中的速度、第0帧的重力方向、和尺度s。①获取滑动窗口内所有图像帧相对于第l帧的位姿信息,并设置为关键帧// 计算滑窗帧的位姿Ps、Rs,并将其置为关键帧// initialStructure函数虽然计算了所有帧all_image_frame的位姿 frame_it->second.R 和frame_it->second.T,// 但是并没有存到Ps和Rs中,这里我们把这些位姿存到Ps和Rs中,并且把这些帧的is_key_frame标志位置为true。
2025-03-25 01:43:14
829
原创 VINS-Mono学习(二):feature_tracker
以运行数据集为例,运行命令:第一行命令是启动VINS系统,第二行是打开配置好的可视化界面,第三行播放数据。通过euroc.launch 启动了三个结点:feature_tracker、vins_estimator、pose_graph。feature_tracker总体的作用是接收图像,使用KLT光流算法跟踪;vins_estimate包含相机和IMU数据的前端预处理(也就是预积分过程)、单目惯性联合初始化(在线的标定过程)、基于滑动窗口的BA联合优化、全局的图优化和回环检测等通过rqt_graph命
2025-03-21 22:34:41
624
原创 VINS-Mono学习(一):论文
一个鲁棒的基于紧耦合的滑动窗非线性优化的单目视觉惯性里程计(VIO)。单目VIO模块不仅提供精确的局部姿态、速度和方位估计,而且还以在线方式执行摄像机IMU外部校准和IMU偏置校正。使用DBoW2进行回环检测。重新定位是在对单目VIO进行特征级别融合的紧耦合设置中完成。这使得重新定位具有鲁棒性和精确性且有最小的计算代价。最后,几何验证的回环被添加到位姿图中,并且由于来自单目VIO的可观测的翻滚角和俯仰角,生成四自由度(DOF)位姿图以确保全局一致性。:ORB-SLAM 采用,由于单目相机无法直接感知。
2025-03-20 18:38:18
584
原创 VIO笔记
记录笔记快速运动融合过程本身会影响视觉和IMU中的参数(如IMU的零偏和视觉的 尺度)。典型方案为MSCKF和非线性优化。VIO使用紧耦合原因:视觉存 在尺度不确定性、IMU存在零偏导致漂移。将IMU定位与视觉的位姿直接进行融合,融合过程对二者本 身不产生影响,作为后处理方式输出。典型方案为卡尔曼滤波器。IMU坐标系到世界坐标系的外参矩阵Twb 的平移部分可直接视作IMU在世界中的坐标。IMU坐标系的原点Pb = [0,0,0] 因此Pw = t_wb。
2025-03-13 01:12:26
625
原创 ORB-SLAM2源码学习:总结篇(二)三大线程
① 对于单目而言,连续两帧的特征点个数大于100,然后寻找两帧的匹配点对(具体方法在总结篇一),匹配点对大于100后计算两帧的位姿,位姿通过单应矩阵H或基础矩阵F计算;② 以单应矩阵H为例,从匹配点在随机选择八对点计算H,每个解通过卡方检验计算最优解,代码有个打分机制,最终确定通过H或者F计算位姿;③若以H进行位姿的恢复,通过SVD计算得到多组解,每个解通过三角化计算空间点坐标,至此得到了两帧的位姿变换、当前帧的位姿Tcw(cur) (初始化第一帧的位姿是单位矩阵)、特征点对应的空间点;
2025-03-11 23:25:42
934
原创 ORB-SLAM2源码学习:总结篇(一)
跟踪线程中的SLAM模式和纯定位模式就是在可视化界面进行修改的。③然后计算图一特征点和在图二找到的最佳匹配点的角度差,通过直方图统计 特征点的角度差值主流的前三个区域(因为所有的特征点的角度变化应该是一致的),其余的匹配认为是误匹配。对pKF和F中的特征点进行快速匹配,不属于同一node的特征点直接跳过匹配(只有属于同一node,才有可能是匹配点);对当前关键帧和 共视关键帧 中的特征点进行快速匹配,不属于同一node的特征点直接跳过匹配(只有属于同一node,才有可能是匹配点);
2025-03-11 00:38:46
773
原创 ORB-SLAM2源码学习(八):LoopClosing线程
目录1.回环检测 DetectLoop()2.Sim3 计算 ComputeSim3()2.1 构造Sim3Solver对象2.2 Sim3具体计算2.3 将闭环匹配上的关键帧以及相连关键帧的MapPoints投影到当前关键帧进行投影匹配 SearchByProjection()3.闭环矫正 3.1 矫正当前帧的共视关键帧位置和地图点3.2 地图点融合 SearchAndFuse()3.3 更新共视图3.4 本质图优化3.5 全局BA优化loopclosing线程在 实例化 ORB_SLAM2::Sys
2025-03-09 17:06:51
990
原创 ORB-SLAM2源码学习(七):LocalMapping线程
LocalMapping线程在实例化ORB_SLAM2::System对象的时候就已经运行了。线程函数Run()中会一直执行死循环(因为这个时候等待处理的关键帧为空)。直到Tracking线程的最后生成了关键帧,并且放到等待处理的关键帧列表mlNewKeyFrames,才真正开始LocalMapping线程。1.将关键帧插入地图中 ProcessNewKeyFrame()①从 mlNewKeyFrames 中取出列表最前面的关键帧,随后马上把列表中的该关键帧删除,然后对该关键帧进行处理;
2025-03-08 01:00:01
877
原创 ORB-SLAM2源码学习(六):相机跟踪(局部地图跟踪和关键帧创建)
目录1.局部地图跟踪1.1 更新局部关键帧UpdateLocalKeyFrames1.2 更新局部地图点(来自局部关键帧)UpdateLocalPoints()1.3 投影匹配2. 对比四种跟踪方式以及使用的投影匹配3.关键帧创建3.1 判断是否需要创建新关键帧: NeedNewKeyFrame()3.2 关键帧的创建CreateNewKeyFrame()当初始位姿估计成功(参考关键帧来跟踪、恒速模型跟踪、重定位跟踪跟踪成功)后需要进行局部地图跟踪TrackLocalMap()。初始位姿估计只是跟踪一帧得到
2025-03-06 00:04:36
1045
原创 docker使用记录
在ubuntu22.04中使用docker拉取ubuntu20.04镜像,后续安装ros1以及相机和激光驱动。只是记录使用docker的一些命令,防止以后忘记。
2024-06-19 20:25:38
359
原创 多线程c++
1. join会阻塞当前的线程,直到运行的线程结束。(例如第二段代码主线程被阻塞,直到子线程执行完才会执行join之后的主线程代码)2.detach从线程对象中分离出执行线程,允许线程独立的执行。(第三段代码,主线程和两个子线程独立的执行)
2024-01-30 17:20:23
1230
原创 ROS2学习记录
1.创建编辑.msg文件功能包下新建msg文件夹,文件夹中创建.msg文件2.编辑配置文件package.xml中添加依赖包--编译依赖-->--执行依赖-->--声明当前包所属的功能包组--><export></export></package>cmakelists.txt添加编译colcon build --packages-select 功能包3.测试编译完成,在工作空间下的install目录下将生成xxx.msg文件对应的C++和Python文件。
2023-12-27 19:07:32
895
原创 STL--关联式容器底层实现
unordered_set、unordered_map、unordered_multiset和unordered_multimap。结合数组查找数据快和链表插入删除效率高优点得到一个寻址容易,插⼊删除也容易的数据结构。查找、增删数据时间复杂度(O(1))红黑树的查找,插入和删除操作,时间复杂度都是O(logn)。红⿊树的每个节点上都有存储位表示节点的颜⾊,可以是红或⿊。:set、map、multiset和multimap ②。
2023-12-12 16:56:05
450
原创 ORB-SLAM2源码学习(四):单目初始化
从代码框架中知道GrabImageMonocular()函数主要做了两件事:对当前帧进行构造(Frame)和调用Track()对当前帧进行跟踪。前者已经介绍过了,本篇博客是对Track()函数中单目初始化的介绍。函数主要分为三步:Code:Tracking.cc初始化成功条件:①前后两帧提取的特征点大于100 ②两帧匹配的特征点对大于100ORB-SLAM2中特征点匹配均采用了各种技巧减小特征点匹配范围,特征点通过描述子匹配后会进行旋转一致性检测,并且要求最佳匹配特征点要明显优于次优匹配点。关键点匹配
2023-10-18 16:55:07
82
原创 OrbbecSDK_ros关于imu数据的发布
orbbec官方提供ros版本的sdk还不支持imu数据获取,貌似下个版本更新后就可以得到imu数据的话题。参考c++版本的sdk对ros的sdk进行修改,最后将imu数据以topic的形式发布。参考的c++_sdk关于imu数据获取代码。
2023-09-14 19:20:58
466
原创 ORB-SLAM2源码学习(三):构造Frame
目录1.提取OBR特征ExtractORB()1.1计算图像金字塔ComputePyramid()1.2 提取特征点ComputeKeyPointsOctTree()1.2.1 CELL网格1.2.2 四叉树筛选特征点1.3计算描述子computeDescriptors()2.去畸变UndistortKeyPoints()3.计算去畸变后图像边界ComputeImageBounds()4.特征点分配AssignFeaturesToGrid()提取图像的ORB特征点,提取的关键点存放在mvKeys,描
2023-07-16 20:37:35
46
原创 使用kalibr对相机和IMU标定
分别是包含标定相机和IMU数据的rosbag,IMU内参yaml,相机内外参yaml,标定板yaml.②IMU内参yaml、相机内外参yaml、标定板yaml。标定好的参数包括各方向的随机噪声与随机游走。acc_w 加速计偏置随机工作噪声标准偏差。gyr_w 陀螺仪偏差随机工作噪音标准偏差。acc_n 加速度计测量噪音标准偏差。关于需要下载的环境和具体的包参考【gyr_n 陀螺仪测量噪音标准偏差。相机-IMU联合标定总共需要准备好。2)相机内外参yaml用之前得到的。①录制相机和imu的rosbag。
2023-07-11 14:09:23
1635
原创 视觉SLAM ch13 设计SLAM系统
(一种特殊的函数,它作为参数传递给另一个函数,并在被调用函数执行完毕后被调用)如果是类的成员函数,这时想把成员函数设置给一个回调函数指针往往是不行的。:插入图像帧,提取图像特征,然后与上一帧进行光流追踪,通过光流结果计算该帧的位姿。必要时补充新的特征点并作三角化。前后端在分别的线程中处理数据,前端负责在地图中添加路标点,后端检测到地图更新以后优化路标点,并将旧的路标点删除掉,保持一定的规模。地图以hash的形式记录了所有的关键帧和对应的路标点,同时维护一个被激活的关键帧和地图点,激活的意思就是。
2023-05-13 20:47:00
1332
7
原创 工厂模式:简单工厂模式、工厂方法模式和抽象工厂模式
某厂有两个加工厂A和B分别生产鞋和衣服,随着订单的增加,A厂所在地有了衣服的订单,B厂所在地有了鞋子的订单,再开新的工厂显然是不现实的,因此在原来的工厂增加生产需求的功能,即A生产鞋+衣服,B生产衣服+鞋。将“类实例化的操作”与“使用对象的操作”分开,让使用者不用知道具体参数就可以实例化出所需要的“产品”类,从而避免了在客户端代码中显式指定,实现了解耦。将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类。具体的工厂负责实现具体的产品实例。
2023-04-24 22:05:30
598
原创 记录关于GPT的应用
但是也有一些缺点:代码不能保证准确性,对于较难的代码需要很多时间,python相对其他代码更准确。也可以全选输入Ctrl + K,对代码进行修改,如图片路径为 D:\\image。:openai账户里应该是送了18刀,每次提问都会扣除一定费用,N不要太大。如果运行的时候代码有问题,可以把问题丢给它,让它帮我们debug.选中某一行代码进行解释: Ctrl + L。如果让他写代码,生成的内容保存在。
2023-04-20 22:19:29
829
原创 opencv实现卡尔曼滤波
opencv自带程序:建立一个绕某一圆心做匀速圆周运动的小球,但是实际中它会受到系统噪声影响从而其角度和角速度有所变化,通过带有噪声的观测值(真实值+观测噪声)和匀速运动模型的预测值为输入使用KF得到估计值。原有的代码中比较的是真实值与预测值、真实值与观测值的偏差,没有用到估计值,因此我在上述代码中加入了真实值与估计值的比较。在更新阶段,滤波器利用对当前状态的观测值优化在预测阶段获得的预测值,以获得一个更精确的新估计值。x(k) = A*x(k-1) + B*u(k)+w(k) 运动方程。
2023-04-19 20:34:20
2673
原创 视觉SLAM ch12 建图(RGB-D)
假设每个点与临近点之间的距离是一个高斯分布,那么平均距离就是均值,并且可以根据均值和每一个距离求得标准差,那么平均距离在标准范围之外的点,可以被定义为离群点并从数据中去除。:取决与前端视觉里程计的处理方式。如果是基于特征点的视觉里程计,由于点云中没有存储特征点的信息,则无法用于基于特征点的定位方式。:点云无法直接用于避障,纯粹的点云无法表示“是否有障碍物",不过,可以在点云的基础上加工,得到更适合导航避障的地图形式。:根据估计的相机位姿,将RGB-D数据转化为点云,然后进行拼接,最终得到由离散的点组成的。
2023-04-17 21:38:01
532
原创 opencv双线性插值
对于float类型的像素,使用双线性插值方法求灰度。如下图所示,求P点灰度时找到附近的四个。设P(x+xx,y+yy),P1(x+xx,y), P2(x+xx,y+1) (int函数和floor函数区别:int函数返回的值是整型,floor函数返回值是浮点型。坐标的像素点A(x,y) B(x,y+1) C(x+1,y) D(x+1,y+1),双线性插值就是在x、y轴进行了三次单线性插值。这里的xx和yy指的是x和y的小数部分。关于单线性插值和双线性插值的概念参考。
2023-04-06 18:37:56
849
1
原创 视觉SLAMch12 建图(单目)
稠密重建需要知道参考帧所有像素点的深度,由于大部分像素点都不是特征点,对于这些点通过极线搜索和快匹配方法确定在其他帧图像位置。选择最高点当投影点计算深度值,但是某个像素点不可能只被观测两次,导致计算的深度值不一样。缩小不确定度是通过如下方式进行的:不断求出三维点的坐标,更新这个分布,直到这个分布的不确定性小于你希望的阈值,就认为是收敛了,收敛以后的均值,就不再改动了,当做是你确定下来的深度值。单目通过三角化得到像素的距离,双目通过左右目的视差计算像素的距离,这两种方式称为。,书中给出了具体的计算方法,
2023-04-03 17:59:53
1263
1
原创 视觉SLAM ch10位姿图
ch9介绍了以BA为主的图优化,可以精确地优化每个相机位姿和地图点位置,但在更大场景无法实时化,ch10介绍一种简化的BA:位姿图 (pose graph)
2023-02-16 20:27:08
422
原创 leetcode--二叉树
写完了递归算法, 运行的时候,经常会遇到栈溢出的错误,就是没写终止条件或者终止条件写的不对,操作系统也是用一个栈的结构来保存每一层递归的信息,如果递归没有终止,操作系统的内存栈必然就会溢出。确定哪些参数是递归的过程中需要处理的,那么就在递归函数里加上这个参数, 并且还要明确每次递归的返回值是什么进而确定递归函数的返回类型。前序遍历是中左右,因此我们可以得到中右左顺序的遍历方法,然后将中右左反转(reverse),得到左右中。,先将根节点入栈,然后栈顶元素出栈,右节点入栈,左节点入栈。
2022-12-08 10:54:37
285
原创 SLAM面试笔记
本质矩阵:5个自由度,最少可以用5对点求解,也可以使用八点法估计本质矩阵(需要SVD分解)基础矩阵:7个自由度,八对点求矩阵矩阵。单应性矩阵(描述了两个平面的映射关系):8个自由度,已知两个平面的图像坐标p1和p2,则p2 = H p1一对点提供两个约束方程,需要四对点求单应性矩阵。:只有旋转没有平移的时候可以用单应性矩阵求R。因为t为0,E也将为0,导致无法求解R。PnP(P3P)提供了一种解决方案,它是一种由3D-2D的位姿求解方式,即需要已知匹配的3D点和图像2D点。
2022-10-12 19:20:18
543
原创 leetcode--字符串
KMP算法:解决字符串匹配问题前缀:包含首字母不包含尾字母的子串 344 反转字符串541 每隔2k个字符反转前k个字符58 左旋转字符串28 实现strStrkmp算法
2022-06-21 21:49:13
186
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人