拟合椭球到三维数据点

10
我有一组大量的3D数据点,想将其拟合成一个椭球体。
我的数学知识很差,所以我在没有任何数学库的情况下实现最小二乘法时遇到了麻烦。
有没有人知道或者有一段可以将椭球体拟合到数据中的代码,我可以直接插入到我的项目中?C语言最好,但我可以从C ++、Java、C#、Python等转换过来。
编辑:只能找到中心点也会非常有帮助。请注意,这些点不是均匀分布的,因此取平均值不会得出中心点。

1
你希望你的点落在椭球面上,还是希望你的点在一个椭球云中? - ellisbben
我期望它们落在一个椭球体的表面上,因此中心是空心的。 - Hannesh
9个回答

10

2
如果你想要最小体积的包围椭球,可以查看这个边界椭球的SO答案。
如果你想要在最小二乘意义下拟合最佳椭圆,可以查看这个MATLAB代码误差椭圆,其中你可以找到你的平移后3D点的协方差矩阵,并用它来构造椭球。

1
这是一种使用快速简单的随机搜索方法得出的非严格解决方案*。最好的一面是不需要重型线性代数库**。似乎对于网格碰撞检测效果良好。
假设椭球中心与云中心匹配,然后使用某种镜像平均值来搜索主轴。
完整的工作代码稍微大一些,并放置在git上,主轴搜索的思路在这里:
np.random.shuffle(pts)

pts_len = len(pts)
pt_average =  np.sum(pts, axis = 0) / pts_len

vec_major = pt_average * 0
minor_max, major_max = 0, 0

# may be improved with overlapped pass, 
for pt_cur in pts:
    vec_cur = pt_cur - pt_average
    proj_len, rej_len = proj_length(vec_cur, vec_major)

    if proj_len < 0:
        vec_cur = -vec_cur
    vec_major += (vec_cur - vec_major) / pts_len

    major_max = max(major_max, abs(proj_len))
    minor_max = max(minor_max, rej_len)

它在某些方面可以进一步改进/优化。它将生成以下示例:0。并且完整的实验代码和图表。
*即随机调整代码行直到它们工作
**实际上是找出这个解决方案的原因

1
我找不到一个好的基于Java的椭球拟合算法,所以最终我自己编写了这个算法。虽然有一些适用于二维点的椭圆算法,但对于三维点的椭球却没有。我尝试了几个不同的MATLAB脚本,最终选择了Yury Petrov的Ellipsoid Fit。它将椭球拟合到多项式Ax^2 + By^2 + Cz^2 + 2Dxy + 2Exz + 2Fyz + 2Gx + 2Hy + 2Iz = 1上。它不使用任何约束来强制椭球,因此您必须具有相当大数量的点才能防止随机四次曲线被拟合成椭球。除此之外,它的表现非常出色。我使用Apache Commons Math编写了一个小型的Java库,实现了Yury Petrov的脚本。GIT存储库可以在https://github.com/BokiSoft/EllipsoidFit中找到。

0


1

1

最小二乘数据拟合可能是一种适合您所描述的数据性质的良好方法。GNU科学库包含线性非线性最小二乘数据拟合例程。在您的情况下,您可以将数据转换为线性空间并使用线性最小二乘,但这取决于您的实际用例。否则,您需要使用非线性方法。


0

0

你应该提供原始的Matlab源代码链接,并且包含对JAMA的链接/解释,因为问题要求Java代码必须能够在C中移植使用。 - Esoteric Screen Name
当然:Matlab源代码 http://www.mathworks.com/matlabcentral/fileexchange/24693-ellipsoid-fit - mdoube
JAMA是一个Java矩阵库 - 类似的库必须存在于C/C++中。http://math.nist.gov/javanumerics/jama/ - mdoube

0
我有一个想法。大致的解决方案,不是最好的,但可以保持点在内部。在XY平面上找到半径R1,以获得所有点。在XZ平面上做同样的事情(R2),并在YZ平面上做同样的事情(R3)。然后使用每个轴上的最大值。A=max(R1,R2),B=max(R1,R3)和C=max(R2,R3)。但首先要找到所有点的平均值(中心)并将其与原点对齐。

这就是我一直在做的事情。问题在于它无法找到椭球体的实际最大值。此外,我希望所有点的平均值都是中心!但是,只有当点均匀分布在表面上时才有效。 - Hannesh
好吧,这不是一个好主意。 :) 它比一开始看起来更复杂。 - Krešimir Prcela

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接