LoveArx 发表于 2017-1-11 16:27:42

最小二乘法椭圆拟合

对平面上的一些点拟合有很多手段,其中椭圆拟合在图像轮廓划分等很多方面都很重要,当然,我们一般还是用最小二乘法来拟合椭圆,      在这里,我实现了两种算法,一种是
view plaincopy




[*]http://wenku.baidu.com/link?url=7kIrC8LoOMCtlmAH8yqkpUQfiKwWnVe4EoUJekkQSgQ1qTWfLAuEXTYvYTv7SATGIJYX4IxcTIB94-iO0SpUgztWgx661O2VEOwm_dvoSqO

    这篇文章给出的,核心也是最小二乘法,利用gauss消去法解方程组,不过他给出的代码有些小bug,所以我改了一下,也去掉了opencv的东西。
    还有一个就是利用奇异值分解法来求超定方程的最小二乘法的思想来求出椭圆的五个参数,关于奇异值分解法可以参考    http://blog.csdn.net/wangzhiqing3/article/details/7446444   下面是我的代码实现:
//LSEllipse.h
view plaincopy




[*]/*************************************************************************
[*]    版本:   2014-12-31
[*]    功能说明: 对平面上的一些列点给出最小二乘的椭圆拟合,利用奇异值分解法
[*]               解得最小二乘解作为椭圆参数。
[*]    调用形式: cvFitEllipse2f(arrayx,arrayy,box);   
[*]    参数说明: arrayx: arrayx,每个值为x轴一个点
[*]               arrayx: arrayy,每个值为y轴一个点
[*]               n   : 点的个数
[*]               box   : box,椭圆的五个参数,分别为center.x,center.y,2a,2b,xtheta
[*]               esp: 解精度,通常取1e-6,这个是解方程用的说
[*]***************************************************************************/
[*]
[*]
[*]
[*]
[*]#include"stdafx.h"
[*]#include<cstdlib>
[*]#include<float.h>
[*]#include<vector>
[*]using namespace std;
[*]
[*]class LSEllipse
[*]{
[*]public:
[*]    LSEllipse(void);
[*]    ~LSEllipse(void);
[*]    vector<double> getEllipseparGauss(vector<CPoint> vec_point);
[*]    void cvFitEllipse2f( int *arrayx, int *arrayy,int n,float *box );
[*]private:
[*]    int SVD(float *a,int m,int n,float b[],float x[],float esp);
[*]    int gmiv(float a[],int m,int n,float b[],float x[],float aa[],float eps,float u[],float v[],int ka);
[*]    int ginv(float a[],int m,int n,float aa[],float eps,float u[],float v[],int ka);
[*]    int muav(float a[],int m,int n,float u[],float v[],float eps,int ka);
[*]};


//LSEllipse.cpp

view plaincopy




[*]#include"stdafx.h"
[*]#include "LSEllipse.h"
[*]#include <cmath>
[*]
[*]LSEllipse::LSEllipse(void)
[*]{
[*]}
[*]
[*]
[*]LSEllipse::~LSEllipse(void)
[*]{
[*]}
[*]//列主元高斯消去法
[*]//A为系数矩阵,x为解向量,若成功,返回true,否则返回false,并将x清空。
[*]
[*]bool RGauss(const vector<vector<double> > & A, vector<double> & x)
[*]{
[*]    x.clear();
[*]    int n = A.size();
[*]    int m = A.size();
[*]    x.resize(n);
[*]    //复制系数矩阵,防止修改原矩阵
[*]    vector<vector<double> > Atemp(n);
[*]    for (int i = 0; i < n; i++)
[*]    {
[*]      vector<double> temp(m);
[*]      for (int j = 0; j < m; j++)
[*]      {
[*]            temp = A;
[*]      }
[*]      Atemp = temp;
[*]      temp.clear();
[*]    }
[*]    for (int k = 0; k < n; k++)
[*]    {
[*]      //选主元
[*]      double max = -1;
[*]      int l = -1;
[*]      for (int i = k; i < n; i++)
[*]      {
[*]            if (abs(Atemp) > max)
[*]            {
[*]                max = abs(Atemp);
[*]                l = i;
[*]            }
[*]      }
[*]      if (l != k)
[*]      {
[*]            //交换系数矩阵的l行和k行
[*]            for (int i = 0; i < m; i++)
[*]            {
[*]                double temp = Atemp;
[*]                Atemp = Atemp;
[*]                Atemp = temp;
[*]            }
[*]      }
[*]      //消元
[*]      for (int i = k+1; i < n; i++)
[*]      {
[*]            double l = Atemp/Atemp;
[*]            for (int j = k; j < m; j++)
[*]            {
[*]                Atemp = Atemp - l*Atemp;
[*]            }
[*]      }
[*]    }
[*]    //回代
[*]    x = Atemp/Atemp;
[*]    for (int k = n-2; k >= 0; k--)
[*]    {
[*]      double s = 0.0;
[*]      for (int j = k+1; j < n; j++)
[*]      {
[*]            s += Atemp*x;
[*]      }
[*]      x = (Atemp - s)/Atemp;
[*]    }
[*]    return true;
[*]}
[*]
[*]vector<double>LSEllipse::getEllipseparGauss(vector<CPoint> vec_point)
[*]{
[*]    vector<double> vec_result;
[*]    double x3y1 = 0,x1y3= 0,x2y2= 0,yyy4= 0, xxx3= 0,xxx2= 0,x2y1= 0,yyy3= 0,x1y2= 0 ,yyy2= 0,x1y1= 0,xxx1= 0,yyy1= 0;
[*]    int N = vec_point.size();
[*]    for (int m_i = 0;m_i < N ;++m_i )
[*]    {
[*]      double xi = vec_point.x ;
[*]      double yi = vec_point.y;
[*]      x3y1 += xi*xi*xi*yi ;
[*]      x1y3 += xi*yi*yi*yi;
[*]      x2y2 += xi*xi*yi*yi; ;
[*]      yyy4 +=yi*yi*yi*yi;
[*]      xxx3 += xi*xi*xi ;
[*]      xxx2 += xi*xi ;
[*]      x2y1 += xi*xi*yi;
[*]
[*]      x1y2 += xi*yi*yi;
[*]      yyy2 += yi*yi;
[*]      x1y1 += xi*yi;
[*]      xxx1 += xi;
[*]      yyy1 += yi;
[*]      yyy3 += yi*yi*yi;
[*]    }
[*]    double resul;
[*]    resul = -(x3y1);
[*]    resul = -(x2y2);
[*]    resul = -(xxx3);
[*]    resul = -(x2y1);
[*]    resul = -(xxx2);
[*]    long double Bb,Cc,Dd,Ee,Aa;
[*]    Bb = x1y3, Cc = x2y1, Dd = x1y2, Ee = x1y1, Aa = x2y2;
[*]    Bb = yyy4, Cc = x1y2, Dd = yyy3, Ee = yyy2, Aa = x1y3;
[*]    Bb = x1y2, Cc = xxx2, Dd = x1y1, Ee = xxx1, Aa = x2y1;
[*]    Bb = yyy3, Cc= x1y1, Dd = yyy2, Ee = yyy1, Aa = x1y2;
[*]    Bb= yyy2, Cc= xxx1, Dd = yyy1, Ee = N, Aa= x1y1;
[*]
[*]    vector<vector<double>>Ma(5);
[*]    vector<double>Md(5);
[*]    for(int i=0;i<5;i++)
[*]    {
[*]      Ma.push_back(Aa);
[*]      Ma.push_back(Bb);
[*]      Ma.push_back(Cc);
[*]      Ma.push_back(Dd);
[*]      Ma.push_back(Ee);
[*]      Ma.push_back(resul);
[*]    }
[*]
[*]    RGauss(Ma,Md);
[*]    long double A=Md;
[*]    long double B=Md;
[*]    long double C=Md;
[*]    long double D=Md;
[*]    long double E=Md;
[*]    double XC=(2*B*C-A*D)/(A*A-4*B);
[*]    double YC=(2*D-A*C)/(A*A-4*B);
[*]    long double fenzi=2*(A*C*D-B*C*C-D*D+4*E*B-A*A*E);
[*]    long double fenmu=(A*A-4*B)*(B-sqrt(A*A+(1-B)*(1-B))+1);
[*]    long double fenmu2=(A*A-4*B)*(B+sqrt(A*A+(1-B)*(1-B))+1);
[*]    double XA=sqrt(fabs(fenzi/fenmu));
[*]    double XB=sqrt(fabs(fenzi/fenmu2));
[*]    double Xtheta=0.5*atan(A/(1-B))*180/3.1415926;
[*]    if(B<1)
[*]      Xtheta+=90;
[*]    vec_result.push_back(XC);
[*]    vec_result.push_back(YC);
[*]    vec_result.push_back(XA);
[*]    vec_result.push_back(XB);
[*]    vec_result.push_back(Xtheta);
[*]    return vec_result;
[*]}
[*]
[*]voidLSEllipse::cvFitEllipse2f(int *arrayx, int *arrayy,int n,float *box )
[*]{   
[*]    float cx=0,cy=0;
[*]    double rp, t;
[*]    float *A1=new float;
[*]    float *A2=new float;
[*]    float *A3=new float;
[*]    float *B1=new float,*B2=new float,*B3=new float;
[*]    const double min_eps = 1e-6;
[*]    int i;
[*]    for( i = 0; i < n; i++ )
[*]    {
[*]
[*]      cx += arrayx*1.0;
[*]      cy += arrayy*1.0;
[*]
[*]    }
[*]    cx /= n;
[*]    cy /= n;
[*]    for( i = 0; i < n; i++ )
[*]    {
[*]      int step=i*5;
[*]      float px,py;
[*]      px = arrayx*1.0;
[*]      py = arrayy*1.0;
[*]      px -= cx;
[*]      py -= cy;
[*]      B1 = 10000.0;
[*]      A1 = -px * px;
[*]      A1 = -py * py;
[*]      A1 = -px * py;
[*]      A1 = px;
[*]      A1 = py;
[*]    }
[*]    float *x1=new float;
[*]    //解出Ax^2+By^2+Cxy+Dx+Ey=10000的最小二乘解!
[*]    SVD(A1,n,5,B1,x1,min_eps);
[*]    A2=2*x1,A2=A2=x1,A2=2*x1;
[*]    B2=x1,B2=x1;
[*]    float *x2=new float;
[*]    //标准化,将一次项消掉,求出center.x和center.y;
[*]    SVD(A2,2,2,B2,x2,min_eps);
[*]    rp=x2,rp=x2;
[*]    for( i = 0; i < n; i++ )
[*]    {
[*]      float px,py;
[*]      px = arrayx*1.0;
[*]      py = arrayy*1.0;
[*]      px -= cx;
[*]      py -= cy;
[*]      B3 = 1.0;
[*]      int step=i*3;
[*]      A3 = (px - rp) * (px - rp);
[*]      A3 = (py - rp) * (py - rp);
[*]      A3 = (px - rp) * (py - rp);
[*]         
[*]    }
[*]    //求出A(x-center.x)^2+B(y-center.y)^2+C(x-center.x)(y-center.y)的最小二乘解
[*]    SVD(A3,n,3,B3,x1,min_eps);
[*]
[*]    rp = -0.5 * atan2(x1, x1 - x1);
[*]    t = sin(-2.0 * rp);
[*]    if( fabs(t) > fabs(x1)*min_eps )
[*]      t = x1/t;
[*]    else
[*]      t = x1 - x1;
[*]    rp = fabs(x1 + x1 - t);
[*]    if( rp > min_eps )
[*]      rp = sqrt(2.0 / rp);
[*]    rp = fabs(x1 + x1 + t);
[*]    if( rp > min_eps )
[*]      rp = sqrt(2.0 / rp);
[*]      
[*]    box = (float)rp + cx;
[*]    box= (float)rp + cy;
[*]    box= (float)(rp*2);
[*]    box = (float)(rp*2);
[*]    if( box > box )
[*]    {
[*]      double tmp=box;
[*]      box=box;
[*]      box=tmp;
[*]    }
[*]    box = (float)(90 + rp*180/3.1415926);
[*]    if( box < -180 )
[*]      box += 360;
[*]    if( box > 360 )
[*]      box -= 360;
[*]    delete []A1;
[*]    delete []A2;
[*]    delete []A3;
[*]    delete []B1;
[*]    delete []B2;
[*]    delete []B3;
[*]    delete []x1;
[*]    delete []x2;
[*]
[*]}
[*]
[*]int LSEllipse::SVD(float *a,int m,int n,float b[],float x[],float esp)
[*]{   
[*]    float *aa;
[*]    float *u;
[*]    float *v;
[*]    aa=new float;
[*]    u=newfloat;
[*]    v=newfloat;
[*]   
[*]   int ka;
[*]   intflag;
[*]   if(m>n)
[*]   {   
[*]    ka=m+1;
[*]   }else
[*]   {
[*]       ka=n+1;
[*]   }
[*]   
[*]   flag=gmiv(a,m,n,b,x,aa,esp,u,v,ka);
[*]   
[*]      
[*]      
[*]    delete []aa;
[*]    delete []u;
[*]    delete []v;
[*]      
[*]    return(flag);
[*]}
[*]
[*]
[*]
[*]
[*]
[*]int LSEllipse::gmiv( float a[],int m,int n,float b[],float x[],float aa[],float eps,float u[],float v[],int ka)   
[*]{   
[*]    int i,j;
[*]    i=ginv(a,m,n,aa,eps,u,v,ka);
[*]
[*]    if (i<0) return(-1);
[*]    for (i=0; i<=n-1; i++)
[*]      { x=0.0;
[*]      for (j=0; j<=m-1; j++)
[*]          x=x+aa*b;
[*]      }
[*]    return(1);
[*]}
[*]
[*]
[*]int LSEllipse::ginv(float a[],int m,int n,float aa[],float eps,float u[],float v[],int ka)
[*]{   
[*]
[*] //int muav(float a[],int m,int n,float u[],float v[],float eps,int ka);
[*]      
[*]    int i,j,k,l,t,p,q,f;
[*]    i=muav(a,m,n,u,v,eps,ka);
[*]    if (i<0) return(-1);
[*]    j=n;
[*]    if (m<n) j=m;
[*]    j=j-1;
[*]    k=0;
[*]    while ((k<=j)&&(a!=0.0)) k=k+1;
[*]    k=k-1;
[*]    for (i=0; i<=n-1; i++)
[*]    for (j=0; j<=m-1; j++)
[*]      { t=i*m+j; aa=0.0;
[*]      for (l=0; l<=k; l++)
[*]          { f=l*n+i; p=j*m+l; q=l*n+l;
[*]            aa=aa+v*u/a;
[*]          }
[*]      }
[*]    return(1);
[*]}
[*]
[*]
[*]
[*]
[*]
[*]
[*]int LSEllipse::muav(float a[],int m,int n,float u[],float v[],float eps,int ka)
[*]{ int i,j,k,l,it,ll,kk,ix,iy,mm,nn,iz,m1,ks;
[*]    float d,dd,t,sm,sm1,em1,sk,ek,b,c,shh,fg,cs;
[*]    float *s,*e,*w;
[*]    //void ppp();
[*]   // void sss();
[*]   void ppp(float a[],float e[],float s[],float v[],int m,int n);
[*]   void sss(float fg[],float cs[]);
[*]
[*]    s=(float *) malloc(ka*sizeof(float));
[*]    e=(float *) malloc(ka*sizeof(float));
[*]    w=(float *) malloc(ka*sizeof(float));
[*]    it=60; k=n;
[*]    if (m-1<n) k=m-1;
[*]    l=m;
[*]    if (n-2<m) l=n-2;
[*]    if (l<0) l=0;
[*]    ll=k;
[*]    if (l>k) ll=l;
[*]    if (ll>=1)
[*]      { for (kk=1; kk<=ll; kk++)
[*]          { if (kk<=k)
[*]            { d=0.0;
[*]                for (i=kk; i<=m; i++)
[*]                  { ix=(i-1)*n+kk-1; d=d+a*a;}
[*]                s=(float)sqrt(d);
[*]                if (s!=0.0)
[*]                  { ix=(kk-1)*n+kk-1;
[*]                  if (a!=0.0)
[*]                      { s=(float)fabs(s);
[*]                        if (a<0.0) s=-s;
[*]                      }
[*]                  for (i=kk; i<=m; i++)
[*]                      { iy=(i-1)*n+kk-1;
[*]                        a=a/s;
[*]                      }
[*]                  a=1.0f+a;
[*]                  }
[*]                s=-s;
[*]            }
[*]            if (n>=kk+1)
[*]            { for (j=kk+1; j<=n; j++)
[*]                  { if ((kk<=k)&&(s!=0.0))
[*]                      { d=0.0;
[*]                        for (i=kk; i<=m; i++)
[*]                        { ix=(i-1)*n+kk-1;
[*]                            iy=(i-1)*n+j-1;
[*]                            d=d+a*a;
[*]                        }
[*]                        d=-d/a[(kk-1)*n+kk-1];
[*]                        for (i=kk; i<=m; i++)
[*]                        { ix=(i-1)*n+j-1;
[*]                            iy=(i-1)*n+kk-1;
[*]                            a=a+d*a;
[*]                        }
[*]                      }
[*]                  e=a[(kk-1)*n+j-1];
[*]                  }
[*]            }
[*]            if (kk<=k)
[*]            { for (i=kk; i<=m; i++)
[*]                  { ix=(i-1)*m+kk-1; iy=(i-1)*n+kk-1;
[*]                  u=a;
[*]                  }
[*]            }
[*]            if (kk<=l)
[*]            { d=0.0;
[*]                for (i=kk+1; i<=n; i++)
[*]                  d=d+e*e;
[*]                e=(float)sqrt(d);
[*]                if (e!=0.0)
[*]                  { if (e!=0.0)
[*]                      { e=(float)fabs(e);
[*]                        if (e<0.0) e=-e;
[*]                      }
[*]                  for (i=kk+1; i<=n; i++)
[*]                      e=e/e;
[*]                  e=1.0f+e;
[*]                  }
[*]                e=-e;
[*]                if ((kk+1<=m)&&(e!=0.0))
[*]                  { for (i=kk+1; i<=m; i++) w=0.0;
[*]                  for (j=kk+1; j<=n; j++)
[*]                      for (i=kk+1; i<=m; i++)
[*]                        w=w+e*a[(i-1)*n+j-1];
[*]                  for (j=kk+1; j<=n; j++)
[*]                      for (i=kk+1; i<=m; i++)
[*]                        { ix=(i-1)*n+j-1;
[*]                        a=a-w*e/e;
[*]                        }
[*]                  }
[*]                for (i=kk+1; i<=n; i++)
[*]                  v[(i-1)*n+kk-1]=e;
[*]            }
[*]          }
[*]      }
[*]    mm=n;
[*]    if (m+1<n) mm=m+1;
[*]    if (k<n) s=a;
[*]    if (m<mm) s=0.0;
[*]    if (l+1<mm) e=a;
[*]    e=0.0;
[*]    nn=m;
[*]    if (m>n) nn=n;
[*]    if (nn>=k+1)
[*]      { for (j=k+1; j<=nn; j++)
[*]          { for (i=1; i<=m; i++)
[*]            u[(i-1)*m+j-1]=0.0;
[*]            u[(j-1)*m+j-1]=1.0;
[*]          }
[*]      }
[*]    if (k>=1)
[*]      { for (ll=1; ll<=k; ll++)
[*]          { kk=k-ll+1; iz=(kk-1)*m+kk-1;
[*]            if (s!=0.0)
[*]            { if (nn>=kk+1)
[*]                  for (j=kk+1; j<=nn; j++)
[*]                  { d=0.0;
[*]                      for (i=kk; i<=m; i++)
[*]                        { ix=(i-1)*m+kk-1;
[*]                        iy=(i-1)*m+j-1;
[*]                        d=d+u*u/u;
[*]                        }
[*]                      d=-d;
[*]                      for (i=kk; i<=m; i++)
[*]                        { ix=(i-1)*m+j-1;
[*]                        iy=(i-1)*m+kk-1;
[*]                        u=u+d*u;
[*]                        }
[*]                  }
[*]                  for (i=kk; i<=m; i++)
[*]                  { ix=(i-1)*m+kk-1; u=-u;}
[*]                  u=1.0f+u;
[*]                  if (kk-1>=1)
[*]                  for (i=1; i<=kk-1; i++)
[*]                      u[(i-1)*m+kk-1]=0.0;
[*]            }
[*]            else
[*]            { for (i=1; i<=m; i++)
[*]                  u[(i-1)*m+kk-1]=0.0;
[*]                u[(kk-1)*m+kk-1]=1.0;
[*]            }
[*]          }
[*]      }
[*]    for (ll=1; ll<=n; ll++)
[*]      { kk=n-ll+1; iz=kk*n+kk-1;
[*]      if ((kk<=l)&&(e!=0.0))
[*]          { for (j=kk+1; j<=n; j++)
[*]            { d=0.0;
[*]                for (i=kk+1; i<=n; i++)
[*]                  { ix=(i-1)*n+kk-1; iy=(i-1)*n+j-1;
[*]                  d=d+v*v/v;
[*]                  }
[*]                d=-d;
[*]                for (i=kk+1; i<=n; i++)
[*]                  { ix=(i-1)*n+j-1; iy=(i-1)*n+kk-1;
[*]                  v=v+d*v;
[*]                  }
[*]            }
[*]          }
[*]      for (i=1; i<=n; i++)
[*]          v[(i-1)*n+kk-1]=0.0;
[*]      v=1.0;
[*]      }
[*]    for (i=1; i<=m; i++)
[*]    for (j=1; j<=n; j++)
[*]      a[(i-1)*n+j-1]=0.0;
[*]    m1=mm; it=60;
[*]    while (1==1)
[*]      { if (mm==0)
[*]          { ppp(a,e,s,v,m,n);
[*]            free(s); free(e); free(w); return(1);
[*]          }
[*]      if (it==0)
[*]          { ppp(a,e,s,v,m,n);
[*]            free(s); free(e); free(w); return(-1);
[*]          }
[*]      kk=mm-1;
[*]    while ((kk!=0)&&(fabs(e)!=0.0))
[*]          { d=(float)(fabs(s)+fabs(s));
[*]            dd=(float)fabs(e);
[*]            if (dd>eps*d) kk=kk-1;
[*]            else e=0.0;
[*]          }
[*]      if (kk==mm-1)
[*]          { kk=kk+1;
[*]            if (s<0.0)
[*]            { s=-s;
[*]                for (i=1; i<=n; i++)
[*]                  { ix=(i-1)*n+kk-1; v=-v;}
[*]            }
[*]            while ((kk!=m1)&&(s<s))
[*]            { d=s; s=s; s=d;
[*]                if (kk<n)
[*]                  for (i=1; i<=n; i++)
[*]                  { ix=(i-1)*n+kk-1; iy=(i-1)*n+kk;
[*]                      d=v; v=v; v=d;
[*]                  }
[*]                if (kk<m)
[*]                  for (i=1; i<=m; i++)
[*]                  { ix=(i-1)*m+kk-1; iy=(i-1)*m+kk;
[*]                      d=u; u=u; u=d;
[*]                  }
[*]                kk=kk+1;
[*]            }
[*]            it=60;
[*]            mm=mm-1;
[*]          }
[*]      else
[*]          { ks=mm;
[*]            while ((ks>kk)&&(fabs(s)!=0.0))
[*]            { d=0.0;
[*]                if (ks!=mm) d=d+(float)fabs(e);
[*]                if (ks!=kk+1) d=d+(float)fabs(e);
[*]                dd=(float)fabs(s);
[*]                if (dd>eps*d) ks=ks-1;
[*]                else s=0.0;
[*]            }
[*]            if (ks==kk)
[*]            { kk=kk+1;
[*]                d=(float)fabs(s);
[*]                t=(float)fabs(s);
[*]                if (t>d) d=t;
[*]                t=(float)fabs(e);
[*]                if (t>d) d=t;
[*]                t=(float)fabs(s);
[*]                if (t>d) d=t;
[*]                t=(float)fabs(e);
[*]                if (t>d) d=t;
[*]                sm=s/d; sm1=s/d;
[*]                em1=e/d;
[*]                sk=s/d; ek=e/d;
[*]                b=((sm1+sm)*(sm1-sm)+em1*em1)/2.0f;
[*]                c=sm*em1; c=c*c; shh=0.0;
[*]                if ((b!=0.0)||(c!=0.0))
[*]                  { shh=(float)sqrt(b*b+c);
[*]                  if (b<0.0) shh=-shh;
[*]                  shh=c/(b+shh);
[*]                  }
[*]                fg=(sk+sm)*(sk-sm)-shh;
[*]                fg=sk*ek;
[*]                for (i=kk; i<=mm-1; i++)
[*]                  { sss(fg,cs);
[*]                  if (i!=kk) e=fg;
[*]                  fg=cs*s+cs*e;
[*]                  e=cs*e-cs*s;
[*]                  fg=cs*s;
[*]                  s=cs*s;
[*]                  if ((cs!=1.0)||(cs!=0.0))
[*]                      for (j=1; j<=n; j++)
[*]                        { ix=(j-1)*n+i-1;
[*]                        iy=(j-1)*n+i;
[*]                        d=cs*v+cs*v;
[*]                        v=-cs*v+cs*v;
[*]                        v=d;
[*]                        }
[*]                  sss(fg,cs);
[*]                  s=fg;
[*]                  fg=cs*e+cs*s;
[*]                  s=-cs*e+cs*s;
[*]                  fg=cs*e;
[*]                  e=cs*e;
[*]                  if (i<m)
[*]                      if ((cs!=1.0)||(cs!=0.0))
[*]                        for (j=1; j<=m; j++)
[*]                        { ix=(j-1)*m+i-1;
[*]                            iy=(j-1)*m+i;
[*]                            d=cs*u+cs*u;
[*]                            u=-cs*u+cs*u;
[*]                            u=d;
[*]                        }
[*]                  }
[*]                e=fg;
[*]                it=it-1;
[*]            }
[*]            else
[*]            { if (ks==mm)
[*]                  { kk=kk+1;
[*]                  fg=e; e=0.0;
[*]                  for (ll=kk; ll<=mm-1; ll++)
[*]                      { i=mm+kk-ll-1;
[*]                        fg=s;
[*]                        sss(fg,cs);
[*]                        s=fg;
[*]                        if (i!=kk)
[*]                        { fg=-cs*e;
[*]                            e=cs*e;
[*]                        }
[*]                        if ((cs!=1.0)||(cs!=0.0))
[*]                        for (j=1; j<=n; j++)
[*]                            { ix=(j-1)*n+i-1;
[*]                              iy=(j-1)*n+mm-1;
[*]                              d=cs*v+cs*v;
[*]                              v=-cs*v+cs*v;
[*]                              v=d;
[*]                            }
[*]                      }
[*]                  }
[*]                else
[*]                  { kk=ks+1;
[*]                  fg=e;
[*]                  e=0.0;
[*]                  for (i=kk; i<=mm; i++)
[*]                      { fg=s;
[*]                        sss(fg,cs);
[*]                        s=fg;
[*]                        fg=-cs*e;
[*]                        e=cs*e;
[*]                        if ((cs!=1.0)||(cs!=0.0))
[*]                        for (j=1; j<=m; j++)
[*]                            { ix=(j-1)*m+i-1;
[*]                              iy=(j-1)*m+kk-2;
[*]                              d=cs*u+cs*u;
[*]                              u=-cs*u+cs*u;
[*]                              u=d;
[*]                            }
[*]                      }
[*]                  }
[*]            }
[*]          }
[*]      }
[*]   
[*]    free(s);free(e);free(w);   
[*]      return(1);
[*]
[*]
[*]}
[*]
[*]   
[*]void ppp(float a[],float e[],float s[],float v[],int m,int n)   
[*]{ int i,j,p,q;
[*]    float d;
[*]    if (m>=n) i=n;
[*]    else i=m;
[*]    for (j=1; j<=i-1; j++)
[*]      { a[(j-1)*n+j-1]=s;
[*]      a[(j-1)*n+j]=e;
[*]      }
[*]    a[(i-1)*n+i-1]=s;
[*]    if (m<n) a[(i-1)*n+i]=e;
[*]    for (i=1; i<=n-1; i++)
[*]    for (j=i+1; j<=n; j++)
[*]      { p=(i-1)*n+j-1; q=(j-1)*n+i-1;
[*]      d=v; v=v; v=d;
[*]      }
[*]    return;
[*]}
[*]
[*]   
[*]void sss(float fg[],float cs[])
[*] { float r,d;
[*]    if ((fabs(fg)+fabs(fg))==0.0)
[*]      { cs=1.0; cs=0.0; d=0.0;}
[*]    else   
[*]      { d=(float)sqrt(fg*fg+fg*fg);
[*]      if (fabs(fg)>fabs(fg))
[*]          { d=(float)fabs(d);
[*]            if (fg<0.0) d=-d;
[*]          }
[*]      if (fabs(fg)>=fabs(fg))
[*]          { d=(float)fabs(d);
[*]            if (fg<0.0) d=-d;
[*]          }
[*]      cs=fg/d; cs=fg/d;
[*]      }
[*]    r=1.0;
[*]    if (fabs(fg)>fabs(fg)) r=cs;
[*]    else
[*]      if (cs!=0.0) r=1.0f/cs;
[*]    fg=d; fg=r;
[*]    return;
[*]}

利用VC效果如下:


其中青色的线为第一种方法的效果,黑色为第二种方法的拟合效果。

wuyanfan 发表于 2023-12-20 17:07:48

点赞!
ObjectARX 同道友人{:1_12:}
页: [1]
查看完整版本: 最小二乘法椭圆拟合