Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 将三维椭球体拟合到三维空间中的点-不同的方法,不同的答案_Python_Numpy_Geometry_Computational Geometry_Ellipse - Fatal编程技术网

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

Python 将三维椭球体拟合到三维空间中的点-不同的方法,不同的答案,python,numpy,geometry,computational-geometry,ellipse,Python,Numpy,Geometry,Computational Geometry,Ellipse,我有一个大的3D点云,我正试图定义它的形状、大小和体积。我使用scipy.spatial.convexHull来找到点云的凸包,它给出了点云的体积,然后我使用凸包的顶点来拟合椭球体来定义大小和形状。我确定了两个可能用于拟合椭球体的python模块:pyelloid_-Fit()和椭球体_-Fit_-python(),这两个模块似乎都来自于Yury Petrov的同一个MATLAB库。这听起来很简单 我展示了凸包中的一组简化点,以了解它的形状,但它在云中大约有30000个点,凸包有大约2000个顶

我有一个大的3D点云,我正试图定义它的形状、大小和体积。我使用
scipy.spatial.convexHull
来找到点云的凸包,它给出了点云的体积,然后我使用凸包的顶点来拟合椭球体来定义大小和形状。我确定了两个可能用于拟合椭球体的python模块:
pyelloid_-Fit
()和
椭球体_-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
进行最小二乘回归,这种方法看起来简单有效。我实现了此方法以进行比较:

    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
one在我的计算机上的速度大约是3倍。我将在比本例中使用的2000点外壳更大的数据集上执行1000次,因此如果准确度明显降低,我不希望选择更快的一次


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

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


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

这是一个编程问题还是一个统计问题?不同的方法,不同的答案对我来说乍一看似乎是合理的。@Triarion这是一个计算几何问题。计算相同值的两种方法得出不同的结果-这些方法正确吗?哪一个最合适?这就解释了为什么值不同。我没有意识到
椭球体_fit_LS
假设与xyz轴对齐。因为我的几乎总是会旋转,所以使用其他的会更有意义。有没有一种方法明显比MATLAB副本更好?我不知道有没有更好的方法,也不知道是否会有这样的方法。我的猜测是,这个问题的拟合椭球壳是不是一个共同的需要,所以我不会期望有许多不同的方法存在。