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

Matlab通过GUI实现点云的GICP配准

        本节分享的是使用Matlab进行点云的GICP配准。GICP(Generalized Iterative Closest Point,广义迭代最近点)是 ICP 算法的改进版本,核心优势在于引入高斯混合模型(GMM)描述点云分布,并通过最大化两点云间的概率相似度实现配准,而非仅依赖 “最近点距离最小化”。相比传统 ICP,GICP 具有:

  • 更强鲁棒性:可处理点云密度不均、噪声干扰场景;

  • 更高精度:考虑点云局部几何特征(如法向量、协方差);

  • 更快收敛:通过概率模型优化迭代方向,减少迭代次数。

一、 MATLAB 对 GICP 的支持

MATLAB 通过Computer Vision Toolbox提供 GICP 点云配准的完整工具链,核心函数包括:

  • pcregistergicp:执行 GICP 配准,输出配准后点云及变换矩阵;

  • pcpreprocess:点云预处理(去噪、下采样),为配准优化输入数据;

  • pcshowpair:可视化配准前后两点云的叠加效果,辅助结果验证;

  • pccorrespondences:计算点云对应关系,可用于配准过程监控。

二、MATLAB 中 GICP 点云配准主要流程

1. 步骤 1:点云数据准备

  • 数据获取:导入待配准的两点云(源点云source、目标点云target),支持格式包括.pcd、.ply、.las等,通过pcread函数读取:

source = pcread('source.pcd'); % 源点云(待变换点云)target = pcread('target.pcd'); % 目标点云(参考点云)
  • 预处理优化

  • 去噪:用pcpreprocess去除孤立噪声点(基于统计滤波):
source = pcpreprocess(source, 'NumNeighbors', 10, 'Sigma', 1.5);target = pcpreprocess(target, 'NumNeighbors', 10, 'Sigma', 1.5);
  • 下采样:若点云密度过高,通过pcdownsample降低点数(保留关键几何特征),提升配准效率:
source = pcdownsample(source, 'gridAverage', 0.05); % 栅格尺寸0.05mtarget = pcdownsample(target, 'gridAverage', 0.05);

2. 步骤 2:初始配准(可选但关键)

GICP 需依赖初始变换姿态(避免陷入局部最优),若两点云初始偏差较大,需先执行粗配准:

  • 常用方法:基于特征的配准(如 SIFT、FPFH),或使用 MATLAB 内置的 ICP 粗配准函数pcregistericp(设置InitialTransform参数):

% 粗配准获取初始变换矩阵[~, initT] = pcregistericp(source, target, 'Metric', 'pointToPlane');

3. 步骤 3:GICP 配准参数设置与执行

调用pcregistergicp函数,核心参数需根据场景调整:

% 执行GICP配准[registeredSource, tform] = pcregistergicp(source, % 源点云target, % 目标点云'InitialTransform', initT, % 初始变换矩阵'MaxIterations', 200, % 最大迭代次数(默认100)'ConvergenceThreshold', 1e-6, % 收敛阈值(位置/姿态变化小于该值停止)'CovarianceEstimation', 'knn', % 协方差估计方式(knn/grid,默认knn)'NumNeighbors', 15 % 协方差估计的邻域点数(默认10));
  • 输出说明:registeredSource为配准后源点云,tform为 4×4 刚体变换矩阵(包含平移 + 旋转)。

4. 步骤 4:配准结果评估与可视化

  • 定量评估:计算配准后两点云的均方根误差(RMSE),反映配准精度:

% 计算对应点对距离correspondences = pccorrespondences(registeredSource, target);distances = sqrt(sum((correspondences.SourcePoints - correspondences.TargetPoints).^2, 2));rmse = mean(distances); % RMSE越小,精度越高
  • 定性可视化:用pcshowpair对比配准前后效果:

figure;% 配准前(红色:源点云,蓝色:目标点云)subplot(1,2,1); pcshowpair(source, target, 'VerticalAxis', 'Y', 'HorizontalAxis', 'X');title('配准前');% 配准后subplot(1,2,2); pcshowpair(registeredSource, target, 'VerticalAxis', 'Y', 'HorizontalAxis', 'X');title(['配准后(RMSE=' num2str(rmse) ')']);

三、GICP 点云配准的应用领域

1. 三维重建领域

  • 场景:文物数字化、建筑三维建模、工业零件逆向工程;

  • 应用逻辑:通过多视角(如激光雷达、结构光相机)采集点云,用 GICP 配准拼接为完整三维模型,解决 “单视角点云遮挡” 问题;

  • MATLAB 优势:预处理工具链完善,可快速处理百万级点云,可视化结果便于模型验证。

2. 自动驾驶领域

  • 场景:激光雷达(LiDAR)点云与高精地图(HD Map)匹配、多传感器(LiDAR + 相机)数据融合;

  • 应用逻辑:通过 GICP 将实时 LiDAR 点云与预存高精地图配准,实现车辆定位(精度达厘米级),适应雨天、强光等复杂环境;

  • 核心需求:GICP 的鲁棒性可抵抗点云噪声(如路面杂物干扰),快速收敛满足实时性要求(MATLAB 可通过 GPU 加速进一步提升效率)。

3. 工业检测领域

  • 场景:零件尺寸公差检测、装配精度验证;

  • 应用逻辑:将实测零件点云与设计模型(CAD 导出点云)通过 GICP 配准,计算对应点距离偏差,判断是否符合公差标准;

  • MATLAB 价值:支持与 CAD 软件(如 SolidWorks)数据交互,pcregistergicp的高精度特性可满足工业级检测需求(公差≤0.1mm)。

4. 机器人导航领域

  • 场景:室内移动机器人定位、仓储机器人环境感知;

  • 应用逻辑:机器人携带深度相机采集环境点云,通过 GICP 与预建地图配准,实现自主定位与路径规划;

  • 适配性:GICP 对动态障碍物(如行人、货架)的鲁棒性,优于传统 ICP,减少导航偏差。

本次使用的数据。。。。兔呗

一、点云GICP配准的程序

1、最简版

%% GICP_Register_Fusion.m —— MATLAB 2024a 兼容(修复版)
clc; clear; close all;%% 1. 读取源点云
[file, path] = uigetfile({'*.pcd;*.ply','点云文件 (*.pcd,*.ply)'}, ...'请选择点云(例如 bunny.pcd)');
if file==0; return; end
sourcePtCloud = pcread(fullfile(path,file));%% 2. 生成目标点云(修复只读属性问题)
rotAngle = 30;          % 旋转角度(度,绕Z轴)
transVec = [0.1 0.15 0.2];  % 平移向量
noiseStd = 0.0005;      % 低噪声标准差
targetPtCloud = createTargetCloud(sourcePtCloud, rotAngle, transVec, noiseStd);%% 3. GICP配准(保留简洁传参)
[tform, regPtCloud, rmse] = pcregistericp(sourcePtCloud, targetPtCloud, ...'Metric', 'pointToPlane', ...'MaxIterations', 35, ...'InlierDistance', 0.2);%% 4. 可视化结果
figure('Name','初始点云','Color','w');
pcshowpair(sourcePtCloud, targetPtCloud);
title('红色=源点云,绿色=目标点云(含旋转+平移+噪声)');figure('Name','GICP配准结果','Color','w');
pcshowpair(regPtCloud, targetPtCloud);
title(['红色=配准后点云,绿色=目标点云 | RMSE = ' num2str(rmse,'%.6f')]);%% 5. 多指标评估(修复距离计算函数)
evalResult = evaluateReg(regPtCloud, targetPtCloud, 0.2);
disp('================ 配准评估结果 ================');
disp(['内点比例:' num2str(evalResult.inlierRatio,'%.2f%%')]);
disp(['平均距离:' num2str(evalResult.meanDist,'%.6f')]);
disp(['RMSE(均方根误差):' num2str(evalResult.rmse,'%.6f')]);
disp('=============================================');%% 子函数1:生成目标点云(修复只读属性问题)
function targetCloud = createTargetCloud(sourceCloud, rotAngle, transVec, noiseStd)srcPoints = sourceCloud.Location;  % N×3 源点坐标% 步骤1:计算点云中心并平移到原点cloudCenter = mean(srcPoints, 1);pointsCentered = srcPoints - cloudCenter;% 步骤2:绕Z轴旋转rotRad = deg2rad(rotAngle);rotMat = [cos(rotRad) -sin(rotRad) 0;sin(rotRad)  cos(rotRad) 0;0           0           1];pointsRotated = (rotMat * pointsCentered')';% 步骤3:平移回原中心 + 额外平移pointsTranslated = pointsRotated + cloudCenter + transVec;% 步骤4:添加噪声pointsNoisy = pointsTranslated + noiseStd * randn(size(pointsTranslated));% 关键修复:创建新的pointCloud对象(而非修改原有对象的Location)targetCloud = pointCloud(pointsNoisy, ...'Normal', sourceCloud.Normal, ...'Color', repmat([0 1 0], size(pointsNoisy,1), 1));
end%% 子函数2:配准多指标评估(用knnsearch替代pcpdist)
function result = evaluateReg(regCloud, targetCloud, inlierThresh)% 获取两点云的坐标regPoints = regCloud.Location;    % M×3 矩阵targetPoints = targetCloud.Location;  % N×3 矩阵% 计算每个配准点到目标点云中最近点的距离(替代pcpdist)% 使用knnsearch寻找最近邻,兼容更多MATLAB版本[~, dists] = knnsearch(targetPoints, regPoints);  % 输出为列向量% 计算评估指标result.inlierRatio = mean(dists < inlierThresh) * 100;  % 内点比例(%)result.meanDist = mean(dists);                          % 平均距离result.rmse = sqrt(mean(dists.^2));                    % RMSE
end

2、GUI版本

function GICP_Register_GUI
%GICP_Register_GUI 基于GICP算法的点云配准GUI(三栏视图)
% 兼容MATLAB 2024a,无需额外工具箱
clc; clear; close all;%% ---------------- 主窗口 ----------------
fig = figure('Name','GICP 配准工具', 'NumberTitle','off', ...'MenuBar','none', 'ToolBar','none', ...'Position',[100 100 1280 720], 'Color','w');%% ---------------- 布局常量 ----------------
imgWidth = 0.78;               % 三栏总宽
panelW   = imgWidth/3 - 0.005; % 单栏宽
gap      = 0.005;%% ---------------- 三栏 axes ----------------
pnlSrc = uipanel('Parent',fig, 'Units','normalized', ...'FontSize',16, 'Position',[0.02 0.02 panelW 0.96], ...'Title','源点云(红)');
pnlTgt = uipanel('Parent',fig, 'Units','normalized', ...'FontSize',16, ...'Position',[0.02+panelW+gap 0.02 panelW 0.96], ...'Title','目标点云(绿)');
pnlReg = uipanel('Parent',fig, 'Units','normalized', ...'FontSize',16, ...'Position',[0.02+2*(panelW+gap) 0.02 panelW 0.96], ...'Title','GICP 配准后(红→绿)');axSrc = axes('Parent',pnlSrc, 'Units','normalized', 'Position',[0.05 0.05 0.9 0.9]);
axTgt = axes('Parent',pnlTgt, 'Units','normalized', 'Position',[0.05 0.05 0.9 0.9]);
axReg = axes('Parent',pnlReg, 'Units','normalized', 'Position',[0.05 0.05 0.9 0.9]);%% ---------------- 控制面板 ----------------
pnlCtrl = uipanel('Parent',fig, 'Units','normalized', ...'FontSize',16, 'Position',[0.78 0 0.22 1], ...'Title','控制');txtH  = 0.04;  btnH = 0.06;  yTop = 0.94;% ① 加载
uicontrol('Parent',pnlCtrl, 'Style','pushbutton', 'String','浏览…', ...'FontSize',16, 'Units','normalized', ...'Position',[0.05 yTop-btnH 0.9 btnH], ...'Callback',@loadCloud);
yTop = yTop - btnH - 0.02;% 状态提示
lblInfo = uicontrol('Parent',pnlCtrl, 'Style','text', ...'String','未加载点云', 'FontSize',10, ...'Units','normalized', ...'Position',[0.05 yTop-txtH 0.9 txtH], ...'HorizontalAlignment','left');
yTop = yTop - txtH - 0.02;% ② 噪声标准差 / m
uicontrol('Parent',pnlCtrl, 'Style','text', 'String','噪声标准差 / m', ...'FontSize',12, 'FontWeight','bold', 'Units','normalized', ...'Position',[0.05 yTop-txtH 0.9 txtH], 'HorizontalAlignment','left');
yTop = yTop - txtH - 0.01;sliderNoise = uicontrol('Parent',pnlCtrl, 'Style','slider', ...'Min',0, 'Max',0.01, 'Value',0.0005, ...'Units','normalized', ...'Position',[0.05 yTop-btnH 0.65 btnH], ...'Callback',@refreshTarget);
txtNoise    = uicontrol('Parent',pnlCtrl, 'Style','edit', 'String','0.0005', ...'FontSize',14, 'Units','normalized', ...'Position',[0.75 yTop-btnH 0.2 btnH], ...'Callback',@editNoiseCB);
yTop = yTop - btnH - 0.02;% ③ 旋转角度 / 度
uicontrol('Parent',pnlCtrl, 'Style','text', 'String','旋转角度(Z轴)/ 度', ...'FontSize',12, 'FontWeight','bold', 'Units','normalized', ...'Position',[0.05 yTop-txtH 0.9 txtH], 'HorizontalAlignment','left');
yTop = yTop - txtH - 0.01;sliderRot = uicontrol('Parent',pnlCtrl, 'Style','slider', ...'Min',0, 'Max',180, 'Value',30, ...'Units','normalized', ...'Position',[0.05 yTop-btnH 0.65 btnH], ...'Callback',@refreshTarget);
txtRot    = uicontrol('Parent',pnlCtrl, 'Style','edit', 'String','30', ...'FontSize',14, 'Units','normalized', ...'Position',[0.75 yTop-btnH 0.2 btnH], ...'Callback',@editRotCB);
yTop = yTop - btnH - 0.02;% ④ 平移偏移 / m
uicontrol('Parent',pnlCtrl, 'Style','text', 'String','平移偏移 / m', ...'FontSize',12, 'FontWeight','bold', 'Units','normalized', ...'Position',[0.05 yTop-txtH 0.9 txtH], 'HorizontalAlignment','left');
yTop = yTop - txtH - 0.01;uicontrol('Parent',pnlCtrl, 'Style','text', 'String','X', ...'FontSize',10, 'Units','normalized', ...'Position',[0.05 yTop-txtH 0.15 txtH]);
editX = uicontrol('Parent',pnlCtrl, 'Style','edit', 'String','0.1', ...'FontSize',14, 'Units','normalized', ...'Position',[0.20 yTop-txtH 0.20 txtH], ...'Callback',@refreshTarget);uicontrol('Parent',pnlCtrl, 'Style','text', 'String','Y', ...'FontSize',10, 'Units','normalized', ...'Position',[0.45 yTop-txtH 0.15 txtH]);
editY = uicontrol('Parent',pnlCtrl, 'Style','edit', 'String','0.15', ...'FontSize',14, 'Units','normalized', ...'Position',[0.60 yTop-txtH 0.20 txtH], ...'Callback',@refreshTarget);uicontrol('Parent',pnlCtrl, 'Style','text', 'String','Z', ...'FontSize',10, 'Units','normalized', ...'Position',[0.05 yTop-2*txtH 0.15 txtH]);
editZ = uicontrol('Parent',pnlCtrl, 'Style','edit', 'String','0.2', ...'FontSize',14, 'Units','normalized', ...'Position',[0.20 yTop-2*txtH 0.20 txtH], ...'Callback',@refreshTarget);
yTop = yTop - 2*txtH - 0.02;% ⑤ GICP参数
uicontrol('Parent',pnlCtrl, 'Style','text', 'String','GICP 参数', ...'FontSize',12, 'FontWeight','bold', 'Units','normalized', ...'Position',[0.05 yTop-txtH 0.9 txtH], 'HorizontalAlignment','left');
yTop = yTop - txtH - 0.01;uicontrol('Parent',pnlCtrl, 'Style','text', 'String','最大迭代次数', ...'FontSize',10, 'Units','normalized', ...'Position',[0.05 yTop-txtH 0.4 txtH], 'HorizontalAlignment','left');
editMaxIter = uicontrol('Parent',pnlCtrl, 'Style','edit', 'String','35', ...'FontSize',14, 'Units','normalized', ...'Position',[0.50 yTop-txtH 0.45 txtH]);uicontrol('Parent',pnlCtrl, 'Style','text', 'String','内点距离阈值', ...'FontSize',10, 'Units','normalized', ...'Position',[0.05 yTop-2*txtH 0.4 txtH], 'HorizontalAlignment','left');
editInlierDist = uicontrol('Parent',pnlCtrl, 'Style','edit', 'String','0.2', ...'FontSize',14, 'Units','normalized', ...'Position',[0.50 yTop-2*txtH 0.45 txtH]);
yTop = yTop - 2*txtH - 0.02;% ⑥ 运行 GICP
uicontrol('Parent',pnlCtrl, 'Style','pushbutton', 'String','运行 GICP 配准', ...'FontSize',16, 'Units','normalized', ...'Position',[0.05 yTop-btnH 0.9 btnH], ...'Callback',@runGICP);
yTop = yTop - btnH - 0.02;% ⑦ 评估结果显示
uicontrol('Parent',pnlCtrl, 'Style','text', 'String','配准评估结果', ...'FontSize',12, 'FontWeight','bold', 'Units','normalized', ...'Position',[0.05 yTop-txtH 0.9 txtH], 'HorizontalAlignment','left');
yTop = yTop - txtH - 0.01;lblInlier = uicontrol('Parent',pnlCtrl, 'Style','text', 'String','内点比例:--', ...'FontSize',10, 'Units','normalized', ...'Position',[0.05 yTop-txtH 0.9 txtH], 'HorizontalAlignment','left');
yTop = yTop - txtH;lblMeanDist = uicontrol('Parent',pnlCtrl, 'Style','text', 'String','平均距离:--', ...'FontSize',10, 'Units','normalized', ...'Position',[0.05 yTop-txtH 0.9 txtH], 'HorizontalAlignment','left');
yTop = yTop - txtH;lblRMSE = uicontrol('Parent',pnlCtrl, 'Style','text', 'String','RMSE:--', ...'FontSize',10, 'Units','normalized', ...'Position',[0.05 yTop-txtH 0.9 txtH], 'HorizontalAlignment','left');
yTop = yTop - txtH - 0.02;% ⑧ 保存
uicontrol('Parent',pnlCtrl, 'Style','pushbutton', 'String','保存配准结果', ...'FontSize',16, 'Units','normalized', ...'Position',[0.05 yTop-btnH 0.9 btnH], ...'Callback',@(s,e)saveCloud(ptCloudReg));%% ---------------- 数据容器 ----------------
ptCloudSrc = pointCloud.empty;
ptCloudTgt = pointCloud.empty;
ptCloudReg = pointCloud.empty;
tform = [];
rmse = 0;%% ---------------- 回调函数 ----------------function loadCloud(~,~)[file,path] = uigetfile({'*.ply;*.pcd;*.xyz','点云文件'},'选择点云');if isequal(file,0); return; endtryptCloudSrc = pcread(fullfile(path,file));catch MEerrordlg(ME.message,'读取失败'); return;endset(lblInfo,'String',sprintf('已加载:%s  (%d 点)',file,ptCloudSrc.Count));refreshTarget();endfunction refreshTarget(~,~)if isempty(ptCloudSrc); return; end% 1. 读取界面参数noiseStd = get(sliderNoise,'Value');rotAngle = get(sliderRot,'Value');t = [str2double(get(editX,'String'));str2double(get(editY,'String'));str2double(get(editZ,'String'))];  % 3×1if any(isnan(t));  t = [0.1; 0.15; 0.2]; endtransVec = t.';  % 1×3% 2. 生成目标点云ptCloudTgt = createTargetCloud(ptCloudSrc, rotAngle, transVec, noiseStd);% 3. 上色区分ptCloudSrc.Color = repmat(uint8([255 0 0]),size(ptCloudSrc.Location,1),1);  % 红色ptCloudTgt.Color = repmat(uint8([0 255 0]),size(ptCloudTgt.Location,1),1);  % 绿色% 4. 显示点云showPointCloud(axSrc,ptCloudSrc);showPointCloud(axTgt,ptCloudTgt);% 5. 清空上次结果ptCloudReg = pointCloud.empty;cla(axReg); title(axReg,'GICP 配准后(红→绿)');% 6. 清空评估结果set(lblInlier, 'String', '内点比例:--');set(lblMeanDist, 'String', '平均距离:--');set(lblRMSE, 'String', 'RMSE:--');% 7. 同步滑竿文本set(txtNoise,'String',num2str(get(sliderNoise,'Value')));set(txtRot,'String',num2str(get(sliderRot,'Value')));endfunction editNoiseCB(src,~)v = str2double(get(src,'String'));if isnan(v); v=0.0005; endv = max(0,min(0.01,v));  % 限制范围set(sliderNoise,'Value',v);refreshTarget();endfunction editRotCB(src,~)v = str2double(get(src,'String'));if isnan(v); v=30; endv = max(0,min(180,v));  % 限制范围set(sliderRot,'Value',v);refreshTarget();endfunction runGICP(~,~)if isempty(ptCloudSrc) || isempty(ptCloudTgt)errordlg('请先加载点云','提示'); return;end% 获取GICP参数maxIter = str2double(get(editMaxIter,'String'));if isnan(maxIter) || maxIter <= 0; maxIter = 35; endinlierDist = str2double(get(editInlierDist,'String'));if isnan(inlierDist) || inlierDist <= 0; inlierDist = 0.2; end% GICP配准try[tform, regPtCloud, rmse] = pcregistericp(ptCloudSrc, ptCloudTgt, ...'Metric', 'pointToPlane', ...'MaxIterations', maxIter, ...'InlierDistance', inlierDist);catch MEerrordlg(ME.message,'配准失败'); return;endptCloudReg = regPtCloud;ptCloudReg.Color = repmat(uint8([255 0 0]),size(ptCloudReg.Location,1),1);% 可视化配准结果showPointCloud(axReg,ptCloudReg); hold(axReg,'on');pcshow(ptCloudTgt,'Parent',axReg); hold(axReg,'off');title(axReg,'GICP 配准结果:红→绿');% 评估配准结果evalResult = evaluateReg(ptCloudReg, ptCloudTgt, inlierDist);% 更新评估结果显示set(lblInlier, 'String', sprintf('内点比例:%.2f%%', evalResult.inlierRatio));set(lblMeanDist, 'String', sprintf('平均距离:%.6f', evalResult.meanDist));set(lblRMSE, 'String', sprintf('RMSE:%.6f', evalResult.rmse));endfunction saveCloud(cloud)if isempty(cloud)errordlg('请先运行 GICP 配准','提示'); return;end[file,path] = uiputfile({'*.pcd','PCD';'*.ply','PLY';'*.xyz','XYZ'},'保存配准点云');if isequal(file,0); return; endtrypcwrite(cloud,fullfile(path,file),'Precision','double');msgbox('保存成功!','提示');catch MEerrordlg(ME.message,'保存失败');endendfunction showPointCloud(ax,pc)cla(ax); set(ax,'Color','w');pcshow(pc,'Parent',ax,'MarkerSize',35);axis(ax,'tight'); grid(ax,'on'); view(ax,3); drawnow;end%% ---------------- 子函数1:生成目标点云 ----------------function targetCloud = createTargetCloud(sourceCloud, rotAngle, transVec, noiseStd)srcPoints = sourceCloud.Location;  % N×3 源点坐标% 步骤1:计算点云中心并平移到原点cloudCenter = mean(srcPoints, 1);pointsCentered = srcPoints - cloudCenter;% 步骤2:绕Z轴旋转rotRad = deg2rad(rotAngle);rotMat = [cos(rotRad) -sin(rotRad) 0;sin(rotRad)  cos(rotRad) 0;0           0           1];pointsRotated = (rotMat * pointsCentered')';% 步骤3:平移回原中心 + 额外平移pointsTranslated = pointsRotated + cloudCenter + transVec;% 步骤4:添加噪声pointsNoisy = pointsTranslated + noiseStd * randn(size(pointsTranslated));% 创建新的pointCloud对象targetCloud = pointCloud(pointsNoisy, ...'Normal', sourceCloud.Normal, ...'Color', repmat([0 1 0], size(pointsNoisy,1), 1));end%% ---------------- 子函数2:配准多指标评估 ----------------function result = evaluateReg(regCloud, targetCloud, inlierThresh)% 获取两点云的坐标regPoints = regCloud.Location;    % M×3 矩阵targetPoints = targetCloud.Location;  % N×3 矩阵% 计算每个配准点到目标点云中最近点的距离[~, dists] = knnsearch(targetPoints, regPoints);  % 输出为列向量% 计算评估指标result.inlierRatio = mean(dists < inlierThresh) * 100;  % 内点比例(%)result.meanDist = mean(dists);                          % 平均距离result.rmse = sqrt(mean(dists.^2));                    % RMSEend
end

二、点云进行GICP配准的结果

        我有罪,我忏悔,我不该抛弃matlab2020a,以上程序使用的是2024a。不过该说不说,高级版本是真的好用哎。话又说回来,既然人家开发了好的工具,为嘛不用呢,君子性非异也,善假于物也。你说是不?

就酱,下次见^-6

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

相关文章:

  • 数字化ERP“一图四清单”战略执行体系
  • 每日一练【约瑟夫环问题】
  • 公司网站推广计划书怎么做网络工程好就业吗
  • 找网站网站防止镜像
  • 监理网站网站ipv6改造怎么做 网页代码
  • 新公司如何做网站wordpress文本块表格
  • 无锡富通电力建设有限公司网站html个人主页制作
  • 重庆微信营销网站建设wordpress用户导入数据库表
  • 网站分类导航代码企业建设网站哪家好
  • ID 生成方案
  • h5开发环境搭建重庆网站seo搜索引擎优化
  • 小程序api的使用搜索引擎排名优化方案
  • 网站怎么才能被搜到微网站排版
  • 建设银行积分网站宿迁网站推广公司
  • 企业电子商务网站的建设方式logo设计公司标志
  • [论文阅读] AI+SRE(网站可靠性工程) | 字节跳动ErrorPrism:微服务错误追踪准确率97%!告别日志“一团乱麻”
  • 打开无忧管理后台网站网站建设 中企动力 常州
  • 装饰公司网站模板17网一起做网店网站
  • 怎么做自己的发卡网站6打开百度地图导航
  • html网页结构文件厦门关键词排名seo
  • 网站建设 嘉兴网站建设 方案书
  • 淄博网站文章优化php网站开发开发实例教程
  • 项目中HTTP协议处理部分(续)
  • 南京网站开发南京乐识不错wordpress文章阅读数
  • 宠物网站设计说明书上海建设网站公司
  • 网站建设具体要求吴江区经济开发区建设工程网站
  • wordpress建外贸网站网站建设专员 岗位职责
  • pc网站同步手机网站千度搜索引擎
  • AI 算力加速指南(中端篇):RTX 3060/i7-12 代 / 16G 内存的多任务优化实战,从卡顿到并行(一)
  • Ymodem协议详解