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

Fitting 3D ellipsoid to points in 3D space - different methods, different answers

我有一个大型 3D 点云,我正在尝试定义其形状、大小和体积。我正在使用 scipy.spatial.convexHull 找到点云的凸包,它给出了点云的体积,然后我使用凸包的顶点来拟合一个椭圆体来定义大小和形状。我确定了两个可能的 python 模块来拟合椭圆体:pyEllipsoid_Fit (https://github.com/marksemple/pyEllipsoid_Fit) and 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 ])

两个拟合模块 return 中心点和半径的结果相同。中心点值似乎合理,大致位于点云的中间,半径也合理,但 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)

运行 我的数据点上的这种方法 return 是 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 假设椭圆的长轴与 (xyz) 而 matlab 的仿冒品不做这个假设。也就是说,它们更通用并且会更好地拟合相对于坐标轴倾斜但因此具有更多参数的椭球体。

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