【问题标题】:Fast plane fitting to many points多点的快速平面拟合
【发布时间】:2014-06-19 21:38:56
【问题描述】:

我正在寻找适合一组约 6-10k 3D 点的平面。我希望尽可能快地做到这一点,而准确性并不是最关心的问题(坦率地说,飞机在任何基本轴上都可以偏离 +-10 度)。

我目前的方法是使用最佳拟合,但速度非常慢(我希望每次运行算法时以大约 10-50k 次的速度提取平面,并且以这个速度完成周,而不是几个小时),因为它适用于 6000 点的所有可能组合,因此大约 35,000,000,000 次迭代,坦率地说,它的准确度比我需要的要高得多。

有人知道任何较弱的平面拟合技术可以大大加快我的算法吗?

编辑:

通过在每个可能的 3D 角度创建平面(每次以 5 度步进)并针对这些点测试现有点以找到最佳平面,而不是拟合飞机到我所拥有的点。

我敢肯定,通过分而治之也能获得一些东西,尽管我担心我会直接跳过最好的飞机。

【问题讨论】:

  • 您可以访问Curve Fitting Toolbox吗?
  • 不幸的是,我没有,我被 vanilla MATLAB 困住了,虽然我有很多编程经验,所以我应该能够处理一个相当复杂的算法。
  • 如果准确性不是您主要关心的问题,请尝试降低数据的输入复杂性。在最初的 6-10k 点上运行 kmeans 或其他东西,然后将平面拟合到样本。
  • @Ansari:好主意。为了进一步提高性能,获取随机点子集可能就足够了。

标签: performance matlab plane


【解决方案1】:

使用标准平面方程Ax + By + Cz + D = 0,并将方程写成矩阵乘法。 P 是你的未知数4x1 [A;B;C;D]

g = [x y z 1];  % represent a point as an augmented row vector
g*P = 0;        % this point is on the plane

现在将其扩展到所有实际点,一个 Nx4 矩阵 G。结果不再是 0,而是您试图最小化的错误。

G*P = E;   % E is a Nx1 vector

所以你想要的是最接近 G 的零空间的向量,可以从 SVD 中找到。让我们测试一下:

% Generate some test data
A = 2;
B = 3;
C = 2.5;
D = -1;

G = 10*rand(100, 2);  % x and y test points
% compute z from plane, add noise (zero-mean!)
G(:,3) = -(A*G(:,1) + B*G(:,2) + D) / C + 0.1*randn(100,1);

G(:,4) = ones(100,1);   % augment your matrix

[u s v] = svd(G, 0);
P = v(:,4);             % Last column is your plane equation

好的,请记住 P 可以随标量变化。所以只是为了表明我们匹配:

scalar = 2*P./P(1);
P./scalar

ans = 2.0000 3.0038 2.5037 -0.9997

【讨论】:

    【解决方案2】:

    在计算机视觉中,根据您的情况,标准方法是使用 RANSAC 或 MSAC;

    1. 从总体中随机抽取 3 个点
    2. 计算由 3 个点定义的平面
    3. 将所有点到该平面的误差(到平面的距离)相加。
    4. 保留显示误差总和最小的 3 个点(并且在阈值内)。
    5. 重复 N 次迭代(参见 RANSAC 理论选择 N,我可以建议 50 次吗?)

    http://en.wikipedia.org/wiki/RANSAC

    【讨论】:

      【解决方案3】:

      看起来griddata 可能是您想要的。该链接中有一个示例。

      如果这不起作用,请查看 MATLAB File Exchange 上的 gridfit。它是为了匹配比griddata 更一般的情况。

      您可能不想滚动自己的曲面拟合,因为那里有几个文档齐全的工具。

      griddata为例:

      x = % some values 
      y = % some values
      z = % function values to fit to
      
      ti = % this range should probably be greater than or equal to your x,y test values
      [xq,yq] = meshgrid(ti,ti);
      zq = griddata(x,y,z,xq,yq,'linear'); % NOTE: linear will fit to a plane!
      Plot the gridded data along with the scattered data.
      
      mesh(xq,yq,zq), hold
      plot3(x,y,z,'o'), hold off
      

      【讨论】:

      • 非常感谢,我会马上调查的。我通常更多来自 CS 背景,所以我的表面拟合数学有点落后。因此,我很乐意让其他人的代码完成这项工作
      • 嗯,我对 griddata 的问题是,为了让它为我提供飞机,我必须(基于他们的第一个示例)告诉它使用 (-1) 处的 4 个点生成 zq ,-1), (-1,1), (1,-1), (1,1) (使用 2:-2 - 示例中数据集的边界 - 出于某种原因仅返回 NaN)。不幸的是,这似乎保证了飞机的拐角在 (-1,-1), (-1,1), (1,-1), (1,1) 并且似乎没有考虑更多点。如果我增加点数,我将不再得到飞机。
      • @NickUdell 在你的答案中加入一些你尝试过的代码,这样我可以为你提供更多帮助。
      【解决方案4】:

      您可以试试 John D'Errico 的 consolidator。它聚合给定容差内的点,这将允许减少数据量并提高速度。您还可以查看 John 的 gridfit 函数,该函数通常比 griddata 更快、更灵活

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2016-12-09
        • 2015-06-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2010-11-02
        • 2018-06-20
        相关资源
        最近更新 更多