Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/13.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
matlab从3D数据点拟合椭圆_Matlab_3d_Transform_Points_Ellipse - Fatal编程技术网

matlab从3D数据点拟合椭圆

matlab从3D数据点拟合椭圆,matlab,3d,transform,points,ellipse,Matlab,3d,Transform,Points,Ellipse,我在给定平面(3D)中有一组3D(X,Y,Z)数据点。我希望能在这些问题上找到一个答案 我找到了很多关于如何在二维点上拟合椭圆的答案。因此,更准确地说,我的问题是如何转换3D数据(x,y,z)点->2D数据(x,y)?在标准投影中,椭圆(圆被a=b=r省略)将投影在椭圆或直线上。所以我将使用这个行为,这样你想要的3D椭圆将由你可以计算的不同椭圆来定义 我不会显示代码,但方法可以是: 在M x 3矩阵中定义数据,其中M是点数,形式为[x,y,z] 以z=f(x,y) 在数据矩阵中搜索与[x,y,f

我在给定平面(3D)中有一组3D(X,Y,Z)数据点。我希望能在这些问题上找到一个答案


我找到了很多关于如何在二维点上拟合椭圆的答案。因此,更准确地说,我的问题是如何转换3D数据(x,y,z)点->2D数据(x,y)?

在标准投影中,椭圆(圆被a=b=r省略)将投影在椭圆或直线上。所以我将使用这个行为,这样你想要的3D椭圆将由你可以计算的不同椭圆来定义

我不会显示代码,但方法可以是:

  • 在M x 3矩阵中定义数据,其中M是点数,形式为
    [x,y,z]
  • z=f(x,y)
  • 在数据矩阵中搜索与
    [x,y,f(x,y)]
    向量相等或相似的行
  • 假设生成的点具有elipse形状间隔。然后使用如何将椭圆拟合到搜索结果矩阵中的
    [x,y]
    对的答案(忽略
    z
    部分可以被视为x-y平面的投影)
  • [x\u fit,y\u fit]
  • 将最后一个矩阵展开为
    [x\u-fit,y\u-fit,f(x\u-fit,y\u-fit)]
  • 瞧,这里我们安装了省略

  • 下面是我针对这个问题的Python代码。 此链接帮助我完成了我的实施:

    将numpy导入为np
    从skimage.measure导入EllipseModel
    #-------------------------------------------------------------------------------
    #罗德里格斯旋转
    #-基于起始和结束向量旋转给定点
    #-轴k和旋转角度θ,由矢量n0,n1给出
    #P_rot=P*cos(θ)+(kxp)*sin(θ)+k**(1-cos(θ))
    #-------------------------------------------------------------------------------
    国防部罗德里格斯大学(P、n0、n1):
    #如果P仅为一维数组(单点坐标),则将其固定为矩阵
    如果P.ndim==1:
    P=P[np.newaxis,:]
    #得到旋转向量k和角度θ
    n0=n0/np.线性范数(n0)
    n1=n1/np.线性范数(n1)
    k=np.交叉(n0,n1)
    k=k/np.linalg.norm(k)
    θ=np.arccos(np.dot(n0,n1))
    #计算旋转点
    P_rot=np.zero((len(P),3))
    对于范围内的i(len(P)):
    P_rot[i]=P[i]*np.cos(θ)+np.cross(k,P[i])*np.sin(θ)+k*np.dot(k,P[i])*(1-np.cos(θ))
    返回P_rot
    def拟合椭圆(P):
    P_平均值=P平均值(轴=0)
    P_居中=P-P_平均值
    #均值中心数据的奇异值分解拟合平面
    U、 s,V=np.linalg.svd(P_居中,全矩阵=False)
    #拟合平面的法向量由V中的第三列给出
    #注意linalg.svd返回V^T,因此我们需要从V^T中选择第三行
    #三维平面上的法线
    正常=V[2,:]
    #将点投影到二维平面中的坐标X-Y
    P_xy=rodrigues_rot(P_居中,法线,[0,0,1])
    #使用skimage EllipseModel将椭圆拟合到一组二维点
    ell=EllipseModel()
    估计值(P_xy[:,:2])
    #在拟合的Elipse上生成n个2D点
    n=100
    xy=ell.predict_xy(np.linspace(0,2*np.pi,n))
    #将二维生成的点转换为三维空间
    点数=[]
    对于范围内的i(len(xy)):
    points.append([xy[i,0],xy[i,1],0])
    点=np.数组(点)
    椭圆点3d=罗德里格斯旋转(点[0,0,1],法线)+P平均值
    返回椭圆\u点\u 3d
    
    要测试代码,可以运行此命令并检查输出结果:

    将numpy导入为np
    绘声绘色地导入
    导入plotly.graph_objs作为go
    P=np.数组([[52.21818786,7.86337722,57.83456389],
    [30.55316226, 32.36591494, 14.35753359],
    [59.77387002, 14.29531811, 53.6462596 ],
    [42.85677086, 32.67223954, -5.95323959],
    [44.46449002,  1.43144171, 54.0253186 ],
    [27.6464027 , 19.80836045, -1.5754063 ],
    [63.48591069,  6.88329618, 57.55556516],
    [44.19484831, 28.32302575,  6.01730042],
    [46.09443886,  2.71782362, 57.98617489],
    [22.55050927, 30.28315605, 42.5642505 ],
    [20.16244533, 18.55944689, 34.06871328],
    [69.4591254 , 33.62256919, 40.91996533],
    [24.42183439,  5.95578526, 35.80224431],
    [70.09161495, 24.03152634, 45.77915268],
    [28.68122335, -6.64788396, 37.53577535],
    [59.84340586, 23.47833222, 60.01530894],
    [23.98376474, 14.23114661, 32.43676647],
    [73.28044481, 29.29426891, 39.28801852],
    [28.48679585, -5.33220296, 36.04206575],
    [54.66351746, 15.7561502 , 51.20981383],
    [38.33444206, -0.08003422, 41.2639318 ],
    [57.27722964, 39.91662965, 20.63778872],
    [43.24856256,  7.79042068, 50.95451935],
    [64.68788661, 31.78841088, 27.19632274],
    [41.67377653, -0.18313508, 49.56081237],
    [60.577958  , 35.8138609 , 28.9005053 ]])
    椭圆点=拟合椭圆(P)
    行=[]
    追加(go.Scatter3d(x=P[:,0],y=P[:,1]\
    z=P[:,2],name='P'\
    ,不透明度=1,))
    lines.append(go.Scatter3d(x=椭圆点[:,0],y=椭圆点[:,1]\
    z=椭圆_点[:,2],name='ellipse_点'\
    ,不透明度=1,))
    plotly.offline.iplot(行)
    
    输出结果:


    您可以在colab中自己尝试代码:

    将平面拟合到这些点。那么你就有了一个平面上的坐标。也许还有更多关于这个问题的信息: