我希望对此代码多加关注。应该为一组数据点找到一个最合适的椭圆。问题是长轴和短轴(aDist和bDist)的长度超出了应有的范围。

输入:

  • points-数据点的一组(x,y)坐标; x和y为非负
  • avgX,avgY-所有数据点的x和y坐标的平均值

  • 输出:
  • aDist,bDist-长轴和短轴的长度
  •         // 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与形状成比例,但总是太大。例如,如果“点”是100x100的圆圈,则aDist和bDist为582。

    更新:总结了mat之后,我现在按照Mike的建议将每个元素除以points->size()。如果points是平方,则aDistbDist现在为5,这与预期的太小了。随着向该正方形添加更多像素,aDistbDist变小。例如,给出sqrt(18.75)= 4.33的半径。

    最佳答案

    您需要将mat除以总点数以获得正确的协方差矩阵。

    关于c++ - 最佳椭圆代码中的错误,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/3427309/

    10-10 21:38