如何在 MATLAB 中插值和平滑 3D 点云?
How can I interpolate and smooth 3D point clouds in MATLAB?
我希望得到一些帮助来解决我面临的点云数据处理问题。基本上,我有很多零散且嘈杂的点云数据。因此,我的目标是对“斑块区域”中缺失的数据进行近似,并应用某种形式的光平滑来过滤噪声。
我第一次尝试解决这个问题是使用 MATLAB 中的插值方法。这是按如下方式执行并提供了良好的结果,因为工作 XY 网格上的内插 Z 点看起来像我期望的形状。
% Load Point Cloud:
Point_Cloud = importdata(‘Point_Cloud_1.txt')
x = Point_Cloud(1,:)';
y = Point_Cloud(2,:)';
z = Point_Cloud(3,:)';
% Interpolate inspection points:
Density = 300;
[X,Y] = meshgrid(linspace(min(x), max(x), Density), linspace(min(y), max(y), Density));
F = scatteredInterpolant(x, y, z, 'natural','linear');
Z = F(X,Y);
Int_PC = [reshape(X,Density^2,1) reshape(Y,Density^2,1) reshape(Z,Density^2,1)];
Int_PC(any(isnan(Int_PC{i}),2),:) = [];
% Plot results:
scatter3(x, y, z, 20, 'r', 'fill'); % Original data
hold on;
scatter3(Int_PC(:,1), Int_PC(:,2), Int_PC(:,3), 20, 'r', 'fill'); % Interpolated data
这个问题是噪声数据被用来计算插值 F,所以上面的代码只解决了数据不完整的问题。
然后我考虑使用曲线拟合工具箱进行样条拟合。薄板平滑样条似乎是有意义的,因为它接受分散的(非网格化)数据并且不对所有点进行插值,从而平滑噪声。代码如下。执行时,结果令人失望,因为原始点和计算表面之间的拟合非常差(超出了平滑噪声所需的范围)。
Spline = tpaps([x;y],z);
fnplt(Spline)
有人可以提出任何解决方案吗?
谢谢。
一个命题,使用 Savitzky-Golay 过滤器:
所以
- 使用这个过滤器
- 使用您的代码完成缺失的部分。
示例
%We build the noisy 3D point cloud
[X,Y] = meshgrid(0:0.1:4.9,0:0.1:4.9);
Z = sin(X)+cos(Y)+0.5*rand(50,50);
% The smoothing (with sgolayfilt(Z,order,length of the moving windows))
t1 = sgolayfilt(Z.',2,25); %smoothing over the x-axis
t2 = sgolayfilt(Z,2,25); %smoothing over the y-axis
t = (t1.'+t2)/2; %smoothing in booth directions
surf(X,Y,t)
平滑前
平滑后
编辑
相同的操作,但数据分散:
%random X and Y
X = rand(100,1)*5;
Y = rand(100,1)*5;
Z = sin(X)+cos(Y);
%Calculate the interpolant
F = scatteredInterpolant(X,Y,Z);
%Fix the grid size
gs = 0.1; %grid size
tx = min(X(:)):gs:max(X(:));
tz = min(Y(:)):gs:max(Y(:));
%Scattered X,Y to gridded x,y
[x,y] = meshgrid(tx,ty);
%Interpolation over z-axis
z = F(x,y);
t1 = sgolayfilt(z.',2,5);
t2 = sgolayfilt(z,2,5);
t = (t1.'+t2)/2;
surf(X,Y,t)
colormap winter
我希望得到一些帮助来解决我面临的点云数据处理问题。基本上,我有很多零散且嘈杂的点云数据。因此,我的目标是对“斑块区域”中缺失的数据进行近似,并应用某种形式的光平滑来过滤噪声。
我第一次尝试解决这个问题是使用 MATLAB 中的插值方法。这是按如下方式执行并提供了良好的结果,因为工作 XY 网格上的内插 Z 点看起来像我期望的形状。
% Load Point Cloud:
Point_Cloud = importdata(‘Point_Cloud_1.txt')
x = Point_Cloud(1,:)';
y = Point_Cloud(2,:)';
z = Point_Cloud(3,:)';
% Interpolate inspection points:
Density = 300;
[X,Y] = meshgrid(linspace(min(x), max(x), Density), linspace(min(y), max(y), Density));
F = scatteredInterpolant(x, y, z, 'natural','linear');
Z = F(X,Y);
Int_PC = [reshape(X,Density^2,1) reshape(Y,Density^2,1) reshape(Z,Density^2,1)];
Int_PC(any(isnan(Int_PC{i}),2),:) = [];
% Plot results:
scatter3(x, y, z, 20, 'r', 'fill'); % Original data
hold on;
scatter3(Int_PC(:,1), Int_PC(:,2), Int_PC(:,3), 20, 'r', 'fill'); % Interpolated data
这个问题是噪声数据被用来计算插值 F,所以上面的代码只解决了数据不完整的问题。
然后我考虑使用曲线拟合工具箱进行样条拟合。薄板平滑样条似乎是有意义的,因为它接受分散的(非网格化)数据并且不对所有点进行插值,从而平滑噪声。代码如下。执行时,结果令人失望,因为原始点和计算表面之间的拟合非常差(超出了平滑噪声所需的范围)。
Spline = tpaps([x;y],z);
fnplt(Spline)
有人可以提出任何解决方案吗?
谢谢。
一个命题,使用 Savitzky-Golay 过滤器:
所以
- 使用这个过滤器
- 使用您的代码完成缺失的部分。
示例
%We build the noisy 3D point cloud
[X,Y] = meshgrid(0:0.1:4.9,0:0.1:4.9);
Z = sin(X)+cos(Y)+0.5*rand(50,50);
% The smoothing (with sgolayfilt(Z,order,length of the moving windows))
t1 = sgolayfilt(Z.',2,25); %smoothing over the x-axis
t2 = sgolayfilt(Z,2,25); %smoothing over the y-axis
t = (t1.'+t2)/2; %smoothing in booth directions
surf(X,Y,t)
平滑前
平滑后
编辑
相同的操作,但数据分散:
%random X and Y
X = rand(100,1)*5;
Y = rand(100,1)*5;
Z = sin(X)+cos(Y);
%Calculate the interpolant
F = scatteredInterpolant(X,Y,Z);
%Fix the grid size
gs = 0.1; %grid size
tx = min(X(:)):gs:max(X(:));
tz = min(Y(:)):gs:max(Y(:));
%Scattered X,Y to gridded x,y
[x,y] = meshgrid(tx,ty);
%Interpolation over z-axis
z = F(x,y);
t1 = sgolayfilt(z.',2,5);
t2 = sgolayfilt(z,2,5);
t = (t1.'+t2)/2;
surf(X,Y,t)
colormap winter