代码之家  ›  专栏  ›  技术社区  ›  jlstrecker

最佳拟合椭圆代码中的错误

c++
  •  1
  • jlstrecker  · 技术社区  · 14 年前

    我会很感激在这个代码上的额外的眼睛集。它应该为一组数据点找到一个最合适的椭圆。问题是,大调的长度;短轴(aDist和bDist)比它们应该的要大。

    • 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是成比例的形状,但总是太大。例如,如果“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。

    1 回复  |  直到 14 年前
        1
  •  1
  •   Mike Seymour    14 年前

    你需要分开 mat