将“二次”曲面拟合为3D中的数据点

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了将“二次”曲面拟合为3D中的数据点相关的知识,希望对你有一定的参考价值。

我试图将二次平面拟合到python中的数据点云。我的飞机功能是这种形式

   f(x,y,z) = a*x**2 + b*y**2 + c*x*y + d*x + e*y + f - z

目前,我的数据点没有与之关联的错误,但是,如果需要,可以假设一些错误。根据here的建议,我计算出从点p0 =(x0,y0,z0)(对应于我的数据点)到this method之后的平面p =(x,y,z)上的点的垂直距离。然后我结束了

def vertical_distance(params,p0):
    *** snip ***
    nominator = f + a*x**2 + b*y**2 + c*x*y - x0*(2*a*x-c*y-d) - y0*(2*b*y-c*x-e) + z0
    denominator = sqrt((2*a*x+c*y+d)**2 + (2*b*y+c*x+e)**2 + (-1)**2)
    return nominator/denominator

最终,我认为我需要最小化vertical_distance函数。我很乐意在两个维度上提供一个起始参数列表(params)和数据点数组,但是,我不确定如何在3D中实现这一点。 ODR包似乎只允许包含x,y或2维的数据。此外,如何将平面(p)上的点实现到最小化程序中?我想在拟合操作期间,点根据参数优化而变化,因此在那个时刻的平面的精确方程。

答案

我猜«二次曲面»将是一个比“平面”更正确的术语。

并且问题是将z = ax ^ 2 +与^ 2 + cxy + dx + ey + f拟合到给定的点集P.

要通过优化来实现这一点,您需要制定残差函数(例如,垂直距离)。

对于P残差的每个3D点p

| p_2 - ap_0 ^ 2 + bp_1 ^ 2 + c * p_0 * p_1 + dp_0 + ep_1 + f |

你需要最小化所有残差,即它们的平方和,改变参数a ... f。

以下代码在技术上应该解决上述问题。但是适应这个问题是多极端的,如果没有良好的起点或搜索全球化,这样的例程可能无法找到正确的参数集。

import numpy
import scipy.optimize

P = numpy.random.rand(3,10) # given point set

def quadratic(x,y, a, b, c, d, e, f): 
  #fit quadratic surface
  return a*x**2 + b*y**2 + c*x*y + d*x + e*y + f

def residual(params, points):
  #total residual
  residuals = [
    p[2] - quadratic(p[0], p[1],
    params[0], params[1], params[2], params[3], params[4], params[5]) for p in points]

  return numpy.linalg.norm(residuals)

result = scipy.optimize.minimize(residual, 
                                 (1, 1, 0, 0, 0, 0),#starting point
                                 args=P)

以上是关于将“二次”曲面拟合为3D中的数据点的主要内容,如果未能解决你的问题,请参考以下文章

抛物面(3D抛物线)曲面拟合python

为啥要进行平面点云数据的拟合

origin三维图数据过少,曲面不圆滑,如何处理可以使曲面圆滑。拟合、差值等,不能改变原来的走势

mathematica画三维曲面

✠OpenGL-11-参数曲面

vtkQuadric创建二次曲面