我会很感激在这个代码上的额外的眼睛集。它应该为一组数据点找到一个最合适的椭圆。问题是,大调的长度;短轴(aDist和bDist)比它们应该的要大。
-
-
avgX,avgY—所有数据点的x和y坐标的平均值
输出:
// Find a and b -- use principal component analysis
// http://ask.metafilter.com/36213/Best-Fit-Ellipse (2nd reply)
// http://number-none.com/product/My%20Friend,%20the%20Covariance%20Body/index.html
double mat[2][2]; // Will be the covariance matrix.
// Eigenvectors will be major & minor axes. Eigenvalues will be lengths of axes, squared.
mat[0][0] = mat[0][1] = mat[1][0] = mat[1][1] = 0;
for (CPixelList::iterator i = points->begin(); i != points->end(); i++)
{
// Add [ x - avgX, y - avgY ] * [ x - avgX ] to mat
// [ y - avgY ]
double diffX = i->x - avgX;
double diffY = i->y - avgY;
mat[0][0] += diffX * diffX;
mat[0][1] += diffX * diffY;
mat[1][1] += diffY * diffY;
}
mat[1][0] = mat[0][1];
// http://www.math.harvard.edu/archive/21b_fall_04/exhibits/2dmatrices/index.html
double T = mat[0][0] + mat[1][1]; // Trace
double D = mat[0][0] * mat[1][1] - mat[0][1] * mat[1][0]; // Determinant
double L1 = T/2 + sqrt(T*T/4 - D); // Eigenvalues
double L2 = T/2 - sqrt(T*T/4 - D); //
aDist = sqrt(L1);
bDist = sqrt(L2);
我已经检查了调试器中的输入,它们看起来正常。我已经尝试了一些简单的形状(圆,椭圆,矩形)的代码没有旋转,和aDist和bDist是成比例的形状,但总是太大。例如,如果“points”是一个100x100的圆,那么aDist和bDist是582。
更新:
总结之后
mat
,我现在将每个元素除以
points->size()
,正如迈克所说。如果
points
是正方形<(0,0)、(10,0)、(10,10)、(0,10)>,然后
aDist
和
bDist
如期而至
太小了。当更多的像素被添加到正方形上时,
阿迪斯特
和
变小点。例如,<(0,0)、(5,0)、(10,0)、(10,5)、(10,10)、(5,10)、(0,10)、(0,5)>半径为sqrt(18.75)=4.33。