给定一组点的特征和SVD找到最佳拟合平面

时间:2016-09-07 12:47:34

标签: c++ math eigen

考虑到3D空间中的一组N个点,我试图使用SVD和Eigen找到最佳拟合平面。

我的算法是:

  1. 中心数据点(0,0,0)。
  2. 形成3xN点坐标矩阵。
  3. 计算矩阵的SVD。
  4. 将对应于最小奇异值的最小奇异向量设置为平面的法线。
  5. 设置从原点到平面的距离为正常∙质心。
  6. 我无法弄清楚如何使用Eigen's SVD Module找到与点坐标矩阵的最小奇异值对应的最小奇异向量。

    到目前为止,我有这段代码(算法的第1,2和5步):

    Eigen::Matrix<float, 3, 1> mean = points.rowwise().mean();
    const Eigen::Matrix3Xf points_centered = points.colwise() - mean;
    
    int setting = Eigen::ComputeThinU | Eigen::ComputeThinV;
    Eigen::JacobiSVD<Eigen::Matrix3Xf> svd = points_centered.jacobiSvd(setting);
    
    Eigen::Vector3d normal = **???**
    
    double d = normal.dot(mean);
    

2 个答案:

答案 0 :(得分:3)

表示U.col(0),向量U.col(1)U.col(2)定义了您的飞机的基础,U.col(0)与您的飞机垂直。

ComputeFullU也定义了标准偏差最大的方向。

即使您的积分是共面的,您也应该使用标记ComputeThinU代替seensets = [set() for _ in inputlist[0]] outputlist = [] for entry in reversed(inputlist): newentry = [] for value, seen in zip(entry, seensets): newentry.append(value + 'E' if value not in seen else value) seen.add(value) outputlist.append(tuple(newentry)) outputlist.reverse() 来获得正确的尺寸。

答案 1 :(得分:1)

您的问题基本上是如何使用Eigen JacobiSVD模块进行最小二乘拟合。这是一个link,其中有一个更有用的示例。最小二乘拟合的基本思想是首先将所有N-1个点的矢量差与N个点中的一个点进行差分,然后尝试将所有这样的N-1个矢量近似为两个基矢量的线性组合,它定义了2D平面。