加权最小二乘法 - 将平面拟合到 3D 点集
我正在使用最小二乘法将平面拟合到 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 个分量是拟合平面的系数...
那么,您能帮我吗?修改它以使用权重?谢谢!
I am fitting a plane to a 3D point set with the least square method. I already have algorithm to do that, but I want to modify it to use weighted least square. Meaning I have a weight for each point (the bigger weight, the closer the plane should be to the point).
The current algorithm (without weight) looks like this:
Compute the sum:
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];
}
than make the matrices:
double[][] A = {
{fSumXX, fSumXY, fSumX},
{fSumXY, fSumYY, fSumY},
{fSumX, fSumY, pointCloud.size()}
};
double[][] B = {
{fSumXZ},
{fSumYZ},
{fSumZ}
};
than solve Ax = B and the 3 components of the solution are the coefficients of the fitted plain...
So, can you please help me how to modify this to use weights? Thanks!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
直觉
由法线
n
定义的平面上的点x
和平面p
上的点遵循:n.(x - p) = 0
。如果点y
不在平面上,n.(y -p)
将不等于 0,因此定义成本的一个有用方法是通过 <代码>|n.(y - p)|^2 。这是点y
到平面的平方距离。在权重相等的情况下,您希望找到一个
n
,在对点求和时最小化总平方误差:现在假设我们知道一些点
p
位于飞机上。我们可以轻松地将 1 计算为质心,它只是点云中点的分量平均值,并且始终位于最小二乘平面中。解决方案
让我们定义一个矩阵
M
,其中每行是第第
点x_i
减去质心c< /code>,我们可以重写:
您应该能够说服自己,这个矩阵乘法版本与上一个方程的总和相同。
然后,您可以对
M
进行奇异值分解,并且n 由对应于最小奇异值的
M
的右奇异向量给出。要合并权重,您只需为每个点定义一个权重
w_i
即可。计算c
作为点的加权平均值,并更改sum_i | n.(x_i - c) |^2
到sum_i | w_i * n.(x_i - c) |^2
,矩阵M
以类似的方式。然后像以前一样解决。Intuition
A point
x
on a plane defined by normaln
and a point on the planep
obeys:n.(x - p) = 0
. If a pointy
does not lie on the plane,n.(y -p)
will not be equal to zero, so a useful way to define a cost is by|n.(y - p)|^2
. This is the squared distance of the pointy
from the plane.With equal weights, you want to find an
n
that minimizes the total squared error when summing over the points:Now this assumes we know some point
p
that lies on the plane. We can easily compute one as the centroid, which is simply the component-wise mean of the points in the point cloud and will always lie in the least-squares plane.Solution
Let's define a matrix
M
where each row is theith
pointx_i
minus the centroidc
, we can re-write:You should be able to convince yourself that this matrix multiplication version is the same as the sum on the previous equation.
You can then take singular value decomposition of
M
, and then
you want is then given by the right singular vector ofM
that corresponds to the smallest singular value.To incorporate weights you simply need to define a weight
w_i
for each point. Calculatec
as the weighted average of the points, and changesum_i | n.(x_i - c) |^2
tosum_i | w_i * n.(x_i - c) |^2
, and the matrixM
in a similar way. Then solve as before.将每个总和中的每一项乘以相应的权重。例如:
由于
pointCloude.size()
是所有点的1
之和,因此应将其替换为所有权重之和。Multiply each term in each sum by the corresponding weight. For example:
Since
pointCloude.size()
is the sum of1
for all points, it should be replaced with the sum of all weights.从重新定义最小二乘误差计算开始。该公式试图最小化误差平方和。将平方误差乘以两点的函数,该函数随着距离的增加而减小。然后尝试最小化加权平方和并从中导出系数。
Start from redefining the least-square error calculation. The formula tries to minimize the sum of squares of errors. Multiply the squared error by a function of two points which decreases with their distance. Then try to minimize the weighted sum of squared errors and derive the coefficients from that.