ちょくせんフィットアルゴリズム


コンピュータビジュアルの応用では,直線の正確な位置を抽出する作業がしばしば用いられる.このときは直線のフィットアルゴリズムが使われます.
ここでは、最小二乗法を用いて最適フィット直線を計算するコードも貼ります.
このコードは私が以前『機械視覚アルゴリズムと応用(バイリンガル版)』[徳]スティーグ(Steger C)著を勉強したものです.楊少栄などが訳した本の時に書いた.すべての公式の導出は本の中で3.8.1で、まあまあ役に立ちます.一元線形回帰アルゴリズムとの違い:一元線形回帰アルゴリズムはXが誤差がなく、Yだけが誤差があると仮定する.このアルゴリズムは,各点のX Y座標の誤差が0平均の正規分布に合致すると仮定する.従って,計算機視覚の応用では,通常の一元線形回帰フィッティングの結果よりも良好である.
#include 
#include 
#include 

///        Qt5    QVector   QPoint。                。

/**
  *          (             )
  *          a x + b y + c = 0    
  *        X Y           0         。
  *             :           X      ,   Y    。
  */
bool lineFit(const QVector &points, double &a, double &b, double &c)
{
     int size = points.size();
     if(size < 2)
     {
         a = 0;
         b = 0;
         c = 0;
         return false;
     }
     double x_mean = 0;
     double y_mean = 0;
     for(int i = 0; i < size; i++)
     {
         x_mean += points[i].x();
         y_mean += points[i].y();
     }
     x_mean /= size;
     y_mean /= size; //  ,     x y    

     double Dxx = 0, Dxy = 0, Dyy = 0;

     for(int i = 0; i < size; i++)
     {
         Dxx += (points[i].x() - x_mean) * (points[i].x() - x_mean);
         Dxy += (points[i].x() - x_mean) * (points[i].y() - y_mean);
         Dyy += (points[i].y() - y_mean) * (points[i].y() - y_mean);
     }
     double lambda = ( (Dxx + Dyy) - sqrt( (Dxx - Dyy) * (Dxx - Dyy) + 4 * Dxy * Dxy) ) / 2.0;
     double den = sqrt( Dxy * Dxy + (lambda - Dxx) * (lambda - Dxx) );
     a = Dxy / den;
     b = (lambda - Dxx) / den;
     c = - a * x_mean - b * y_mean;
     return true;
}