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