2017-03-05 62 views
0

我试图对我们的数据进行反向工程,以显然应该是概率椭圆。作为一个输入,我得到一个包含神秘成员的结构,特别是meanX,meanY,Co00,Co01和Co10。我猜想x和y是椭圆的中心,CoXX是协方差矩阵。听起来像我应该使用特征值和特征向量来找出椭圆的两个半径。我找到了Eigen C++库,但是当我得到向量和值时,我很难弄清楚与Eigen计算结果有什么关系。我如何找到两个半径和椭圆倾斜?从协方差矩阵中找出概率椭圆

回答

2

设:

m = (meanX) 
    (meanY) 

是(载体)是指和:

S = (Co00 Co01) 
    (Co01 Co11) 

是数据的协方差矩阵。椭圆的中心是m,椭圆的轴是矩阵S的特征向量e1e2(短轴e1S的最小特征值相关联)。半径与sqrt(λ1)sqrt(λ2)成正比,其中λ1λ2是与e1e2相关联的特征值。最后,椭圆的倾斜是atan2(e2_y, e2_x)(主轴与轴之间的角度)。

这一切都来自矩阵S对角化和扩大表达式(X - m)^T S^-1 (X - m) = 1以匹配预期的形式(x/a)^2 + (y/b)^2 = 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