当前位置: 首页 > news >正文

SLAM中的非线性优-3D图优化之轴角在Opencv-PNP中的应用(三)

      本讲主要讲解实战篇,代码框架依赖与视觉SLAM十四讲,原版已经将特征提取跟匹配以及PnP求解做好,这里借助这个框架,开发也较快一些,主要展示下,利用第一节的结论,来解析的求解雅可比及残差,并最终优化出最优解,完整代码依然放在个人的码云仓库中

https://gitee.com/zl_vslam/slam_optimizer/tree/master/3d_optimize/ch2https://gitee.com/zl_vslam/slam_optimizer/tree/master/3d_optimize/ch21. 特征提取跟匹配结果展示

总共匹配了79个点对

2. PNP求解结果对比

利用opencv求解pnp,注意opencv中主要使用如下接口:

接口1:

solvePnP ( pts_3d, pts_2d, K, Mat(), r, t, false );

接口2: 

solvePnP ( pts_3d, pts_2d, K, Mat(), r, t, false, SOLVEPNP_EPNP)

注意这两个接口,在于最后一个参数有没有默认方法,如果不设置的话,默认自带了一个LM优化求解器,而若设置了参数,则不优化,只求解PNP问题,因此这里我们的优化器跟opencv作对比

先看接口1的求解结果

再看接口2的结果

接口2主要以旋转轴表示,可以看到,我们的结果与opencv结果基本上很接近了,也可证明求解的正确性

3. 代码展示

void bundleAdjustment (const vector< Point3f > points_3d,const vector< Point2f > points_2d,const Mat& K,Mat& R, Mat& t )
{cout << "=== PnP Solver with Ceres Optimization ===" << endl;// 生成测试数据vector<Eigen::Vector3d> landmarks;vector<Eigen::Vector3d> bearings;// 添加一些测试点for (int i = 0; i < points_3d.size(); ++i) {landmarks.push_back(Eigen::Vector3d(points_3d[i].x, points_3d[i].y, points_3d[i].z));Point2d norm_pt = pixel2cam ( Point2d(points_2d[i].x, points_2d[i].y), K );bearings.push_back(Eigen::Vector3d(norm_pt.x, norm_pt.y, 1.0));}Matrix3d eigenR = cvMatToEigen<double>(R);Vector3d eigent = cvMatToEigen<double>(t);Mat rotation_vector;cv::Rodrigues(R, rotation_vector);Vector3d eigen_rotation_vector = cvMatToEigen<double>(rotation_vector);// 初始位姿估计Vector3d initial_rotation(eigen_rotation_vector);Vector3d initial_translation(eigent);// 测试rodrigues函数MatrixXd jacobian;MyRodrigues(initial_rotation, eigenR, jacobian);cout << "Initial rotation vector: " << initial_rotation.transpose() << endl;cout << "Rotation matrix:\n" << R << endl;// 构建优化问题ceres::Problem problem;for (size_t i = 0; i < landmarks.size(); ++i) {// 使用解析导数(推荐,因为我们已经计算了精确的雅可比矩阵)ceres::CostFunction* cost_function = new AnalyticReprojectionError(landmarks[i], bearings[i]);// 或者使用自动微分// ceres::CostFunction* cost_function = //     AutoDiffReprojectionError::Create(landmarks[i], bearings[i]);problem.AddResidualBlock(cost_function, nullptr,  // 损失函数initial_rotation.data(), initial_translation.data());}// 配置优化选项ceres::Solver::Options options;options.linear_solver_type = ceres::DENSE_QR;options.minimizer_progress_to_stdout = true;options.max_num_iterations = 100;options.function_tolerance = 1e-10;options.gradient_tolerance = 1e-10;options.parameter_tolerance = 1e-10;// 运行优化ceres::Solver::Summary summary;ceres::Solve(options, &problem, &summary);// 输出结果cout << "\n=== Optimization Results ===" << endl;cout << summary.BriefReport() << endl;cout << "Initial rotation: " << eigen_rotation_vector.transpose() << endl;cout << "Initial translation: " << eigent.transpose() << endl;cout << "Final rotation: " << initial_rotation.transpose() << endl;cout << "Final translation: " << initial_translation.transpose() << endl;// 验证最终的重投影误差MatrixXd dpdrot, dpdt, final_reproj_err;ProjectPoints3D2D(landmarks, bearings, initial_rotation, initial_translation, dpdrot, dpdt, final_reproj_err, false);double total_error = final_reproj_err.norm();cout << "Final reprojection error: " << total_error << endl;}

这里展示了求解主要过程,详细情况请参考源码实现吧,这里算法并不完整,没有设置信息矩阵的鲁棒核函数,但是作为验证,足以说明情况

总结

        本节主要展示了算法验证过程,理论也与之前能够完全匹配上,通过对比ceres-solver优化,跟opencv结果,可以看出,本节效果基本与opencv算的结果,完全一致,足以说明算法的有效性,下一讲,主要是相对位姿之间的残差及雅可比推导

http://www.dtcms.com/a/613338.html

相关文章:

  • 如何用WPF做工控设置界面
  • ✨WPF编程进阶【7.2】:动画类型(附源码)
  • 建设网站的安全性介绍深圳seo优化排名推广
  • 上海迈诺网站建设东莞专业做网站的公司有哪些
  • 深度学习中的激活函数全解析:该选哪一个?
  • MySQL复盘总结
  • 对于多方安全计算的中止安全的理解
  • 西游记路线图:12-39,大唐到乌鸡国,幕后boss标注
  • 【学习笔记】DiffFNO: Diffusion Fourier Neural Operator
  • 电磁场中的旋度Curl与散度div
  • KCF 算法在ROS 2 操作系统里面(详解)
  • 《Dev-C++分辨率低-解决办法》
  • Dubbo异步调用实战指南:提升微服务并发性能
  • 【Linux】冯诺依曼体系结构与操作系统概述
  • 简单企业网站模板php做的网站预览
  • 2025年数维杯数学建模挑战赛(秋季赛)【ABCD题】论文首发+百种模型组合+代码分享
  • OpenHarmony内核开发实战手册:编译构建、HCK框架与性能优化
  • 自建开发工具IDE(五)数据库预览——东方仙盟炼气期
  • MATLAB 实现多能源系统(MES)多目标优化
  • 构建企业级机器学习平台:基于Ray和DeepSpeed的半导体AI实践
  • 卡索(CASO)汽车调查:终端体验,是汽车品牌隐形的胜负关键
  • C语言编译器安卓版 | 高效便捷的手机编程环境
  • 子集合判断(map)
  • 潍坊做外贸网站网页源代码在线查看
  • 【Liunx】进程间关系与守护进程
  • el-upload 上传管理与自定义优化实践
  • 开发中的英语积累 P13:Segment、Inclusive、Exclusive、Movement、Arbitrarily、Generic
  • node语法特性详解
  • 2025-11-15 学习记录--Python-LSTM模型定义(PyTorch)
  • PLB-TV 4K+H.265 编码,无广告超流畅