拟合给定 2D 轮廓的椭圆体

Fitting an ellipsoid given 2D contours

我有一组二维轮廓对应的坐标,每个轮廓对应不同的高度。这些轮廓并没有在 3D 中绘制出完美的椭圆体,而是我想做的是找到最合适的椭圆体。我不知道这个椭圆体的起源。

我的第一个想法是结合某种类型的最小二乘算法,我在其中找到最小化点之间距离的椭圆体参数。我想这会非常昂贵,而且与蛮力方法相差不远。我相信有一种更优雅、更有效的方法可以做到这一点。如果有一个现有的库可以处理这个问题(最好在 Python 中),那就更好了。

我已经看过一个相关问题 (Fitting an ellipsoid to 3D data points),但我想我会再问一遍,因为已经过了十多年 post。

所以每个轮廓都有一组 (x,y) 值,它们描述了椭圆的一部分(下面的蓝点)。

最佳拟合椭圆由一般方程描述

A x^2 + B y^2 + 2C x y + 2 Dx+2Ey=1

一旦找到系数(A,B,C,D,E),就可以完全描述椭圆。请参阅下文了解如何从系数和参数 t=0 .. 1.

中找到曲线坐标 (x,y)

要找到椭圆的系数,形成 5 个向量,每个向量都是 n×5 矩阵的一列 Q

for i = 1 to n
  Q(i,1) = x(i)^2
  Q(i,2) = y(i)^2
  Q(i,3) = 2*x(i)*y(i)
  Q(i,4) = 2*x(i)
  Q(i,5) = 2*y(i)
next i

和向量 K 填充了 1 作为 right-hand 边

for i = 1 to n
  K(i) = 1.0
next i

使用 least-squares 与一些线性代数拟合求系数

[A,B,C,D,E] = inv(tr(Q)*Q)*tr(Q)*K

其中 tr(Q)Q 的转置,* 是 matrix/vector 乘积

现在我们需要从系数中提取椭圆的几何特性。我想要 a semi-major 轴,b semi-minor 轴,φ旋转角度,xcx轴心,ycy-轴心.

xc = -(B*D-C*E)/(A*B-(C^2))
yc = -(A*E-C*D)/(A*B-(C^2))
φ = atan( 2*C/(A-B) )/2
a = SQRT(2*(A*(B+E^2)+B*D^2-C*(C+2*D*E))/((A*B-C^2)*(A+B-SQRT((A-B)^2+4*C^2))))
b = SQRT(2*(A*(B+E^2)+B*D^2-C*(C+2*D*E))/((A*B-C^2)*(A+B+SQRT((A-B)^2+4*C^2))))

最后要绘制椭圆,您需要使用上述 5 个系数从曲线参数 t=0..1 生成一组点 (x,y)

  1. 生成居中对齐的坐标(u,v)
    u = a*cos(2*π*t)
    v = b*sin(2*π*t)
    
  2. 生成居中旋转坐标(x',y')
    x' = u*cos(φ) - v*sin(φ)
    y' = u*sin(φ) + v*cos(φ)
    
  3. 生成椭圆坐标(x,y)
    x = x' + xc
    y = y' + yc
    

结果如上图第一张所示


现在对于整体解决方案,每个 2D 切片都有自己的椭圆。但是所有切片都不会以这种方式生成椭圆体。

将上面的内容扩展到 3D 坐标 (x,y,z) 是可行的,但是数学相当复杂,我觉得 [SO] 不是开发这种算法的好地方。您可以通过找到每个切片的平均中心(由椭圆面积 π*a*b 加权)来将其组合在一起。此外,所有轮廓的旋转角度应该相同,因此需要进行另一次平均。最后,长轴和短轴值将落在沿 z 轴的椭圆曲线上,这将需要另一个 least-fit 解。这个是由方程驱动的

(x/a)^2 + (y/b)^2 + (z/c )^2 = 1

而是对齐坐标 (u,v,w)

(u/a)^2 + (v/b)^2 + (w/c )^2 = 1