Matlab使用点云工具箱进行点云配准ICP\NDT\CPD

一、代码

主代码main.m,三种配准方法任选其一

% 读取点云文件
source_pc = pcread('bun_zipper.ply');
target_pc = pcread('bun_zipper2.ply');% 下采样
ptCloudA = point_downsample(source_pc);
ptCloudB = point_downsample(target_pc);% 配准参数设置
opt = param_set("icp");
% opt = param_set("ndt");
% opt = param_set("cpd");
% 执行点云配准
[tform,translation,rotation,registered_pc] = icp_r(ptCloudA,ptCloudB,source_pc,opt);
% [tform,translation,rotation,registered_pc] = ndt_r(ptCloudA,ptCloudB,source_pc,opt);
% [tform,translation,rotation,registered_pc] = cpd_r(ptCloudA,ptCloudB,opt);
cal_and_print_data(tform,translation,rotation);% 可视化
pc_visualization(ptCloudA, ptCloudB, target_pc, registered_pc);

配准参数设置

function[opt] = param_set(name, varargin)
p = inputParser;
addParameter(p,'Metric','pointToPoint');
addParameter(p,'Extrapolate',true);
addParameter(p,'InlierRatio',0.9);
addParameter(p,'Tolerance',[0.01, 0.01]);
addParameter(p,'MaxIterations',100);
addParameter(p,'Verbose',true);
addParameter(p,'method','rigid');
addParameter(p,'viz',0);
addParameter(p,'max_it',100);
addParameter(p,'tol',1e-6);
parse(p,varargin{:});
Metric = p.Results.Metric;
Extrapolate = p.Results.Extrapolate;
InlierRatio = p.Results.InlierRatio;
Tolerance = p.Results.Tolerance;
MaxIterations = p.Results.MaxIterations;
Verbose = p.Results.Verbose;
method = p.Results.method;
viz = p.Results.viz;
max_it = p.Results.max_it;
tol = p.Results.tol;
opt = containers.Map();
if name=="icp" || name == "ndt"opt('Metric') = Metric;opt('Extrapolate') = Extrapolate;opt('InlierRatio') = InlierRatio;opt('Tolerance') = Tolerance;opt('MaxIterations') = MaxIterations;opt('Verbose') = Verbose;
elseif name == "cpd"opt('method') = method;opt('viz') = viz;opt('max_it') = max_it;opt('tol') = tol;
end

icp函数代码icp_r.m

function [tform,translation,rotation,registered_pc] = icp_r(ptCloudA, ptCloudB, source_pc, opt)% tform 是一个 rigid3d 类型的对象,包含了配准后的转换矩阵。
% 参数说明:
% 'Metric' - 配准的度量类型,可以是 'pointToPoint'(默认值)或 'pointToPlane',
%            'pointToPoint' 直接最小化点之间的距离,
%            'pointToPlane' 最小化点到面的距离,通常更快收敛但需要法线信息。
% 'Extrapolate' - 用于加速算法,如果设置为 true,算法会用前两次迭代的变换来预测下一步的变换。
% 'InlierRatio' - 预期的内点比例,范围从 0 到 1。内点是最有可能对应于固定点云中点的移动点云中的点。
% 'MaxIterations' - ICP算法的最大迭代次数。
% 'Tolerance' - 一个包含两个元素的向量,第一个元素是均方根变化容忍度,第二个元素是最小迭代改变容忍度。
% 'Verbose' - 如果设置为 true,将在命令窗口中显示算法的进度信息。
tform = pcregistericp(ptCloudA,ptCloudB, 'Metric', opt('Metric'), ...'Extrapolate', opt('Extrapolate'), ...'InlierRatio', opt('InlierRatio'), ...'Tolerance', opt('Tolerance'), ...'MaxIterations', opt('MaxIterations'), ...'Verbose', opt('Verbose'));
% 提取平移向量
translation = tform.T(4, 1:3);
% 提取旋转矩阵
rotation = tform.T(1:3, 1:3);
% 应用配准变换到源点云
registered_pc = pctransform(source_pc, tform);end

ndt函数代码ndt_r.m,由于matlab点云工具箱没有提供相关的特征提取函数,所以采用icp粗配准获得初始变换矩阵,再进行ndt精配准

function[tform,translation,rotation,registered_pc] = ndt_r(ptCloudA, ptCloudB, source_pc,opt)
% 使用 ICP 算法进行粗略配准,获取初始变换矩阵
tform = pcregistericp(ptCloudA,ptCloudB, 'Metric', opt('Metric'), ...'Extrapolate', opt('Extrapolate'), ...'InlierRatio', opt('InlierRatio'), ...'Tolerance', opt('Tolerance'), ...'MaxIterations', opt('MaxIterations'), ...'Verbose', opt('Verbose'));
% 使用 NDT 算法进行精确配准
% 参数说明:
% gridSize - 用于创建用于 NDT 算法的体素网格的大小。较小的值可能会提高精度,但会增加计算成本。
% 'MaxIterations' - NDT算法的最大迭代次数。
% 'Tolerance' - 一个包含两个元素的向量:
%               tolerance1 - 迭代之间变换的最大容忍度。
%               tolerance2 - 均方根误差的最大容忍度。
% 'InitialTransform' - 配准之前的初始变换,这是一个 rigid3d 类型的对象。
% 'Verbose' - 如果设置为 true,将在命令窗口中显示算法的进度信息。% tform 是一个 rigid3d 类型的对象,包含了配准后的变换矩阵。
gridStep =0.1; % 网格大小
tform = pcregisterndt(ptCloudA, ptCloudB, gridStep, ...'MaxIterations', opt('MaxIterations'), ...'Tolerance', opt('Tolerance'), ...'InitialTransform', tform, ... % 使用单位矩阵作为初始变换'Verbose', opt('Verbose'));
% 提取平移向量
translation = tform.T(4, 1:3);
% 提取旋转矩阵
rotation = tform.T(1:3, 1:3);
% 应用配准变换到源点云
registered_pc = pctransform(source_pc, tform);
end

cpd函数代码cpd_r.m,这个cpd配准还需要额外的cpd工具箱

function[tform,translation,rotation,registered_pc] = cpd_r(ptCloudA,ptCloudB, opt)
% 转换为双精度的坐标矩阵
X = double(ptCloudA.Location);
Y = double(ptCloudB.Location);
% 设置CPD选项,根据需要调整参数
op.method = opt('method'); % 使用非刚性变换,也可以选择 'rigid' 或 'affine'
op.viz = opt('viz');             % 显示配准过程
op.max_it = opt('max_it');        % 最大迭代次数
op.tol = opt('tol');          % 收敛容忍度% 执行CPD配准
[tform, C] = cpd_register(Y, X, op);
% 提取平移向量
translation = tform.t;% 提取旋转矩阵
rotation = tform.R;
registered_pc = pointCloud(tform.Y);
end

点云下采样

function[ptCloud] = point_downsample(pc)
gridStep = 0.005;
ptCloud = pcdownsample(pc,'gridAverage',gridStep);
end

计算并打印相关位姿信息

function[] = cal_and_print_data(tform,translation,rotation)% 将旋转矩阵转换为欧拉角\四元数
eulerAngles = rotm2eul(rotation);
quat = rotm2quat(rotation);
%打印信息
fprintf('变换矩阵:')
disp(tform)
fprintf('平移量 (x, y, z): %.4f, %.4f, %.4f\n', translation(1), translation(2), translation(3));
fprintf('欧拉角 (rx, ry, rz): %.4f, %.4f, %.4f\n', rad2deg(eulerAngles(3)), rad2deg(eulerAngles(2)), rad2deg(eulerAngles(1)));
fprintf('四元数 (w, x, y, z): %.4f, %.4f, %.4f, %.4f\n', quat(1), quat(2), quat(3), quat(4));
end

可视化

function[] = pc_visualization(ptCloudA, ptCloudB, target_pc, registered_source_pc)
figure("Name", "原图像与配准后的图像");
set(gcf,'position',[150 80 1000 800])
subplot(2,1,1)
pcshowpair(ptCloudA, ptCloudB, 'MarkerSize', 20,'BackgroundColor',"white");
title('原图像');
xlabel('X-axis');
ylabel('Y-axis');
zlabel('Z-axis');
view(2)
legend('Target Point Cloud', 'Source Point Cloud');
%figure("Name", "配准后的图像");
subplot(2,1,2)
pcshowpair(target_pc, registered_source_pc, 'MarkerSize', 20,'BackgroundColor',"white");
title('配准后的图像');
xlabel('X-axis');
ylabel('Y-axis');
zlabel('Z-axis');
view(2)
legend('Target Point Cloud', 'Registered Source Point Cloud');% 调整子图之间的距离
h = gcf; % 获取当前图形的句柄
h.Children(1).Position(2) = h.Children(1).Position(2) + 0.05; % 调整第一个子图的位置
h.Children(2).Position(2) = h.Children(2).Position(2) - 0.05; % 调整第二个子图的位置
end

二、结果

icp结果

ndt结果

cpd结果

三种方法实验下来,两个点云基本都是z轴有45度的相对转角

三、工具箱安装和示例文件

点云工具箱:链接:https://pan.baidu.com/s/1zNo03fIxP63-lOSjePCcLg 
提取码:wstc 

cpd工具箱:链接:https://pan.baidu.com/s/1-Um4pRcYJOAKLWjeuL-zlA 
提取码:wstc 
示例文件:链接:https://pan.baidu.com/s/1ql_q4jnUZjlZL3l3fRo8vQ 
提取码:wstc 

完整代码:matlab点云配准,包括ICP/NDT/CPD算法资源-CSDN文库

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://xiahunao.cn/news/2778184.html

如若内容造成侵权/违法违规/事实不符,请联系瞎胡闹网进行投诉反馈,一经查实,立即删除!

相关文章

node网站 宝塔 面板配置 防止刷新404

1.问题 我现在配置了一个网站 后台项目 放到了宝塔上 将相应的域名和项目都配置好了 域名也可以访问 但是有的时候 出现了404 类似这种404 这个资源找不到 2.说明 其实这个问题的原因是nginx 的问题 反向代理的原因 3.解决 在这个配置文件中 有个配置文件 # 防止刷新404l…

Python算法题集_K 个一组翻转链表

Python算法题集_K 个一组翻转链表 题25:K 个一组翻转链表1. 示例说明2. 题目解析- 题意分解- 优化思路- 测量工具 3. 代码展开1) 标准求解【依次反转】2) 改进版一【列表反转】3) 改进版二【堆栈大法】4) 改进版三【递归大法】 4. 最优算法 本文为Python算法题集之一…

在JSP中实现JAVABEAN

在JSP中实现JAVABEAN 问题陈述 创建Web应用程序以连接数据库并检索作者名、地址、城市、州及邮政编码等与作者的详细信息。JavaBean组件应接受作者ID、驱动程序名及URL作为参数。信息要从authors表中检索。 解决方案 要解决上述问题,需要执行以下任务: 创建Web应用程序。创…

Backtrader 文档学习- Plotting - Plotting Date Ranges

Backtrader 文档学习- Plotting - Plotting Date Ranges 1.概述 1.9.31.x版本增加了绘制部分图形的功能。 可以使用策略实例中保留完整长度的时间戳数组的索引或者使用实际的datetime.date 或datetime.datetime 实例来限制需要绘制的内容。 仍然可以使用标准的cerebro.plot…

基于 multiprocessing.dummy 的多线程池与单线程访问多网页的比较示例

一、示例代码: from multiprocessing.dummy import Pool as ThreadPool import time import requestsurls [ # URL队列,通过多线程访问http://www.python.org,http://www.python.org/about/,http://www.…

Eclipse导入maven项目或者创建maven项目时,报错Could not calculate build plan: Plugin

问题&#xff1a;Eclipse导入maven项目或者创建maven项目时,报错Could not calculate build plan: Plugin 1.上述问题大概是项目不能加载此maven插件&#xff0c;在pom文件中添加依赖项 <dependency><groupId>org.apache.maven.plugins</groupId><artifa…

微服务入门篇:http客户端Feign(远程调用,自定义配置,Feign的性能优化,Feign服务抽取)

目录 1.基于Feign的远程调用1.RestTemplate方式调用存在的问题2.Feign的介绍3.定义和使用Feign客户端 2.自定义配置1.方式一&#xff1a;配置文件方式2.方式二: java代码方式&#xff0c;需要先声明一个Bean: 3.Feign的性能优化1.Feign底层的客户端实现2.连接池配置 4.Feign的最…

EMNLP 2023精选:Text-to-SQL任务的前沿进展(下篇)——Findings论文解读

导语 本文记录了今年的自然语言处理国际顶级会议EMNLP 2023中接收的所有与Text-to-SQL相关&#xff08;通过搜索标题关键词查找得到&#xff0c;可能不全&#xff09;的论文&#xff0c;共计12篇&#xff0c;包含5篇正会论文和7篇Findings论文&#xff0c;以下是对这些论文的略…

c语言中的隐式类型转换

数据类型转化 我们在实际编程中&#xff0c;不管你是有意的还是无意的&#xff0c;有时候都会让两个不同类型的数据参与运算&#xff0c;编译器为了能够生成CPU可以正常 执行的指令&#xff0c;往往会对数据做类型转换&#xff0c;将两个不同类型的数据转换成同一种数据类型。…

Springboot+vue的社区养老服务平台(有报告)。Javaee项目,springboot vue前后端分离项目

演示视频&#xff1a; Springbootvue的社区养老服务平台&#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot vue前后端分离项目 项目介绍&#xff1a; 本文设计了一个基于Springbootvue的前后端分离的社区养老服务平台&#xff0c;采用M&#xff08;model&…

最佳视频转换器软件:2024年视频格式转换的选择

我们生活在一个充满数字视频的世界&#xff0c;但提供的内容远不止您最喜欢的流媒体服务目录。虽然我们深受喜爱的设备在播放各种自制和下载的视频文件方面变得越来越好&#xff0c;但在很多情况下您都需要从一种格式转换为另一种格式。 经过大量测试&#xff0c; 我们尝试过…

Go 中如何解析 json 内部结构不确定的情况

本文主要介绍的是关于 Go 如何解析 json 内部结构不确定的情况。 首先&#xff0c;我们直接看一个来提问吧。 问题如下&#xff1a; 上游传递不确定的json&#xff0c;如何透传给下游业务&#xff1f;比如&#xff0c;我解析参数 {"test": 1,"key": {&…

2024年信息管理与工业制造与自动化国际学术会议(ICIMIMA2024)

2024年信息管理与工业制造与自动化国际学术会议(ICIMIMA2024) 会议简介 2024年信息管理与工业制造及自动化国际学术会议&#xff08;ICIMIMA2024&#xff09;将在中国三亚举行。会议旨在为信息管理和工业工程领域的专家、学者、工程师和技术人员提供一个平台&#xff0c;分享…

深入Java容器:概览、设计模式与源码分析

深入Java容器&#xff1a;概览、设计模式与源码分析 Java 容器一、概览Collection1. Set2. List3. Queue Map 二、容器中的设计模式迭代器模式适配器模式 三、源码分析ArrayList1. 概览2. 扩容3. 删除元素4. 序列化5. Fail-Fast Vector1. 同步2. 扩容3. 与 ArrayList 的比较4. …

人工智能算法:理解其工作原理及其在现实世界中的应用

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;已逐渐成为我们生活中不可或缺的一部分。从智能语音助手到自动驾驶汽车&#xff0c;再到医疗诊断系统&#xff0c;人工智能算法正以前所未有的速度改变着我们的世界。本文将带您深入探讨人工智能算法的工作原…

【leetcode热题100】分隔链表

给你一个链表的头节点 head 和一个特定值 x &#xff0c;请你对链表进行分隔&#xff0c;使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。 你应当 保留 两个分区中每个节点的初始相对位置。 示例 1&#xff1a; 输入&#xff1a;head [1,4,3,2,5,2], x 3 输出&am…

【开源】JAVA+Vue+SpringBoot实现班级考勤管理系统

目录 一、摘要1.1 项目介绍1.2 项目录屏 二、功能模块2.1 系统基础支持模块2.2 班级学生教师支持模块2.3 考勤签到管理2.4 学生请假管理 三、系统设计3.1 功能设计3.1.1 系统基础支持模块3.1.2 班级学生教师档案模块3.1.3 考勤签到管理模块3.1.4 学生请假管理模块 3.2 数据库设…

2024年【氧化工艺】新版试题及氧化工艺操作证考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 氧化工艺新版试题是安全生产模拟考试一点通生成的&#xff0c;氧化工艺证模拟考试题库是根据氧化工艺最新版教材汇编出氧化工艺仿真模拟考试。2024年【氧化工艺】新版试题及氧化工艺操作证考试 1、【单选题】 对现场窨…

【GO语言卵细胞级别教程】04.GO函数介绍

【GO语言卵细胞级别教程】04.GO函数介绍 目录&#xff1a; 【GO语言卵细胞级别教程】04.GO函数介绍0.创建项目1.函数的引入2.注意事项3.详细介绍3.1 形参介绍 0.创建项目 创建目录 执行命令加载模块 cd 02.gostudy目录下 1.进入目录下 cd 02.gostudy 2.初始化模块变量 go …

多线程JUC:线程池原理、自定义线程池详细解析

&#x1f468;‍&#x1f393;作者简介&#xff1a;一位大四、研0学生&#xff0c;正在努力准备大四暑假的实习 &#x1f30c;上期文章&#xff1a;多线程&JUC&#xff1a;等待唤醒机制&#xff08;生产者消费者模式&#xff09; &#x1f4da;订阅专栏&#xff1a;多线程&…