7

我有一个 3D 点云 (XYZ),其中Z可以是位置或能量。我想将它们投影在n × m网格(在我的问题n = m中)中的 2D 表面上,其方式是每个网格单元的最大差值为Z,如果Z是位置,或者总和值Z,如果Z是能量。

例如,在 的范围内0 <= (x,y) <= 20,有 500 个点。假设 xy 平面有n × m分区,例如4 × 4;我的意思是在两个x方向上我们都有 4个分区,y间隔5为定义的 xy 平面中的相应列。20Z

我制作了一个简单的 XYZ 数组,只是为了进行如下测试,在这种情况下,Z表示每个点的能量。

n=1;
for i=1:2*round(random('Uniform',1,5))
    for j=1:2*round(random('Uniform',1,5))
        table(n,:)=[i,j,random('normal',1,1)];
        n=n+1;
    end
end

没有循环如何做到这一点?

4

2 回答 2

5

accumarray功能非常适合此类任务。首先我定义示例数据:

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

我假设

  • 的三列分别table代表x,y,z
  • 没有任何点的 x 低于网格的第一个边缘或大于最后一个边缘,y 也是如此。也就是说,网格覆盖了所有点。
  • 如果 bin 不包含任何值,则结果应该是NaN(如果您想要其他填充值,只需更改 的最后一个参数accumarray)。

然后:

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

代码注释:

  • 关键是获得iijj,它给出了每个点所在的 x 和 y 箱的索引。我习惯repmat这样做。使用 会更好bsxfun,但它不支持@max.
  • 结果的大小为 (M-1) x (N-1)(每个维度中的 bin 数量)
于 2013-11-08T21:05:38.977 回答
4

评论:

  1. 通过 python pandas 和切割方法,所有这些几乎都是单行的。
  2. 我重写了你的随机云初始化

你能做的是

  1. 通过布局一个 xy 网格meshgrid
  2. 在 xy 上投影云(简单边缘化)
  3. 通过kd-tree搜索找到最近的网格点,即将与每个云点关联的数据标记为网格节点
  4. 按标签对数据进行分组并评估您的本地统计数据(通过accumarray)。

这是一个工作示例:

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

在此处输入图像描述 在此处输入图像描述

于 2013-11-08T18:54:25.013 回答