2

我有一堆点,我需要最合适的线。我正在使用 JAMA,但我不知道为什么,有些东西不起作用。可能是我不明白它是如何工作的。我有一个 Nx3 矩阵(这是 JAMA svd 支持的),我从 Svd 获得了正确的矩阵 V。我需要的向量是对应于最大奇异值的正确奇异向量(行或列?)。这个向量应该代表主方向。

每个向量都应该有 y 作为最大的正值,x 可以是正的也可以是负的,z 应该是负的。但有时我得到的向量的 y 值为负,或者无论如何它指向错误的方向。

我的点云非常规则,几乎都沿着 y 轴定位(z 小且为负)。所以主要方向应该很容易找到。但它仍然无法正常工作。

在这种情况下,我得到了右矩阵 V 的行向量(我也尝试了列向量)。我已经从“pointSet”中减去了质心。

public static Matrix bestDirection(Matrix pointSet){

    Matrix bestFittingLine = new Matrix(3,1);
    SingularValueDecomposition svd = pointSet.svd();

    bestFittingLine.set(0, 0, svd.getV().get(0, 0));
    bestFittingLine.set(1, 0, svd.getV().get(0, 1));
    bestFittingLine.set(2, 0, svd.getV().get(0, 2));

    return bestFittingLine;
}

我想也许我没有考虑什么。Idk 也许我应该使用另一种技术或另一个库。

4

2 回答 2

1

来自 SVD 上的维基百科:

非退化奇异值始终具有唯一的左奇异向量和右奇异向量,最多乘以单位相位因子(对于实际情况直到符号)。

简单地说,你不能依赖输出奇异向量的符号。

您可能还需要在 SVD 之前将数据居中。

为什么不执行回归?

于 2012-01-25T20:48:45.890 回答
0

如果你的方程采用这种形式:

z = a0 + a1*x + a2*y

对于 N 个点,您的矩阵方程如下所示:

z(i) = a0 + a1*x(i) + a2*y(i)  i = 1, N

左边是一个 Nx1 向量;右手边是一个 Nx3 矩阵乘以一个 3x1 的未知向量。

将两边乘以 A(转置),最终得到一个 3x3 矩阵,乘以等于 3x1 向量的未知系数的 3x1 向量。使用标准矩阵解来求解未知系数。这很容易做到,即使是封闭的形式。

这是简化的线性最小二乘解。这是一个更详细地说明它的草稿文件

于 2012-01-25T18:41:39.333 回答