计算3D(或n-D)质心的最佳方法是什么?
在工作项目中,我需要计算一组在三维空间中的点的中心点。现在我用一种看起来简单但有点幼稚的方法来做,就是通过计算每组点的平均值,具体代码如下:
centroid = average(x), average(y), average(z)
这里的 x
、y
和 z
是一些浮点数的数组。我记得有一种方法可以得到更准确的中心点,但我还没找到简单的算法来实现。有没有人有好的想法或建议?我在用Python,但我也可以参考其他语言的例子。
9 个回答
不,这就是一组点的质心(中心点)的唯一公式。你可以查看维基百科了解更多信息:http://en.wikipedia.org/wiki/Centroid
你提到“获取更准确的中心点”的方法。也许你是在说一个不受极端值影响的中心点。比如,美国的家庭收入平均水平可能很高,因为有少数非常富有的人拉高了这个平均数;他们就是所谓的“极端值”。因此,统计学家通常使用中位数来代替平均数。获取中位数的一种方法是先把所有数值排序,然后选择中间的那个数。
也许你想要的就是这样的东西,但适用于二维或三维的点。问题是,在二维及更高维度中,你不能简单地排序,因为没有自然的顺序。不过,确实有一些方法可以去掉极端值。
一种方法是找到这些点的凸包。凸包就是把所有点的“外侧”包起来的形状。如果你这样做,并且把位于凸包上的点去掉,那么剩下的点就会更能代表整体,从而得到一个更“真实”的中心点。你甚至可以多次重复这个过程,结果就像剥洋葱一样。实际上,这个过程被称为“凸包剥离”。
与这里常说的观点不同,定义(和计算)点云中心的方法有很多种。你已经提到的第一个也是最常见的解决方案,我不会说这个方法有什么问题:
centroid = average(x), average(y), average(z)
这里的“问题”在于,这种方法会根据点的分布“扭曲”你的中心点。比如说,如果你假设所有的点都在一个立方体盒子或其他几何形状内,但大部分点恰好集中在上半部分,那么你的中心点也会向上移动。
作为替代方案,你可以在每个维度上使用数学上的中间值(极值的平均值)来避免这个问题:
middle = middle(x), middle(y), middle(z)
当你不太在意点的数量,而更关心整体的边界框时,这个方法就很有用,因为这实际上就是你点周围边界框的中心。
最后,你还可以在每个维度上使用median
(中间的元素):
median = median(x), median(y), median(z)
这个方法实际上与middle
相反,可以帮助你忽略点云中的异常值,从而找到一个基于点分布的中心点。
找到一个“好”的中心点的更稳健的方法可能是忽略每个维度上前10%和后10%的点,然后再计算average
或median
。正如你所看到的,中心点可以用不同的方法来定义。下面我给你展示了两个2D点云的例子,考虑了这些建议。
深蓝色的点是平均值(均值)中心点。 绿色的点是中位数。 红色的点是中间值。 在第二张图中,你会看到我之前提到的内容:绿色的点“更靠近”点云中最密集的部分,而红色的点则更远,考虑到了点云的最极端边界。