我在Matlab中合并了两个点云对象,比如pc1和pc2pc1是参考云,即pc2中与pc1中的点相等或非常接近的所有点需要在组合云之前移除。
澄清:
我知道函数pcmerge,它几乎可以做我想做的事情-但我肯定需要删除多余的点,平均这些点不是一个选项
每个点云的大小大约为500000个,我必须比较其中的许多(100个)所以速度很重要。
我更希望能够定义一个半径围绕每个点的pc1,以给出一个标准,为“冗余”但是为了加快速度,一些简化是可以的(参见我的第二种解决方法)。
解决方法:
一个有效但非常缓慢的解决方案是在pc2中查找其最近邻居的每个点:

function [ pc ] = pcaddcloud( pc1, pc2, res )

limits = overlapRange(pc2, pc1);
pc1idx = findPointsInROI(pc2, limits);
pc2Overlap = select(pc2, pc1idx);
idx = findPointsInROI(pc1, limits);
pc1Overlap = select(pc1, idx);
endi = pc2Overlap.Count;
pc2Overlap = pc2Overlap.Location;
for i=1:endi
    [idx, ~] = findNeighborsInRadius(pc1Overlap, pc2Overlap(i,:), res);
    % keep only indices of redundant points to delete them later
    if isempty(idx)
        pc1idx(i) = 0;
    end
end
pc1idx(pc1idx==0) = [];
pc2 = pc2.Location;
pc2(pc1idx,:) = [];
pc = pointCloud([pc1.Location; pc2]);
end

% Compute the bounding box of overlapped region (from pcmerge)
function rangeLimits = overlapRange(pcA, pcB)
xlimA = pcA.XLimits;
ylimA = pcA.YLimits;
zlimA = pcA.ZLimits;

xlimB = pcB.XLimits;
ylimB = pcB.YLimits;
zlimB = pcB.ZLimits;

if (xlimA(1) > xlimB(2) || xlimA(2) < xlimB(1) || ...
        ylimA(1) > ylimB(2) || ylimA(2) < ylimB(1) || ...
        zlimA(1) > zlimB(2) || zlimA(2) < zlimB(1))
    % No overlap
    rangeLimits = [];
else
    rangeLimits = [ min(xlimA(1),xlimB(1)), max(xlimA(2),xlimB(2)); ...
        min(ylimA(1),ylimB(1)), max(ylimA(2),ylimB(2)); ...
        min(zlimA(1),zlimB(1)), max(zlimA(2),zlimB(2))];
end
end

我有一个更快的解决方案(仍然很慢,但比解决方案1更快)处理阿尔法形状:我定义了一个围绕pc1的外壳,并决定pc2的点是否在里面缺点:仅“稍外”(即接近pc1点但不在alpha形状内)的点不会被检测为冗余。
function [ pc ] = pcaddcloud( pc1, pc2 )

limits = overlapRange(pc2, pc1);
pc2 = pc2.Location;
pc1 = pc1.Location;
%seems to be faster than findPointsInROI:
pc2Overlap = pc2(pc2(:,1)>=limits(1,1)&pc2(:,1)<=limits(1,2) ...
    &pc2(:,2)>=limits(2,1)&pc2(:,2)<=limits(2,2)...
    &pc2(:,3)>=limits(3,1)&pc2(:,3)<=limits(3,2),:);
pc2idx = find(pc2(:,1)>=limits(1,1)&pc2(:,1)<=limits(1,2) ...
    &pc2(:,2)>=limits(2,1)&pc2(:,2)<=limits(2,2)...
    &pc2(:,3)>=limits(3,1)&pc2(:,3)<=limits(3,2));
pc1Overlap = pc1(pc1(:,1)>=limits(1,1)&pc1(:,1)<=limits(1,2) ...
    &pc1(:,2)>=limits(2,1)&pc1(:,2)<=limits(2,2)...
    &pc1(:,3)>=limits(3,1)&pc1(:,3)<=limits(3,2),:);

shape = alphaShape(double(pc1Overlap));
in = inShape(shape, double(pc2Overlap));
pc2idx(~in) = [];
pc2(pc2idx,:) = [];
pc = pointCloud([pc1; pc2]);

end

% Compute the bounding box of overlapped region (from pcmerge)
function rangeLimits = overlapRange(pcA, pcB)
xlimA = pcA.XLimits;
ylimA = pcA.YLimits;
zlimA = pcA.ZLimits;

xlimB = pcB.XLimits;
ylimB = pcB.YLimits;
zlimB = pcB.ZLimits;

if (xlimA(1) > xlimB(2) || xlimA(2) < xlimB(1) || ...
        ylimA(1) > ylimB(2) || ylimA(2) < ylimB(1) || ...
        zlimA(1) > zlimB(2) || zlimA(2) < zlimB(1))
    % No overlap
    rangeLimits = [];
else
    rangeLimits = [ min(xlimA(1),xlimB(1)), max(xlimA(2),xlimB(2)); ...
        min(ylimA(1),ylimB(1)), max(ylimA(2),ylimB(2)); ...
        min(zlimA(1),zlimB(1)), max(zlimA(2),zlimB(2))];
end
end

我很期待你的想法如果需要的话,请随时询问更多信息-我是这个平台的新手谢谢您!

最佳答案

您可以使用ismembertolByRows选项来检测冗余点但是考虑一下,它使用立方邻域而不是球面邻域。
假设有两个矩阵,pc1每个矩阵有3列和一个公差:

idx = ismembertol(pc2, pc1, tol,'ByRows', true, 'DataScale' , 1);
result = [pc1; pc2(~idx,:)];

关于matlab - 在Matlab中删除冗余点的快速方法,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/53008033/

10-12 03:48