使形状适合点

时间:2019-03-19 08:31:02

标签: algorithm shapes data-fitting

我正在尝试将已知的明确定义的形状(例如,盒子,圆柱体;具有可配置的位置,旋转和尺寸)拟合到一组点,这些点具有通过采样3D网格生成的法线。我目前的方法是为每种形状定义自定义拟合函数,并将其传递给第三方优化函数:

fitness = get_fitness(shape_parameters, points)
best_parameters = external.optimise(get_fitness, initial_parameters, points)

(作为参考,我目前正在使用Python 3和scipy.optimize.minimize带边界,但是语言无关)。

此矩形的适应度函数看起来像

def get_fitness(parameters, points):
    side_fitnesses = []
    for side in [top, right, bottom, left, back, front]:
        dists = get_side_distances(parameters, points, side)
        ndevs = get_side_normal_deviations(parameters, points, side)
        side_fitnesses.append(combine_dists_and_ndevs(dists, ndevs))
    fitnesses = choose_best_side_for_each_point(side_fitnesses)
    return mean(fitnesses)

但这意味着我必须确定异常值(有/没有缓存),并且一次只能拟合一个形状。

例如(在2D模式下),对于这些点(具有法线),我想要以下结果:

boxes fitted to points with normals

请注意,返回了多个形状,并且忽略了异常值。通常,输入数据中可以有许多,一种或零种形状。后处理可以删除无效的结果(例如,太小)。

注意:我真正的问题是3D。我具有真实世界对象的3D网格表示的片段,这意味着除了上面示例中的点/法线(例如面部区域和连接性)之外,我还具有更多的信息。

进一步阅读:

PS:我不确定StackOverflow是否是此问题的最佳StackExchange网站

1 个答案:

答案 0 :(得分:1)

好,那么您将不得不处理具有体积的网格。事情发生了很大变化...

  1. 分段对象

    选择包围其内部的所有面孔...因此类似于此:

    因此,只需在尚未使用的网格中找到一个点,然后“填充”体积,直到击中它所组成的所有面。选择那些属于新对象的面。并将其设置为已使用...。当心触摸物体可能会导致使用两次或更多次人脸...

    您也可以在向量数学/空间上执行此操作,因此只需测试从某个内点到某面的线是否碰到任何其他面...如果没有,您会发现自己的面...类似于Hit test

  2. 过程对象(可选)

    您可以通过将属于同一平面的面分组或在封闭的边缘/轮廓内部,然后将其划分为对象,进一步将对象网格划分为由其组成的“平面”对象

    • 三角形
    • 矩形
    • 多边形
    • 光盘

    从面孔的数量和类型中,您可以检测到以下基本对象:

    cone = 1 disc + 1 curved surface with singular edge point parallel to disc center
    box/cube = 6 rectangles/squares
    cylinder = 2 discs + 1 curved surface with center axis going through discs centers
    
  3. 计算单个对象的基本几何属性(可选)

    类似于BBOX或OBB,表面,体积,几何。中心,质心,...

    现在只需确定它是什么类型的对象。例如,表面积与体积之比可以提示球形或椭圆形,如果 OBB 与侧面匹配则提示框,如果几何和质心相同则提示对称对象...

  4. 将网格传递给可能的对象类型拟合功能

    因此,根据子弹#2,#3 ,您会知道哪个对象可能是哪种形状,因此只需使用拟合函数对其进行确认即可。

    为简化此过程,您可以使用#3 中的属性,例如以下示例:

    因此您可以针对基本的 3D 形状提出类似的技术...