user10293932
user10293932

Reputation: 31

Polynomial curve fitting in OpenCV c++

I have implemented a polynomial curve fitting method in C++ OpenCV based on the fact that any function can be approximated with the power function. The equation is then written into matrix form and is being solved. Basically, the code is this:

PolynomialFit(std::vector<cv::Point>& points, int order) {

    cv::Mat U(points.size(), (order + 1), CV_64F);
    cv::Mat Y(points.size(), 1, CV_64F);
    
    for (int i = 0; i < U.rows; i++) {
        for (int j = 0; j < U.cols; j++) {
            U.at<double>(i, j) = pow(points[i].x, j);
        }
    }
     
    for (int i = 0; i < Y.rows; i++) {
        Y.at<double>(i, 0) = points[i].y;
    }

    cv::Mat K((order + 1), 1, CV_64F);
    if(U.data != NULL) {
        K = (U.t() * U).inv() * U.t() * Y;
    }

and in main this is how I call it:

int order = 2;
        cv::Mat K = PolynomialFit(_points, order);
        
        if(_points.size() > 0) {
            for (int j = _points.at(0).x; j < _points.at(_points.size() - 1).x; j++) {

                cv::Point2d point(j, 0);
                for (int k = 0; k < order + 1; k++) {
                    point.y += K.at<double>(k, 0) * std::pow(j, k);
                }
                
                cv::circle(image, point, 1, cv::Scalar(0, 255, 0), CV_FILLED, CV_AA);
            }
        }

The problem is, it only works for a certain type of points. For example, in the image below, it only works for the points that are in the left curve. How could I change this behaviour? I already tried changing the order parameter, but the right curve won't fit as it should be. enter image description here

Upvotes: 1

Views: 2691

Answers (1)

pullidea-dev
pullidea-dev

Reputation: 1803

For calculating fit curve, it has to transform axis. As you see below, you can get 2 fit curves with horizontal x axis and vertical x axis, and then get the sum of erro power, select one curve which has minium sum.

For this, you can exchange x and y from your code of PolynomialFit function.

The axis of the 1st curve

The axis of the 2nd curve

enter image description here

Upvotes: 2

Related Questions