python - 将 3D 椭球拟合到 3D 空间中的点 - 不同的方法,不同的答案

标签 python numpy geometry computational-geometry ellipse

我有一个大型 3D 点云,我正在尝试定义其形状、大小和体积。我使用 scipy.spatial.convexHull 来查找点云的凸包,这给了我点云的体积,然后我使用凸包的顶点来拟合椭球体来定义尺寸和形状。我确定了两个可能的用于拟合椭圆体的 python 模块:pyEllipsoid_Fit (https://github.com/marksemple/pyEllipsoid_Fit) 和 ellipsoid_fit_python (https://github.com/aleksandrbazhin/ellipsoid_fit_python),它们似乎都源自 Yury Petrov 的同一 MATLAB 库。这一切听起来都很简单。

我展示了凸包中的一组精简点,以了解其形状,但云中约有 30,000 个点,凸包约有 2,000 个顶点。

clusterData = np.array([[ 0.73938582, -0.64072618, -0.30248798],
       [ 0.7456499 , -0.62475833, -0.26983183],
       [ 0.71082352, -0.64138446, -0.26690041],
       [ 0.70722122, -0.61039429, -0.25441756],
       [ 0.73099042, -0.63183361, -0.23934509],
       [ 0.7594304 , -0.60428986, -0.29554205],
       [ 0.71364348, -0.66918549, -0.24510986]])

在船体点上运行椭球拟合会得到以下结果:

center, evecs, radii, v = ellipsoid_fit(hull.points[hull.vertices])

center
Out[51]: array([ 0.73215066, -0.63262089, -0.26906655])

radii
Out[52]: array([0.03521219, 0.06578687, 0.0504479 ])

两个拟合模块都返回相同的中心点和半径结果。中心点值似乎合理,并且大致位于点云的中间,半径也合理,尽管 y 值似乎可能有点大。

我还发现了一种使用 numpy 进行最小二乘回归的不同方法,该方法在 https://jekel.me/2020/Least-Squares-Ellipsoid-Fit/ 上看起来简单而高效。我已经实现了这个方法进行比较:

    def ellipsoid_fit_LS(pos):
        
        # centre coordinates on origin
        pos = pos - np.mean(pos, axis=0)
        
        # build our regression matrix
        A = pos**2
        
        # vector of ones
        O = np.ones(len(A))
        
        # least squares solver
        B, resids, rank, s = np.linalg.lstsq(A, O)
        
        # solving for a, b, c
        a_ls = np.sqrt(1.0/B[0])
        b_ls = np.sqrt(1.0/B[1])
        c_ls = np.sqrt(1.0/B[2])
        
        return (a_ls, b_ls, c_ls)

在我的数据点上运行此方法会针对 3 个半径返回不同的答案:

ellipsoid_fit_LS(hull.points[hull.vertices])
Out[55]: (0.05628746742089332, 0.07109498037367977, 0.04941867027310397)

差异并不大,但我想知道为什么答案有明显差异,特别是在 a/x 系数方面。一种方法比另一种更正确吗?

简单的 numpy 是否有所不同,因为它只包含一般椭球体的平方项,而不包含其他系数项,我认为这些系数项适用于其他形状?

我很好奇,因为对于这个小数据集,简单的 numpy 在我的计算机上速度大约快 3 倍。我将在比本示例中使用的 2000 点外壳大得多的数据集上执行此 1000 次,因此如果它的准确度明显较低,我不想选择更快的一次。

也许精通计算几何的人可以发表评论!

最佳答案

在比较这两种方法时,两者都使用最小二乘法,但 ellipsoid_fit_LS 假设椭圆的长轴与 (x, y, z) 而 matlab 仿冒品则不会做出这种假设。也就是说,它们更通用,并且可以更好地拟合相对于坐标轴倾斜的椭球体,但因此需要拟合更多参数。

对数据的良好但不同的拟合总是这样,具有相似但不相同的结果。一般来说,一个好的开始是选择一种具有尽可能少的自由参数但与数据和模型一致的拟合算法。

关于python - 将 3D 椭球拟合到 3D 空间中的点 - 不同的方法,不同的答案,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/66780826/

相关文章:

python - 如何从 fasta 文件中获取索引列表序列?

python - 三次样条内存错误

Python同质与非同质绘图线

javascript - 在圆 D3/JS 中定位图像

python - 使用 python re 进行正则表达式简化

python - 使用 Tornado RequestHandler 时最好的 REST 实现是什么

python - H5PY保存复合numpy数组时出现问题

python - 寻找四边形内最大矩形拟合的简单算法

python - Windows - 在启动信息中使用 wShowWindow 弹出不影响显示

python - Python(Numpy/Scipy)中的 Varimax 旋转?