我使用最小二乘法将平面拟合到3D点集。我已经有算法来做到这一点,但我想修改它以使用加权最小二乘法。意思是每个点都有一个重量(重量越大,平面越接近该点)。
当前算法(没有重量)如下所示:
计算总和:
for(Point3D p3d : pointCloud) {
pos = p3d.getPosition();
fSumX += pos[0];
fSumY += pos[1];
fSumZ += pos[2];
fSumXX += pos[0]*pos[0];
fSumXY += pos[0]*pos[1];
fSumXZ += pos[0]*pos[2];
fSumYY += pos[1]*pos[1];
fSumYZ += pos[1]*pos[2];
}
制作矩阵:
double[][] A = {
{fSumXX, fSumXY, fSumX},
{fSumXY, fSumYY, fSumY},
{fSumX, fSumY, pointCloud.size()}
};
double[][] B = {
{fSumXZ},
{fSumYZ},
{fSumZ}
};
解决Ax = B,解的3个分量是拟合平面的系数...
那么,你能帮助我如何修改它来使用权重吗?谢谢!
答案 0 :(得分:9)
<强>直觉强>
由普通x
定义的平面上的点n
和平面p
上的点服从:n.(x - p) = 0
。如果点y
不在平面上,n.(y -p)
将不等于零,因此定义成本的有用方法是|n.(y - p)|^2
。这是点y
与平面的平方距离。
如果权重相等,您希望找到n
,以便在对点进行求和时最小化总平方误差:
f(n) = sum_i | n.(x_i - p) |^2
现在假设我们知道位于飞机上的某些点p
。我们可以很容易地计算出一个质心,它只是点云中点的分量均值,并且总是位于最小二乘平面中。
<强>解决方案强>
让我们定义一个矩阵M
,其中每一行是ith
点x_i
减去质心c
,我们可以重写:
f(n) = | M n |^2
你应该能够说服自己这个矩阵乘法版本与前一个等式的总和相同。
然后,您可以M
n
M
,然后w_i
给出c
所需的sum_i | n.(x_i - c) |^2
,它对应于最小的奇异值。
要合并权重,您只需为每个点定义权重sum_i | w_i * n.(x_i - c) |^2
。将M
计算为点的加权平均值,并以类似的方式将{{1}}更改为{{1}},将矩阵{{1}}更改为{{1}}。然后像以前一样解决。
答案 1 :(得分:2)
将每个总和中的每个项乘以相应的权重。例如:
fSumZ += weight * pos[2];
fSumXX += weight * pos[0]*pos[0];
由于pointCloude.size()
是所有点的1
的总和,因此应将其替换为所有权重的总和。
答案 2 :(得分:0)
从重新定义最小二乘误差计算开始。该公式试图最小化误差平方和。将平方误差乘以两个点的函数,这两个点随距离减小。然后尝试最小化平方误差的加权和并从中导出系数。