将三维椭球体拟合到三维空间中的点不同的方法,不同的答案

2024-09-28 20:41:14 发布

您现在位置:Python中文网/ 问答频道 /正文

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

我展示了凸包中的一组简化点,以了解它的形状,但它在云中大约有30000个点,凸包有大约2000个顶点

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次,因此如果准确度明显降低,我不希望选择更快的一次

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


Tags: 模块方法httpsposnp半径outarray
1条回答
网友
1楼 · 发布于 2024-09-28 20:41:14

在比较这两种方法时,两者都使用最小二乘法,但ellipsoid_fit_LS假设椭圆的长轴与(xyz)对齐,而matlab仿冒品不作此假设。也就是说,它们更通用,将为相对于坐标轴倾斜的椭球体生成更好的拟合,但因此需要拟合更多的参数

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

相关问题 更多 >