橢圓擬合(python)

import pandas as pd
import numpy as np
import matplotlib.pylab as plt
from sympy.solvers import solve
from sympy import Symbol
import os


def solve_tuoyuan(x,y):

    #a*x**2 + b*x*y + c*y**2 + d*x + e*y + f
    print('擬合......')
    x0,y0 = x.mean(),y.mean()      
    D1=np.array([(x-x0)**2,(x-x0)*(y-y0),(y-y0)**2]).T
    D2=np.array([x-x0,y-y0,np.ones(y.shape)]).T
    S1=np.dot(D1.T,D1)
    S2=np.dot(D1.T,D2)
    S3=np.dot(D2.T,D2)    
    T=-1*np.dot(np.linalg.inv(S3),S2.T)
    M=S1+np.dot(S2,T)
    M=np.array([M[2]/2,-M[1],M[0]/2])
    lam,eigen=np.linalg.eig(M)
    cond=4*eigen[0]*eigen[2]-eigen[1]**2
    A1=eigen[:,cond>0] 
    A=np.vstack([A1,np.dot(T,A1)]).flatten()
    A3=A[3]-2*A[0]*x0-A[1]*y0
    A4=A[4]-2*A[2]*y0-A[1]*x0
    A5=A[5]+A[0]*x0**2+A[2]*y0**2+A[1]*x0*y0-A[3]*x0-A[4]*y0
    A[3]=A3;A[4]=A4;A[5]=A5
    return A


def normal_style(paras):
    print('計算標準橢圓位置.....')
    #solve_tuoyuan.return A
    paras=paras/paras[5]
    A,B,C,D,E=paras[:5]
    #橢圓中心    
    x0=(B*E-2*C*D)/(4*A*C-B**2)
    y0=(B*D-2*A*E)/(4*A*C-B**2)
    #長短軸
    a= 2*np.sqrt((2*A*(x0**2)+2*C*(y0**2)+2*B*x0*y0-2)/(A+C+np.sqrt(((A-C)**2+B**2))))
    b= 2*np.sqrt((2*A*(x0**2)+2*C*(y0**2)+2*B*x0*y0-2)/(A+C-np.sqrt(((A-C)**2+B**2))))
    #長軸傾角
    q=0.5 * np.arctan(B/(A-C))
    #normal_style
    return x0,y0,a,b,q


def tuoyuan(y,x,p):
    #用來計算
    return p[0]*x**2+p[1]*x*y+p[2]*y**2+p[3]*x + p[4]*y + p[5]


def cal_fit_data(p,normal):
    print('計算擬合後的數據.....')
    ##,solve_tuoyuan,P
    ##normal_style,
    x=np.linspace(normal[0]-normal[2]/2,normal[0]+normal[2]/2,100)
    rx,ry=[],[]
    y=Symbol('y')
    for i in x:
        yi=solve(tuoyuan(y,i,p),y)
        if  'I' not in str(yi[0]):
            rx.append(i)
            ry.append(yi[0])
        if 'I' not in str(yi[1]):
            rx.append(i)
            ry.append(yi[1])
    return rx,ry
    


def plots(x,y,fits,pfile):
    fig=plt.figure()
    ax=fig.add_subplot(111)
    ax.plot(x,y,'b*',label='origin')    
    ax.plot(fits[0],fits[1],'r.',label='fits')
    plt.show()
    fig.savefig(pfile.replace('.txt','.png'))
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章