确定散点最准确的最佳拟合算法

问题描述 投票:0回答:1

我目前正在使用 Python3 中的

skspatial
包。我目前有两个功能:

  1. skspatial.objects.Cylinder.best_fit
    尝试将点最好地拟合到圆柱体中
  2. 返回散点的边界框的函数。此函数返回一个自定义类,该类应该使用具有类似方法的
    skspatial.objects
    对象“扩展”
    Cuboid
    ,但实际上只是一个边界框。

我的问题如下:有没有办法确定这两种形状中哪一个更好地包含散点?对于同一组分散点,它们都返回有效的

cylinder
Cuboid
对象,但只有其中一个实际上更适合点。

如果这个问题很重要,散点仅代表它们实际所在形状的表面,因此物体“内部”没有点。

python python-3.x shapes data-fitting best-fit
1个回答
0
投票

我决定用我在上面评论中给出的解释来测试我自己的指标。

方法如下:假设我们知道任一形状(圆柱体或长方体)是目标(从技术上讲,所有形状都可以在给定其中心坐标的 3D 空间中进行点反射/镜像),那么我们可以确定百分比不在任一形状表面上的点:

  1. 定义错误计数器变量

    errors = 0

  2. 确定形状的中心。

对于圆柱体,它将是

Point(cylinder.point + cylinder.vector * 0.5)
。对于长方体,它将是从
(x_min, y_min, z_min)
点到
(x_max, y_max, z_max)
点的线的中间。在
skspatial
中,这将由
Line.from_points(p_min, p_max).to_point(0.5)
完成。

  1. 主循环:对于点云中的每个
    point
    ,从之前计算的中心点到各个点画一条线:
point_center_line = Line.from_points(center, point)
  1. 获取
    point_center_line
    与圆柱体或长方体形状相交时返回的两个交点。由于我们的形状是“空心”的,并且线穿过形状的中心,因此总会有 2 个交点
    a
    b
    :
a, b = shape.intersect_line(point_center_line)
  1. 从这两个点
    a
    b
    构造一条线。这条线的长度为
    2 * (length_of_point_center_line +- delta)
    delta
    是从 a 或 b(以较近者为准)到个体
    point
    的直线长度。
    +-
    是因为该点要么仍在形状本身内,要么就在形状外部。

我们现在可以检查

delta
是否在指定的容差范围内:

delta = abs(length_of_point_center_line - length_of_a_b_line / 2)
if delta > tolerance:
    errors += 1
  1. 循环结束。现在,我们可以计算百分比:
    errors / number_of_points

这将为点云(实际上来自圆柱体形状的物体)提供在我的用例中的以下输出:

Fitting error for Cuboid.best_fit: 0.951777280636341
Fitting error for Cylinder.best_fit: 0.0019885657469550086

由于长方体完全拟合圆柱点云,因此圆柱点实际上位于长方体表面上的点只有少数。然而,对于圆柱体,大多数点都在表面的公差范围内,只有 0.19% 的点在该公差范围之外。

有了这个,我可以简单地检查返回值并采用百分比较低的函数。

© www.soinside.com 2019 - 2024. All rights reserved.