3d点最接近3D空间中的多条线

时间:2018-01-08 16:23:42

标签: algorithm computer-vision geometry linear-algebra computational-geometry

我搜索非迭代的闭合形式算法,以找到最接近3d线组的点的最小二乘解。它类似于3d点三角测量(最小化重新投影),但似乎更简单,更快?

线条可以任何形式描述,2点,点和单位方向或类似。

2 个答案:

答案 0 :(得分:5)

i 行由点 a i 和单位方向向量 d i 的。我们需要找到最小化点到线距离平方和的单点。这是渐变是零向量的地方:

unsimplified gradient of sum of squared distances

扩展渐变

rewritten gradient set to zero

代数产生规范的3x3线性系统,

3x3 linear system

其中矩阵M的第k行(3元素行向量)是

matrix M

使用vector e k 各自的单位基矢量,

vector b

将其转换为代码并不难。我从Rosettacode借用(并修复了一个小错误)高斯消除函数来解决系统问题。感谢作者!

<class 'numpy.ndarray'>
0.6930587610394646

这还没有经过广泛测试,但似乎工作正常。

答案 1 :(得分:1)

让行的基点为p,单位方向向量为d。 然后,可以计算从v点到此线的距离using cross product

SquaredDist = ((v -  p) x d)^2

使用Maple包符号计算,我们可以得到

d := <dx, dy, dz>;
v := <vx, vy, vz>;
p := <px, py, pz>;
w := v - p;
cp := CrossProduct(d, w);
nrm := BilinearForm(cp, cp, conjugate=false);  //squared dist
nr := expand(nrm);       

//now partial derivatives
nrx := diff(nr, vx);     
//results:
nrx := -2*dz^2*px-2*dy^2*px+2*dz^2*vx+2*dy^2*vx
       +2*dx*py*dy-2*dx*vy*dy+2*dz*dx*pz-2*dz*dx*vz
nry := -2*dx^2*py-2*dz^2*py-2*dy*vz*dz+2*dx^2*vy
       +2*dz^2*vy+2*dy*pz*dz+2*dx*dy*px-2*dx*dy*vx
nrz := -2*dy^2*pz+2*dy^2*vz-2*dy*dz*vy+2*dx^2*vz
       -2*dx^2*pz-2*dz*vx*dx+2*dy*dz*py+2*dz*px*dx

为了最小化平方距离的总和,我们必须为零偏导数建立线性方程组,如下所示:

  vx*2*(Sum(dz^2)+Sum(dy^2)) + vy * (-2*Sum(dx*dy)) + vz *(-2*Sum(dz*dx)) = 
     2*Sum(dz^2*px)-2*Sum(dy^2*px) -2*Sum(dx*py*dy)-2*Sum(dz*dx*pz)

where 
  Sum(dz^2) = Sum{over all i in line indexes} {dz[i] * dz[i]}

并为unknowns vx,vy,vz

解决它

编辑:对于飞机而不是线的旧错误答案,留待参考

如果我们使用线的一般方程

 A * x + B * y + C * z + D = 0

然后从点(x,y,z)到该线的距离为

Dist = Abs(A * x + B * y + C * z + D) / Sqrt(A^2 + B^2 + C^2)

简化 - 只需将Norm的所有线方程归一化

Norm = Sqrt(A^2 + B^2 + C^2)
a = A / Norm
b = B / Norm
c = C / Norm
d = D / Norm

现在等式是

 a * x + b * y + c * z  + d = 0

和距离

Dist = Abs(a * x + b * y + c * z + d)

我们可以像LS方法一样使用平方距离(ai, bi, ci, di是第i行的系数)

F = Sum(ai*x + bi*y + ci * z + d)^2 = 
Sum(ai^2*x^2 + bi^2*y^2 + ci^2*z^2 + d^2 +
2 * (ai*bi*x*y + ai*ci*x*z + bi*y*ci*z + ai*x*di + bi*y*di + ci*z*di))

  partial derivatives
dF/dx = 2*Sum(ai^2*x + ai*bi*y + ai*ci*z + ai*di) = 0
dF/dy = 2*Sum(bi^2*y + ai*bi*x + bi*ci*z + bi*di) = 0
dF/dz = 2*Sum(ci^2*z + ai*ci*x + bi*ci*y + ci*di) = 0
  so we have system of linear equation 
x * Sum(ai^2) + y * Sum(ai*bi) + z * Sum(ai*ci)= - Sum(ai*di)
y * Sum(bi^2) + x * Sum(ai*bi) + z * Sum(bi*ci)= - Sum(bi*di)
z * Sum(ci^2) + x * Sum(ai*ci) + y * Sum(bi*ci)= - Sum(ci*di)

x * Saa + y * Sab + z * Sac = - Sad
x * Sab + y * Sbb + z * Sbc = - Sbd
x * Sac + y * Sbc + z * Scc = - Scd

where S** are corresponding sums

可以解决未知问题x, y, z