2017-03-05 147 views
0

私は明らかに確率楕円でなければならないものにデータをリバースエンジニアリングしようとしています。入力として、わかりやすいメンバー、特にmeanX、meanY、Co00、Co01およびCo10を含む構造体を取得します。私はxとyが楕円の中心であり、CoXXは共分散行列であると思います。楕円の2つの半径を見つけるために固有値と固有ベクトルを使用する必要があります。私はEigenのC++ライブラリを見つけましたが、ベクターと値を取得したときにEigen計算結果と何をすればいいのか分かりにくいです。 2つの半径と楕円の傾きを見つけるにはどうすればよいですか?共分散行列から確率楕円を求める

答えて

2

う:

m = (meanX) 
    (meanY) 

は(ベクトル)であることを意味すると:

S = (Co00 Co01) 
    (Co01 Co11) 

は、データの共分散行列です。楕円の中心はmであり、楕円の軸はSの固有ベクトルe1e2です(副軸e1Sの最小固有値に関連付けられています)。半径は、sqrt(λ1)およびsqrt(λ2)に比例し、λ1およびλ2は、e1およびe2に関連付けられた固有値です。最後に、楕円の傾きは、atan2(e2_y, e2_x)(長軸とx軸との間の角度)である。

これはすべて、行列Sを対角化し、式と一致する式(X - m)^T S^-1 (X - m) = 1を展開したものです。特定の信頼水準を見ている場合は半径をスケーリングする必要があり、95%の信頼度の場合はスケーリング係数はsqrt(5.911)です。固有で

、次のコードは動作するはずです:

#include <Eigen/Eigenvalues> 

// [...] 

Vector2d m; 
Matrix2d S; 

m << meanX, meanY; 
S << Co00, Co01, Co01, Co11; 

SelfAdjointEigenSolver<Matrix2d> solver(S); 
double l1 = solver.eigenvalues().x(); 
double l2 = solver.eigenvalues().y(); 
Vector2d e1 = solver.eigenvectors().col(0); 
Vector2d e2 = solver.eigenvectors().col(1); 

double scale95 = sqrt(5.991); 
double R1 = scale95 * sqrt(l1); 
double R2 = scale95 * sqrt(l2); 
double tilt = atan2(e2.y(), e2.x()); 
+0

あなたは男です! OpenCVと同じような出力が得られます。ありがとうございました! – kreuzerkrieg

関連する問題