按均值合并点云中的相似点

Merge similar points in point cloud by its mean

我有一组 x,y,z 坐标,其中每个 z 值都有一些相似的 x,y 值(不相同但相似)。这意味着当我绘制 3D 对象时,一些点在每个帧中重复(对于每个 z)并且这些点也有一点点移动,因为对象在获取数据时可能会移动一点点。

每一帧中重复点的数量可以不同。为了点位置的准确性,我无法消除那些重复的点。我必须将它们合并到质心位置并构建 3D 对象。

我的部分数据如下所示: 其中,z 在每一帧中增加 1 的值,我为此得到一组 x,y 值。

211.312500 242.803571 5.000000
213.864407 267.259887 5.000000
211.986111 214.125000 5.000000
224.198864 298.812500 5.000000
233.244444 225.170370 5.000000
238.354067 249.894737 5.000000
240.807692 198.725275 5.000000
247.603922 281.317647 5.000000
251.493671 316.481013 5.000000
260.176796 223.276243 5.000000
269.823529 256.522876 5.000000
276.506073 188.214575 5.000000
276.941176 292.972851 5.000000
286.388060 327.701493 5.000000
291.673684 223.368421 5.000000
302.773913 261.330435 5.000000
309.080189 300.816038 5.000000
315.031746 196.456349 5.000000
331.283784 231.896396 5.000000
338.495327 271.518692 5.000000
345.351064 303.595745 5.000000
362.117647 243.806723 5.000000
185.085714 256.892857 6.000000
193.821918 287.328767 6.000000
192.929293 227.070707 6.000000
210.651163 242.682171 6.000000
211.977654 213.435754 6.000000
213.306122 266.918367 6.000000
214.909091 183.415584 6.000000
224.152941 298.235294 6.000000
223.957746 327.887324 6.000000
233.672131 225.754098 6.000000
240.058091 198.863071 6.000000
238.150943 250.150943 6.000000
244.044586 170.891720 6.000000
246.847561 280.390244 6.000000
250.793651 316.892857 6.000000
263.232143 354.392857 6.000000
272.419643 157.517857 6.000000
275.139423 187.812500 6.000000
285.312217 327.692308 6.000000
304.767606 167.133803 6.000000
313.893519 195.916667 6.000000
317.795238 334.623810 6.000000
330.388430 230.388430 6.000000
337.775510 271.877551 6.000000
345.485294 304.955882 6.000000
355.268456 206.140940 6.000000
362.585635 243.928177 6.000000
372.008850 279.336283 6.000000
184.281818 255.945455 7.000000
185.614035 201.964912 7.000000
193.048673 286.907080 7.000000
192.668790 227.694268 7.000000
202.280000 316.160000 7.000000
214.126829 184.546341 7.000000
212.371795 212.762821 7.000000
212.763636 266.836364 7.000000
224.266332 298.502513 7.000000
224.325758 327.977273 7.000000
233.230088 349.371681 7.000000
239.947977 199.000000 7.000000
243.050251 170.839196 7.000000
250.298246 317.192982 7.000000
262.468900 354.789474 7.000000
271.629213 156.535581 7.000000
285.615385 328.750000 7.000000
296.467949 358.865385 7.000000
304.243697 165.693277 7.000000
312.126761 196.197183 7.000000
317.313725 334.406863 7.000000
337.482759 177.057471 7.000000
344.804598 305.028736 7.000000
354.792929 205.030303 7.000000
362.387500 243.662500 7.000000
371.720000 279.490000 7.000000

好吧,我猜了很多,但我们拭目以待。

首先为了完整起见,您的数据(已缩短):

data = [...
211.312500 242.803571 5.000000
...
362.387500 243.662500 7.000000
371.720000 279.490000 7.000000]

然后你需要设置一个阈值,你建议1.5我宁愿至少3

thresh = 3;

然后算法:

%// sort rows, first regarding column 1, then 2
s = sortrows(data,[1 2]);

%// get differences
sdiff = diff([0 0 0; s],1,1);

%// creat mask with threshold
mask = (abs(sdiff(:,1)) < thresh) & (abs(sdiff(:,2)) < thresh);

%// assign indices to "similar" values
subs = cumsum(~mask);

%// calculate the means of similar values
xmean = accumarray(subs,s(:,1),[],@mean)
ymean = accumarray(subs,s(:,2),[],@mean)

%// create new filtered dataset
fdata = [xmean(subs) ymean(subs) s(:,3)]

%// optional: resort data
fdata = sortrows(fdata,3);

以及结果,在每种情况下,最大 z 的点在顶部:

figure(1)
subplot(121)
scatter(data(:,1),data(:,2),[],data(:,3))
title('unfiltered')
xlim([150,400])
ylim([150,400])
colormap(jet)
subplot(122)
scatter(fdata(:,1),fdata(:,2),[],data(:,3))
title('filtered')
xlim([150,400])
ylim([150,400])

这是你想要的吗?如果不是,你需要更清楚,post一个例子。

如您所见,它没有完全过滤单个点,您可以通过重新运行不同排序的算法来修复它:

s = sortrows(data,[2 1]);

编辑:正如您所说,您需要运行 5-6 次,您可以使用这样的循环:

fdata = data;
for i = 1:5
    shiftvec = circshift([1 2],i,2);
    s = sortrows(fdata,shiftvec);
    sdiff = diff([0 0 0; s],1,1);
    mask = (abs(sdiff(:,1)) < thresh) & (abs(sdiff(:,2)) < thresh);
    subs = cumsum(~mask);
    xmean = accumarray(subs,s(:,1),[],@mean);
    ymean = accumarray(subs,s(:,2),[],@mean);
    fdata = [xmean(subs) ymean(subs) s(:,3)]; 
    fdata = sortrows(fdata,3); 
end

最终结果: