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文库

  • 18
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: MATLAB点云工具箱是一个用于处理、分析和可视化点云数据的工具包。它为用户提供了一套丰富的功能,可以进行点云的读取、处理、滤波、配准、分割等操作。 首先,点云工具箱允许用户从激光扫描仪、摄像机等设备中导入点云数据。用户可以通过直接读取点云文件或使用传感器接口来获取点云数据。通过这个工具箱,用户可以轻松地获取各种类型的点云数据。 其次,点云工具箱提供了多种点云处理算法,包括滤波、配准、分割等。对于不规则、噪声干扰较大的点云数据,用户可以使用滤波算法对其进行平滑处理,提高数据的质量。此外,用户还可以将多个点云数据进行配准操作,实现不同坐标系下的点云数据的对齐和融合。在进行某些特定任务时,用户可以通过分割算法将点云数据进行分块,提取感兴趣的区域。 再次,点云工具箱还提供了一系列的可视化函数,用于显示和分析点云数据。用户可以通过三维点云显示函数将点云数据可视化为三维模型,以便更直观地观察和分析数据。同时,该工具箱还提供了灰度、彩色、深度图像的显示函数,方便用户查看点云数据的各个方面。 总之,MATLAB点云工具箱是一个功能强大、便捷易用的工具包,可用于点云数据的处理、分析和可视化。无论是在工程领域还是研究领域,该工具箱都为用户提供了丰富的功能,可以大大提高点云数据处理的效率和准确性。 ### 回答2: MATLAB点云工具箱是一个用于处理和分析三维点云数据的功能强大的工具包。它提供了一系列算法和函数,可以方便地进行点云的操作、可视化和模型拟合等任务。 首先,点云工具箱提供了读取和保存点云数据的函数,支持多种点云文件格式,如PLY、PCD等。这可以方便地从各种设备或软件中导入和导出点云数据。 其次,点云工具箱包含了一系列对点云数据进行处理和分析的函数。例如,可以进行点云的滤波、降采样、变换和配准等操作。通过这些函数,可以对原始点云数据进行预处理,提高数据质量和准确性。 此外,点云工具箱还提供了一些用于点云可视化的函数和工具。可以将点云数据以各种方式呈现出来,比如散点图、网格图和体素图等。这样,我们可以更直观地观察点云的形状、结构和特征。 在模型拟合方面,点云工具箱提供了一些常用的算法,比如最小二乘法和RANSAC。这些算法可以用来估计点云数据的参数模型,如平面、曲面和直线等。通过模型拟合,可以对点云数据进行更进一步的分析和应用。 总之,MATLAB点云工具箱是一个功能丰富的工具包,可以方便地处理和分析三维点云数据。它提供了丰富的函数和算法,支持点云的读取、处理、可视化和模型拟合等任务,为点云数据的研究和应用提供了便利。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

jjm2002

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值