点到点ICP-基于SVD分解的帧间点云匹配
目录1.寻找匹配点对2.直接法求解R和t2.1 求解旋转2.2 求解平移2.3 对应代码实现3.迭代上述步骤4.完整流程注本篇笔记的主体内容来源于对深蓝学院《多传感器融合定位》课程的学习推荐有一定基础的SLAM初学者学习该课程。两帧点云的配准过程如上图过程所示。假设当前存在两个点云集合相邻两帧点云scan其中X为k-1时刻激光雷达采集到的三维点云目标点集Y为k时刻采集到的三维点云源点集合。配准的目的为寻找一对合适的旋转R与平移t即帧间相对位姿T[R,t]对Y进行位姿变换后使Y‘可以完美贴合至X理想情况配准的目标即残差函数可以描述为寻找一对合适的[R, t]使旋转后的yi与xi之间的距离最小其中m为集合Y中能找到对应点的点的数量为在集合X中的对应点。算法流程大致为1.寻找匹配点对配准过程需要知道两个点集中点的匹配关系所以需要对集合Y中的点在目标集合X中寻找对应点。由于普通的激光点只包含三维坐标数据无法像视觉特征点通过比较描述子的相似度来显示地找到对应点所以一般通过将Y集合的点根据初始的相对位姿估计投影到k-1时刻并根据三维坐标距离寻找离距离最近的作为对应点。如LOAM点云投影// input_source_k时刻的源点云 // transformed_input_source用于保存转换后的点云 // predict_pose预测的帧间相对位姿T(k-1_k) pcl::transformPointCloud(*input_source_, *transformed_input_source, predict_pose);对于一个点在另一团点云中寻找最近点可以利用kd-tree加速pcl::KdTreeFLANNpcl::PointXYZ::Ptr input_target_kdtree_; // input_target_k-1时刻的目标点云 input_target_kdtree_-setInputCloud(input_target_);通过kd-tree在X中为yi寻找xi// input_source投影到k-1时刻的Y点云 // ys保存能在X点云中找到对应点xi的点yi // xs保存xi size_t ICPSVDRegistration::GetCorrespondence( const CloudData::CLOUD_PTR input_source, // Y集合 std::vectorEigen::Vector3f xs, std::vectorEigen::Vector3f ys ) { const float MAX_CORR_DIST_SQR max_corr_dist_ * max_corr_dist_; size_t num_corr 0; std::vectorint pointSearchIndex; std::vectorfloat pointSearchDistance; for(size_t i 0; i input_source-size(); i) { // 1只找最近的1个点 input_target_kdtree_-nearestKSearch(input_source-points[i], 1, pointSearchIndex, pointSearchDistance); // MAX_CORR_DIST_SQR限制点的最远距离 if(pointSearchDistance.size() 1 pointSearchDistance[0] MAX_CORR_DIST_SQR) { CloudData::POINT point input_source-points[i]; ys.push_back(Eigen::Vector3f{point.x, point.y, point.z}); point input_target_-points[pointSearchIndex[0]]; xs.push_back(Eigen::Vector3f{point.x, point.y, point.z}); num_corr; // pointSearchIndex.clear(); // pointSearchDistance.clear(); } } return num_corr; }因为并不能为Y集合中的每个点在X集合中都找到合适的最近点所以只保存能找到的合适距离之内的yi和xi。2.直接法求解R和t残差函数E可以化简由于则其中只与旋转有关。根据求解出旋转R后就可以代入并令求解平移t。2.1 求解旋转继续看因为R是正交矩阵所以可以化简成如上形式。由于与为常量可以忽略则此时为了将R从两个向量的夹心中提取出来利用矩阵的迹的性质。由于是标量并且标量的迹等于其本身则迹trace而标量的迹是其本身所以最大化等价于最大化。再根据迹的循环性质得因为和Trace()都是线性算子它们可以交换顺序。所以上式中将求和符号放进迹的内部。并且令H矩阵为去中心化后的协方差矩阵则此时问题转化为寻找合适的R使Trace(RH)的值最大。当前R和H都是3x3的矩阵。根据定理若有正定矩阵则对于任何正交矩阵B有。若能寻找到一个R能将转换成的形式则该R就是能使值最大的R。此时对H进行SVD奇异值分解其中为3x3的正交矩阵为3x3的对角矩阵为3x3的正交矩阵。取则有这就得到了能使值最大的R。2.2 求解平移令则2.3 对应代码实现// xs对应目标点集 // ys对应源点集 // transformation_待求解的相对位姿变换增量 void ICPSVDRegistration::GetTransform( const std::vectorEigen::Vector3f xs, const std::vectorEigen::Vector3f ys, Eigen::Matrix4f delta_transformation_ ) { const size_t N xs.size(); // 1.计算两个点集各自的质心 Eigen::Vector3f mu_x Eigen::Vector3f::Zero(), mu_y Eigen::Vector3f::Zero(); for(size_t i 0; i N; i) { mu_x xs[i]; mu_y ys[i]; } mu_x / N; mu_y / N; // 2.构建H矩阵 Eigen::Matrix3f H Eigen::Matrix3f::Zero(); for(size_t i 0; i N; i) { H (ys[i] - mu_y) * (xs[i] - mu_x).transpose(); } // 3.对H执行SVD分解 Eigen::JacobiSVDEigen::Matrix3f svd(H, Eigen::ComputeFullU | Eigen::ComputeFullV); Eigen::Matrix3f U svd.matrixU(); Eigen::Matrix3f V svd.matrixV(); // 4.得到R并检查行列式符号以防止镜像反射 Eigen::Matrix3f R V * U.transpose(); if(R.determinant() 0) { Eigen::Matrix3f I Eigen::Matrix3f::Identity(); I(2,2) -1; R V * I * U.transpose(); } // 5.计算t Eigen::Vector3f t; t mu_x - R * mu_y; // TODO: set output: delta_transformation_.setIdentity(); delta_transformation_.block3,1(0,3) t; delta_transformation_.block3,3(0,0) R; }3.迭代上述步骤因为寻找对应点时并不能准确地为每个yi寻找到其真正对应的xi此时只是用距离最近作为一个匹配关系但并不准确。所以需要循环上述过程直至残差或计算出的相对变换小于设定的阈值则认为找到了两帧的相对位姿变换。4.完整流程// 当前帧点云先验位姿结果点云结果位姿 bool ICPSVDRegistration::ScanMatch( const CloudData::CLOUD_PTR input_source, const Eigen::Matrix4f predict_pose, CloudData::CLOUD_PTR result_cloud_ptr, Eigen::Matrix4f result_pose ) { input_source_ input_source; CloudData::CLOUD_PTR transformed_input_source(new CloudData::CLOUD()); // 将点云根据先验位姿T(lidar(k-1)_lidar(k))进行旋转 pcl::transformPointCloud(*input_source_, *transformed_input_source, predict_pose); // init estimation: transformation_.setIdentity(); int curr_iter 0; std::vectorEigen::Vector3f xs,ys; // 目标点源点 Eigen::Matrix4f delta_transformation Eigen::Matrix4f::Identity(); while (curr_iter max_iter_) { pcl::transformPointCloud(*transformed_input_source, *transformed_input_source, delta_transformation); // 获取对应点集 size_t num_corr GetCorrespondence(transformed_input_source, xs, ys); // TODO: do not have enough correspondence -- break: size_t MIN_CORR_NUM input_source_-size() * 0.5; if(num_corr MIN_CORR_NUM) { break; } // 计算R,t GetTransform(xs, ys, delta_transformation); xs.clear(); ys.clear(); // 叠加位姿增量 transformation_ delta_transformation * transformation_; Eigen::Matrix3f R transformation_.block3,3(0,0); Eigen::Quaternionf q(R); q.normalize(); transformation_.block3,3(0,0) q.toRotationMatrix(); // 阈值判断 if(!IsSignificant(delta_transformation, trans_eps_)) { break; } curr_iter; } // set output: result_pose transformation_ * predict_pose; pcl::transformPointCloud(*input_source_, *result_cloud_ptr, result_pose); return true; }注目标点集也可以是一团局部地图点云先验位姿predict_pose也可以是T(map_lidar(k))。结尾推荐深蓝学院的《多传感器融合定位》课程。

相关新闻

LLM集成前必答6大问题:从需求匹配到成本控制的实战指南

LLM集成前必答6大问题:从需求匹配到成本控制的实战指南

1. 引言:为什么在集成LLM前需要深思熟虑?在当前的AI浪潮中,大语言模型(LLM)已成为众多企业和开发者眼中的"万能钥匙"。无论是智能客服、内容生成,还是代码辅助、数据分析,LLM似乎都能…

2026/7/26 22:38:01阅读更多 →
基于YOLOv8的输电线路智能检测系统实践

基于YOLOv8的输电线路智能检测系统实践

1. 项目背景与核心价值输电线路作为电力系统的"大动脉",其安全稳定运行直接关系到整个电网的可靠性。然而在户外复杂环境中,输电设备常年面临绝缘子破损、防雷器外壳损坏、鸟巢筑造、风筝缠绕、垃圾附着等多重威胁。传统人工巡检方式效率低下&…

2026/7/26 22:38:01阅读更多 →
Jellium Desktop网络连接优化:提升连接稳定性的技巧

Jellium Desktop网络连接优化:提升连接稳定性的技巧

Jellium Desktop网络连接优化:提升连接稳定性的技巧 【免费下载链接】jellium-desktop An unofficial desktop client for Jellyfin 项目地址: https://gitcode.com/GitHub_Trending/je/jellium-desktop Jellium Desktop是一款非官方的Jellyfin桌面客户端&am…

2026/7/26 22:36:01阅读更多 →
OMAP-L137高速接口设计:USB 2.0与HPI时序参数解析与工程实践

OMAP-L137高速接口设计:USB 2.0与HPI时序参数解析与工程实践

1. 项目概述与核心价值在嵌入式系统开发,尤其是基于德州仪器(TI)OMAP-L137这类异构多核处理器的项目中,硬件接口的稳定性和可靠性是项目成功的基石。我们常常把目光聚焦在软件算法和系统架构上,但一个不稳定的物理层连…

2026/7/27 1:36:42阅读更多 →
go2rtc:5分钟搞定视频流转发,让所有摄像头在浏览器中流畅播放

go2rtc:5分钟搞定视频流转发,让所有摄像头在浏览器中流畅播放

go2rtc:5分钟搞定视频流转发,让所有摄像头在浏览器中流畅播放 【免费下载链接】go2rtc Ultimate camera streaming application 项目地址: https://gitcode.com/GitHub_Trending/go/go2rtc 你是否遇到过这样的烦恼?家里的智能摄像头只…

2026/7/27 1:36:42阅读更多 →
AM389x引脚配置全解析:从终端功能表到硬件设计避坑指南

AM389x引脚配置全解析:从终端功能表到硬件设计避坑指南

1. 项目概述与核心价值在嵌入式硬件设计的深水区,引脚配置是连接芯片灵魂与物理世界的桥梁,也是最容易“踩坑”的地方。今天,我们聚焦德州仪器(TI)的AM389x系列高性能处理器,特别是AM3894和AM3892这两款芯片…

2026/7/27 1:36:42阅读更多 →
DDrawCompat:终极DirectX兼容性解决方案,让经典游戏在现代Windows完美运行

DDrawCompat:终极DirectX兼容性解决方案,让经典游戏在现代Windows完美运行

DDrawCompat:终极DirectX兼容性解决方案,让经典游戏在现代Windows完美运行 【免费下载链接】DDrawCompat DirectDraw and Direct3D 1-7 compatibility, performance and visual enhancements for Windows Vista, 7, 8, 10 and 11 项目地址: https://gi…

2026/7/27 1:36:42阅读更多 →
论文查重与AIGC检测技术解析与应用指南

论文查重与AIGC检测技术解析与应用指南

1. 项目概述:论文查重与AIGC检测的双重保障需求毕业季来临,学术诚信问题再次成为焦点。传统查重工具已无法满足当前需求,AI生成内容(AIGC)的泛滥让教育机构不得不升级检测手段。Paperzz推出的"查重AIGC检测"…

2026/7/27 1:36:42阅读更多 →
人工智能训练师三级·从零到拿证完全指南|77篇全系列导读(2026版)

人工智能训练师三级·从零到拿证完全指南|77篇全系列导读(2026版)

人工智能训练师三级从零到拿证完全指南|77篇全系列导读(2026版) 摘要:本专栏是人工智能训练师三级考证最完整的备考指南,共77篇文章,覆盖从职业认知、报名实操、AI基础知识、数据标注、模型训练测试部署、考…

2026/7/27 1:34:42阅读更多 →
覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

覆盖国产 + 海外 + 开源模型,OpenClaw 2.7.9 Windows/Mac 双端部署详解

🔹 工具基础介绍 OpenClaw 是开源生态中一款实用性较强的本地智能工具,凭借本地离线运行、可视化图形操作和任务自动化三大核心特性,赢得了众多用户的青睐。与普通在线对话AI工具不同,它属于能够直接操控本机软硬件的智能数字员工…

2026/7/27 1:14:34阅读更多 →
伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

伺服阀焊完微漏毁整机?精密激光焊接三关锁住高压

所谓液压伺服阀体的精密激光焊接,是用激光束对阀座壳体(通常为不锈钢或铝合金)进行密封焊接,使阀体在21-35MPa的高压液压油或压缩气体中长期运行而不发生介质泄漏。液压伺服阀是高端液压系统的"大脑"。从航空航天飞行控…

2026/7/27 1:14:52阅读更多 →
D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南

D2DX:三步实现《暗黑破坏神2》高清宽屏体验的终极指南 【免费下载链接】d2dx D2DX is a complete solution to make Diablo II run well on modern PCs, with high fps and better resolutions. 项目地址: https://gitcode.com/gh_mirrors/d2/d2dx 你是否还在…

2026/7/27 1:14:56阅读更多 →
SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

SPI实战指南:从时钟模式到寄存器配置,解决嵌入式通信难题

1. 项目概述:从寄存器手册到实战指南 如果你手头有一份类似德州仪器(TI)TMS320x240xA系列DSP的SPI模块技术手册,看着里面密密麻麻的寄存器位定义、时序图和公式,是不是感觉头大?这份资料虽然权威&#xff0…

2026/7/27 0:00:24阅读更多 →
【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

【JAVA毕设源码分享】基于springboot的水果购物管理系统的设计与实现(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/7/27 0:00:24阅读更多 →
2007-2023年各市区县生态文明建设示范区DID

2007-2023年各市区县生态文明建设示范区DID

数据简介 自改革开放以来,我国依赖高投入、高资源消耗和高污染等传统发展模式实现了经济短期内的快速增长, 然而这也导致了严重的生态环境危机。因此,国家有力于推动企业高质量经济发展,协同生态保护的方针,从而从201…

2026/7/27 0:00:24阅读更多 →
YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

YOLOv8推理性能优化:从1.2FPS到35FPS的全链路加速实践

如果你在部署 YOLOv8 时,发现推理速度只有可怜的 1-2 FPS,而别人的演示视频却能跑到 30 FPS 以上,那么问题很可能不在模型本身,而在于你的整个处理链路。很多开发者拿到一个训练好的 YOLOv8 模型后,会直接使用官方示例…

2026/7/25 23:03:25阅读更多 →
Coze与Dify对比指南:低代码AI应用开发从入门到实战

Coze与Dify对比指南:低代码AI应用开发从入门到实战

1. 从零到一:为什么你需要了解 Coze 和 Dify?如果你对 AI 应用开发感兴趣,但一看到“大模型”、“智能体”、“工作流”这些词就头疼,觉得门槛太高,那这篇文章就是为你准备的。很多开发者,包括我自己&#…

2026/7/26 19:05:21阅读更多 →
AI生图工具怎么选?2026年6月版实测对比

AI生图工具怎么选?2026年6月版实测对比

做自媒体的朋友应该都有体会:配图一直是个让人头疼的问题。2026年,AI生图工具已经非常成熟了,但工具太多反而不知道怎么选。以下是截至2026年6月我对主流AI生图工具的实测对比。Midjourney V8.1:速度之王2026年6月11日&#xff0c…

2026/7/26 19:05:21阅读更多 →