代码之家  ›  专栏  ›  技术社区  ›  Pyy

如何在MATLAB中插值和平滑3D点云?

  •  1
  • Pyy  · 技术社区  · 8 年前

    我希望能在我面临的点云数据处理问题上获得一些帮助。基本上,我有很多零星杂乱的点云数据。因此,我的目标是近似数据,在斑块区域中缺失数据,并应用某种形式的光平滑来过滤噪声。

    我第一次尝试解决这个问题的是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
    

    这方面的问题是,noisey数据用于计算插值F,所以上面的代码只解决了不完整的数据问题。

    然后,我考虑使用曲线拟合工具箱进行样条曲线拟合。薄板平滑样条线似乎很有意义,因为它接受分散的(非网格化的)数据,并且不插值所有点,从而平滑噪声。其代码如下。执行时,结果令人失望,因为原始点和计算曲面之间的拟合非常差(超出平滑噪波所需的范围)。

    Spline = tpaps([x;y],z);
    fnplt(Spline)
    

    Thin plate spline example

    有人能提出解决方案吗?

    谢谢

    1 回复  |  直到 8 年前
        1
  •  3
  •   obchardon    8 年前

    使用Savitzky-Golay过滤器的一个主张是:

    所以

    1. 使用此筛选器
    2. 使用您的代码来完成缺少的部分。

    例子

    %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)
    

    平滑之前

    before

    平滑后

    after

    编辑

    相同操作,但数据分散:

    %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