Analysis of a 3D point cloud by projection in a 2D surface

后端 未结 2 1524
借酒劲吻你
借酒劲吻你 2021-02-09 11:51

I have a 3D point cloud (XYZ) where the Z can be position or energy. I want to project them on a 2D surface in a n-by-m grid (in my problem

相关标签:
2条回答
  • 2021-02-09 12:43

    The accumarray function is quite suited for this kind of task. First I define example data:

    table = [ 20*rand(1000,1) 30*rand(1000,1) 40*rand(1000,1)]; % random data
    x_partition = 0:2:20; % partition of x axis
    y_partition = 0:5:30; % partition of y axis
    

    I'm assuming that

    • The three columns of table represent x, y, z respectively
    • No point has x lower than that of first edge of your grid or greater than last edge, and the same for y. That is, the grid covers all points.
    • If a bin contains no values the result should be NaN (if you want some other fill value, just change last argument of accumarray).

    Then:

    L = size(table,1);
    M = length(x_partition);
    N = length(y_partition);
    [~, ii] = max(repmat(table(:,1),1,M) <= repmat(x_partition,L,1),[],2);
    [~, jj] = max(repmat(table(:,2),1,N) <= repmat(y_partition,L,1),[],2);
    ii = ii-1; % by assumption, all values in ii will be at least 2, so we subtract 1
    jj = jj-1; % same for jj
    result_maxdif = accumarray([ii jj], table(:,3), [M-1 N-1], @(v) max(v)-min(v), NaN);
    result_sum = accumarray([ii jj], table(:,3), [M-1 N-1], @sum, NaN);
    

    Notes to the code:

    • The key is obtaining ii and jj, which give the indices of the x and y bins in which each point lies. I use repmat to do that. It would have been better to usebsxfun, but it doesn't support the multiple-output version of @max.
    • The result has size (M-1) x (N-1) (numbers of bins in each dimension)
    0 讨论(0)
  • 2021-02-09 12:54

    Remarks:

    1. all this can be almost one-liner via python pandas and cutting methods.
    2. I've rewritten your random cloud initialization

    What you can do is

    1. layout an xy grid via meshgrid,
    2. project the cloud on xy (simple marginalization)
    3. find the nearest grid point via a kd-tree search, i.e. label your data associating to each cloud point a grid node
    4. group data by label and evaluate your local statistic (via accumarray).

    Here's a working example:

     samples = 500;
     %data extrema
     xl = 0; xr = 1; yl = 0; yr = 1;
    
     % # grid points
     sz = 20;
     % # new random cloud    
     table = [random('Uniform',xl,xr,[samples,1]) , random('Uniform',yr,yl,[samples,1]), random('normal',1,1,[samples,1])];
    
     figure; scatter3(table(:,1),table(:,2),table(:,3));
    
     % # grid construction
     xx = linspace(xl,xr,sz); yy = linspace(yl,yr,sz);
     [X,Y] = meshgrid(xx,yy);
     grid_centers = [X(:),Y(:)];
    
     x = table(:,1); y = table(:,2); 
    
     % # kd-tree
     kdtreeobj = KDTreeSearcher(grid_centers);
     clss = kdtreeobj.knnsearch([x,y]); % # classification
    
     % # defintion of local statistic
     local_stat = @(x)sum(x) % # for total energy
     % local_stat = @(x)max(x)-min(x) % # for position off-set
    
     % # data_grouping
     class_stat = accumarray(clss,table(:,3),[],local_stat );       
     class_stat_M  = reshape(class_stat , size(X)); % # 2D reshaping
    
     figure; contourf(xx,yy,class_stat_M,20); 
    

    enter image description here enter image description here

    0 讨论(0)
提交回复
热议问题