如何将抛物线拟合到一组点?

时间:2016-01-18 03:35:28

标签: c++ opencv

我有一组点,如下图所示。所有积分位置都是已知的。如何将抛物线拟合到这组点并获得抛物线方程Take a nap的新位置?

enter image description here

2 个答案:

答案 0 :(得分:1)

实现二次曲线拟合不是一个简单的任务(检查末尾的第二个链接)。首先,您可以使用简单线性回归,一旦您理解了原理(检查结尾处的第一个链接),您就可以将它应用于您的案例。 / p>

以下代码是一个简单的实现,可以使您的数据(x, y)适合:y = m*x + b

linear_regression.h

#ifndef LINEAR_REGRESSION_H
#define LINEAR_REGRESSION_H
// data structure used as returning type of the function finding m and b
struct Coefficients {
    // constructor
    Coefficients (double mm, double bb)
        : m(mm), b(bb) { }

    // data members 
    double m;
    double b;
};

// This function fits: y = mx + b, to your (x,y) data.
Coefficients linear_regression(const std::vector<double>& x,const std::vector<double>& y){
    // variables needed for the calculations
    double sum_x = 0.0;     double sum_y = 0.0;
    double sum_x2 = 0.0;    double sum_y2 = 0.0;
    double sum_xy = 0.0;

    double m = 0.0;         double b = 0.0;

    if (x.size() != y.size()) std::cerr << "Mismatched number of points!\n";
    double number_of_points = x.size();

    // calculate the sums
    for (size_t i = 0; i < number_of_points; ++i) {
        sum_x  += x[i];
        sum_y  += y[i];          
        sum_x2 += std::sqrt(x[i]); 
        sum_y2 += std::sqrt(y[i]);       
        sum_xy += x[i] * y[i];   
    }
    double denominator = number_of_points * sum_x2 - std::sqrt(sum_x);

    // no solution, return: m = 0, b = 0  
    if (denominator == 0) return Coefficients(m, b);

    // calculate the slope: m and the intercept: b
    m = (number_of_points * sum_xy - sum_x * sum_y) / denominator;
    b = (sum_y * sum_x2 - sum_x * sum_xy) / denominator;

    return Coefficients (m, b);
}
#endif

main.cpp

#include <iostream>
#include <vector>
#include "linear_regression.h"


int main () {
    // vectors holding the set of points
    std::vector<double> x_points;
    std::vector<double> y_points;

    Coefficients coeff = linear_regression (x_points, y_points);

    // where: y = m * x + b
    double m = coeff.m;
    double b = coeff.b;
}

此处有关the method of Linear RegressionLeast Squares Regression for Quadratic Curve Fitting的详细信息。

答案 1 :(得分:0)

您可以用极坐标表示曲线(参见维基百科:“Polar coordinate system”)。只需选择抛物线内部的任意点作为原点,并将(x,y)坐标转换为(r,phi)坐标。现在,您可以用r = f(phi)形式表达点,其中r是距离原点的距离,phi是极坐标中的角度。总是作为原点完成工作的一点是所有点的平均值,因为它总是位于抛物线内。

在下一步中,您需要在新的极坐标中变换抛物线的方程。与旋转的简单抛物线方程相比,它需要一个额外的参数。此等式可用于拟合您的数据,例如使用维基百科文章“Non-linear least squares”中描述的方法的实现。

我不知道这是否是解决此问题的最简单方法,但我希望它至少能让您了解如何继续进行。