版权声明:https://github.com/stslinux https://blog.csdn.net/qq_20797273/article/details/83930101
OpenCV最小二乘法:cv::solve函数
本例程通过opencv库函数对一系列点进行三次曲线拟合,最小二乘法原理可自行百度理解
#include<iostream>
#include<opencv2/opencv.hpp>
using namespace std;
using namespace cv;
bool polynomial_curve_fit(vector<Point2f>& key_point, vector<Point2f>& poly_point, int n, Mat& A)
{
//Number of key points
int N = key_point.size();
//构造X
Mat X = Mat::zeros(n + 1, n + 1, CV_64FC1);
for (int i = 0; i < n + 1; i++)
{
for (int j = 0; j < n + 1; j++)
{
for (int k = 0; k < N; k++)
{
X.at<double>(i, j) = X.at<double>(i, j) +pow(key_point[k].x, i + j);
}
}
}
//构造Y
Mat Y = Mat::zeros(n + 1, 1, CV_64FC1);
for (int i = 0; i < n + 1; i++)
{
for (int k = 0; k < N; k++)
{
Y.at<double>(i, 0) = Y.at<double>(i, 0) + pow(key_point[k].x, i) * key_point[k].y;
}
}
A = Mat::zeros(n + 1, 1, CV_64FC1);
//求解A
solve(X, Y, A,DECOMP_LU);
for (float x = 0; x < 4.; x+=0.112)
{
double y = A.at<double>(0, 0) + A.at<double>(1, 0) * x +
A.at<double>(2, 0)*pow(x, 2) + A.at<double>(3, 0)*pow(x, 3);
poly_point.push_back(Point2f(x, y));
}
return true;
}
int main()
{
Mat image = Mat::zeros(480, 640, CV_8UC3);
image.setTo(Scalar(100, 0, 0));
vector<Point2f> points;
points.push_back(Point2f(0., 2.));
points.push_back(Point2f(1., 4.));
points.push_back(Point2f(2., 10.));
points.push_back(Point2f(3., 20.));
float x_temp, y_temp;
int qqq = points.size();
x_temp = points[points.size() - 1].x;
y_temp = points[points.size() - 1].y;
Mat A;
vector<Point2f> points_fitted;
polynomial_curve_fit(points, points_fitted, 3, A);
points_fitted.clear();
return 0;
}