码迷,mamicode.com
首页 > 其他好文 > 详细

Modified Least Square Method Fit Circle from Data

时间:2016-09-20 16:31:17      阅读:213      评论:0      收藏:0      [点我收藏+]

标签:

In OpenCv, it only provide the function fitEllipse to fit Ellipse, but doesn‘t provide function to fit circle, so i read some paper, and write a function to do it.

template<typename _tp>
struct Circle_
{
    _tp x;
    _tp y;
    _tp r;
};

typedef Circle_<float> Circle3f;

// This function is based on Modified Least Square Methods from Paper
// "A Few Methods for Fitting Circles to Data".
void FitCircle(const std::vector<cv::Point2f> &vecPoints, Circle3f &circle)
{
    double Sx = 0., Sy = 0., Sxx = 0., Sx2 = 0., Sy2 = 0., Sxy = 0., Syy = 0., Sx3 = 0., Sy3 = 0., Sxy2 = 0., Syx2 = 0.;
    for ( const auto &point : vecPoints )   {
        Sx   += point.x;
        Sy   += point.y;
        Sx2  += point.x * point.x;
        Sy2  += point.y * point.y;
        Sxy  += point.x * point.y;
        Sx3  += point.x * point.x * point.x;
        Sy3  += point.y * point.y * point.y;
        Sxy2 += point.x * point.y * point.y;
        Syx2 += point.y * point.x * point.x;
    }

    double A, B, C, D, E;
    int n = vecPoints.size();
    A = n * Sx2 - Sx * Sx;
    B = n * Sxy - Sx * Sy;
    C = n * Sy2 - Sy * Sy;
    D = 0.5 * ( n * Sxy2 - Sx * Sy2 + n * Sx3 - Sx * Sx2 );
    E = 0.5 * ( n * Syx2 - Sy * Sx2 + n * Sy3 - Sy * Sy2 );

    auto AC_B2 = ( A * C - B * B);  // The variable name is from AC - B^2
    auto am = ( D * C - B * E ) / AC_B2;
    auto bm = ( A * E - B * D ) / AC_B2;

    double rSqureSum = 0.f;
    for ( const auto &point : vecPoints )
    {
        rSqureSum += sqrt ( ( point.x - am ) * ( point.x - am ) + ( point.y - bm) * ( point.y - bm) );
    }
    auto r = rSqureSum / n;
    circle.x = static_cast<float>( am );
    circle.y = static_cast<float>( bm );
    circle.r = static_cast<float>( r );
}

void TestFitCircle()
{
    std::vector<cv::Point2f> vecPoints;
    vecPoints.push_back(cv::Point2f(0, 10));
    vecPoints.push_back(cv::Point2f(0.1f, 10.1f));
    vecPoints.push_back(cv::Point2f(10, 0));
    vecPoints.push_back(cv::Point2f(10, 20));
    vecPoints.push_back(cv::Point2f(20, 10));

    Circle3f circle; 
    FitCircle(vecPoints, circle);

    cout << "X, Y " <<circle.x << ", " << circle.y << "    r " << circle.r << endl;
}

 

Modified Least Square Method Fit Circle from Data

标签:

原文地址:http://www.cnblogs.com/shengguang/p/5889172.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!