OpenCV最小二乘法:cv::solve函数

版权声明: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;
}

猜你喜欢

转载自blog.csdn.net/qq_20797273/article/details/83930101